-
Notifications
You must be signed in to change notification settings - Fork 13.3k
repr(i64) picks 32-bit discriminant on 32-bit platform #26114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is actually pretty simple to fix. Right now we select the type based on, mostly, the overall alignment of the type. We're also basically assuming that an alignment-sized integer is big enough to fit all discriminants in, what happens is that the alignment for a 64-bit integer on a 32-bit platform is 4 bytes, so we end up using a 4-byte integer for discriminant. The easiest fix is to just skip the calculation for the discriminant type altogether when we have an repr attribute on the enum. A slightly better one might be to only allow the calculation to extend the int type to a larger size. |
@Aatch could you post a link to the general area of code that needs tweaking? |
I'd be happy to work on this if no one else is doing so yet. |
Go ahead! I'll help if necessary, though @Aatch knows more about this bug. |
The code you need to change is in trans/adt.rs. |
I've been having some trouble getting the compiler to build with 32-bit emulation on my 64-bit machine. I thought |
FWIW, I'm using |
Please ask for a try run when you need it 😄 IIRC Travis doesn't run all of the tests. Not sure. |
@Manishearth This might be a newb question, but what's a try run? Is that a bors-specific thing? If so, is there some documentation somewhere about the different bors options and when to use them? |
It just runs all tests on the infrastructure without merging the PR. The commands are documented here, however you don't have permissions to run any of them. (but you can ask us to if you need something run) |
Gotcha. Thanks! |
@dotdash I successfully reproduced the issue on my machine by using |
@Aatch So I'm a little confused about this line on master. In the case covered by this issue, it seems to me like the discriminant should be bigger than the alignment, since the alignment will be 4 bytes but we want the discriminant to be 8 bytes. But this means that |
@devonhollowood yeah, that'll need to be changed. I think the assertion is supposed to be ensuring that the alignment of the type is an integer multiple of the alignment of the discriminant, and is assuming that the alignment of an integer and the size of an integer are the same (which isn't true). Specifically, I think it's there to protect against a problem I encountered where I was accidentally increasing the size of the enum by using a too-large discriminant. It should probably be |
Okay, I'm making a lot of progress on this. I've got a question about the expected behavior, though. What should the output of this program be? #[repr(u64)]
enum Eu64NonCLike<T> {
_None,
_Some(T),
}
fn main() {
println!("{}", std::mem::size_of::<Eu64NonCLike<u8>>());
} On 64-bit, I think the output should be On 32-bit, it seems like the same logic would imply that the output should be |
@devonhollowood the results of things like sizes is always going to be different on different platforms for this exact reason. It's no different to |
@Aatch Thanks for the clarification. I figured that was the case, but I wanted to double check. |
Nice! Thanks for fixing this 🌟 |
From the PR #25651 it looks like repr(i64) (and presumably repr(u64)) picks a 32-bit discriminant for the non C-like enum case.
Testcase was:
Errored on platform auto-mac-32-opt with this:
The text was updated successfully, but these errors were encountered: