-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Mark enums with non-zero discriminant as non-zero #37224
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM although I believe it could be simpler.
@@ -769,6 +770,7 @@ pub enum Layout { | |||
CEnum { | |||
discr: Integer, | |||
signed: bool, | |||
non_zero: bool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You already have the range (see rustc_trans::adt
for a way to determine if a value is in the range), why would this additional field be needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enum E {
A = -1,
B = 1,
}
0
is in the range, but the enum is still non-zero.
(Also, non_zero: bool
fits into previous padding so it doesn't increase the size of Layout
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's annoying. What I expect to eventually have would use 2
there, that's why I don't like non_zero
: it's a special-case that makes sense mostly on pointers.
If you want to discuss the full niche optimization, I'd be down for it (IRC?).
If you don't want to change this implementation I'll r+ and take out this later (and/or switch to multi-ranges - LLVM actually supports them for !range
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't plan to implement the full optimization so far.
CEnum { discr: value, .. } => { | ||
return success(RawNullablePointer { | ||
nndiscr: discr as u64, | ||
value: Int(value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe make this match
produce the Primitive
type and do the return after the match
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
@@ -15,6 +15,8 @@ | |||
#![feature(test)] | |||
#![feature(libc)] | |||
|
|||
#![cfg_attr(stage0, feature(question_mark))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few people hit this, I guess it got removed by accident. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that #37177 already contains this (and is in the queue)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#37202 contains it too :D
The sooner it lands the better.
@bors r+ |
📌 Commit 49e6b46 has been approved by |
Mark enums with non-zero discriminant as non-zero cc rust-lang/rfcs#1230 r? @eddyb
Mark enums with non-zero discriminant as non-zero cc rust-lang/rfcs#1230 r? @eddyb
Btw, this caused some rather tricky issues in Servo (rust-lang/rust-bindgen#225). IMO when changing reprs for things which may come from FFI (e.g. an enum) we should be more careful and have a cycle of warnings or a compiler note or something. Not sure how it would be implemented. (I agree that it's non ideal for C++ to abuse enums as bitflags but apparently it's a common pattern) The only reason we could figure this out was because I knew how Rust's encoded enum debuginfo works, and I also knew that this PR had happened -- which is a rather high bar for being able to debug things like this. It's otherwise quite an opaque and nonsensical bug that feels like a compiler bug (in this case, setting |
Hmm. @Manishearth I've not read this PR, but I assume that the enums in question were not marked as (In which case, was the "safe for C" lint not firing, or was it disabled?) |
They were marked as |
That's just setting the size of the enum, it's still UB to have a value other than the assigned ones. |
cc rust-lang/rfcs#1230
r? @eddyb