-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Tracking issue for RFC 2363, "Allow arbitrary enums to have explicit discriminants" #60553
Comments
Mentoring-wise: I'd suggest trying out an example and then tracking down where the error comes from. I don't remember, it's either during parsing or in Most of the compiler should already support this, where doing the uniform thing is easier. |
Has anyone stepped up to implement this? If not, I'd like to take a stab. The current error arises in parsing. I haven't fiddled with it yet, but I suspect a good first step is to remove the rust/src/libsyntax/parse/parser.rs Lines 7781 to 7789 in 33cde4a
|
I don't know of anyone
Go for it!
That looks like the right start, yes. |
I've started work on this here by removing the parsing restriction preventing non-unit variants from having explicit discriminants. As you predicted @eddyb, things seem to basically just work; e.g.: #![feature(core_intrinsics)]
enum Enum {
A(u16) = 7,
B(u32) = 42,
}
fn main() {
use std::intrinsics::discriminant_value;
unsafe {
assert_eq!(discriminant_value(&Enum::A(1)), 7);
assert_eq!(discriminant_value(&Enum::B(2)), 42);
}
} As it stands, adding this feature required removing more lines of code than it involved writing new code! :D Future work that comes to mind include writing tests and putting this behind a feature flag. Shall I go ahead and file an initial PR? |
Sweet! Yes please open a PR with the feature gate and throw some tests in for good measure (there may already be tests checking for the "discriminator values can only be used with a field-less enum" error message, those should now be emitting a feature gate error instead) |
Implement arbitrary_enum_discriminant Implements RFC rust-lang/rfcs#2363 (tracking issue #60553).
Documentation
I've submitted a PR to update the reference to reflect this feature (in its current state): rust-lang/reference#639. I do not believe that either the Book or Rust By Example need updating:
Unresolved Questions
Presently: no. Discriminants of all types of enumerations are specified with
Presently: yes, this feature applies only to enumerations using a primitive representation. Since this feature is only relevant when you care about the precise memory layout of enums, this feature is only reasonable to use when the precise layout of an enum is well-specified. |
What are layout guarantees for such enums? Ideally I would like to be able to write code likes this: #[repr(u8, C)]
enum Foo {
A = 0,
B { a: u16 } = 1,
C { a: u32, b: u16 } = 2,
} And I want for this type to have exactly the same memory layout as: #[repr(C)]
struct foo_t {
pub discr: u8,
pub payload: foo_u,
}
union foo_u {
b: u16,
c: c_t,
}
#[repr(C)]
struct c_t {
a: u32,
b: u16,
} Meaning if
Having such guarantees would allow in some cases some neat zero-cost translations of C types to safe Rust ones. |
@newpavlov You get most of that (the placement and size of the discriminant) from just Keep in mind that since your discriminants are the default ones (starting at We defined all these back in rust-lang/rfcs#2195, for Servo <-> Firefox I believe. |
What about casting those enums into the primitive? And then even |
Being a rust newbie, I instinctively tried this and the compiler sent me to this issue. I see this is fairly old, but I'm not familiar with how quickly features make it into a stable version of the compiler. Is it possible to tell how far this feature is from stabilizing? |
It's not even an year old, and within that, not much has happened once this was implemented. |
The next step to stabilizing would be to prepare a stabilization report, which basically summarizes:
|
For an example of a stabilization report, see e.g., #67712 and please reach out to e.g., myself (Discord or Zulip works) before publishing it. |
There's still work to be done to document this feature before stabilization—my PR updating the reference is stalled. The main roadblock I hit was I wasn't aware of RFC2195 when I submitted that PR, and the details of that RFC aren't already well-documented in the reference. Since it's trivial to explain what this feature does in the context of RFC2195, a PR should probably first be submitted to the reference updating the Type Layout chapter to document RFC2195. There're some hairy terminology issues nobody's been particularly consistent about, too. |
@jswrenn Note that we do not require that you update the reference before stabilization. It's perfectly acceptable to write a good report and then have that report be the material for later changes to the book, the reference, the rustc-dev-guide, etc. I would be happy to work with you towards a stabilization report! (and ❤️ for the work you've done so far). |
There are a set of changes related to enums that we need to make, including discriminants, |
Would anyone like to collaborate with me on this design? I'm very familiar with these issues, and have some design sketches on hand, but would love a collaborator help construct a cohesive vision of the future. |
…ry_enum_discriminant, r=joshtriplett Stabilize arbitrary_enum_discriminant, take 2 Documentation has been updated in rust-lang/reference#1055. cc rust-lang#86860 for previous stabilization report. Not yet marks rust-lang#60553 as done: need documentation in the rust reference.
…ry_enum_discriminant, r=joshtriplett Stabilize arbitrary_enum_discriminant, take 2 Documentation has been updated in rust-lang/reference#1055. cc rust-lang#86860 for previous stabilization report. Not yet marks rust-lang#60553 as done: need documentation in the rust reference.
…ry_enum_discriminant, r=joshtriplett Stabilize arbitrary_enum_discriminant, take 2 Documentation has been updated in rust-lang/reference#1055. cc rust-lang#86860 for previous stabilization report. Not yet marks rust-lang#60553 as done: need documentation in the rust reference.
…ry_enum_discriminant, r=joshtriplett Stabilize arbitrary_enum_discriminant, take 2 Documentation has been updated in rust-lang/reference#1055. cc rust-lang#86860 for previous stabilization report. Not yet marks rust-lang#60553 as done: need documentation in the rust reference.
…ry_enum_discriminant, r=joshtriplett Stabilize arbitrary_enum_discriminant, take 2 Documentation has been updated in rust-lang/reference#1055. cc rust-lang#86860 for previous stabilization report. Not yet marks rust-lang#60553 as done: need documentation in the rust reference.
I'm going to close as I believe this is now essentially complete as of 1.66. There might be some longer-term decisions to make around
// Allowed since 1.15, even without a #[repr]
enum Fieldless {
Tuple(),
Struct{},
Unit,
}
assert_eq!(0, Fieldless::Tuple() as isize);
assert_eq!(1, Fieldless::Struct{} as isize);
assert_eq!(2, Fieldless::Unit as isize);
#[repr(u8)]
enum FieldlessWithDiscrimants {
First = 10,
Tuple(),
Second = 20,
Struct{},
Unit,
}
assert_eq!(10, FieldlessWithDiscrimants::First as u8);
assert_eq!(11, FieldlessWithDiscrimants::Tuple() as u8);
assert_eq!(20, FieldlessWithDiscrimants::Second as u8);
assert_eq!(21, FieldlessWithDiscrimants::Struct{} as u8);
assert_eq!(22, FieldlessWithDiscrimants::Unit as u8); I suspect further changes may require an RFC or some design decisions with the lang team. |
… r=jieyouxu Update E0517 message to reflect RFC 2195. E0517 occurs when a `#[repr(..)]` attribute is placed on an unsupported item. Currently, the explanation of the error implies that `#[repr(u*/i*)]` cannot be placed on fieldful enums, which is no longer the case since [RFC 2195](rust-lang/rfcs#2195) was [stabilized](rust-lang#60553), which allows placing `#[repr(u*/i*)]` and/or `#[repr(C)]` on fieldful enums to produce a defined layout. This PR doesn't (currently) add a description of the semantics of placing `#[repr(u*/i*)]` on a fieldful enum to the error explanation, it just removes the claims/implications that it is not allowed.
… r=jieyouxu Update E0517 message to reflect RFC 2195. E0517 occurs when a `#[repr(..)]` attribute is placed on an unsupported item. Currently, the explanation of the error implies that `#[repr(u*/i*)]` cannot be placed on fieldful enums, which is no longer the case since [RFC 2195](rust-lang/rfcs#2195) was [stabilized](rust-lang#60553), which allows placing `#[repr(u*/i*)]` and/or `#[repr(C)]` on fieldful enums to produce a defined layout. This PR doesn't (currently) add a description of the semantics of placing `#[repr(u*/i*)]` on a fieldful enum to the error explanation, it just removes the claims/implications that it is not allowed.
… r=jieyouxu Update E0517 message to reflect RFC 2195. E0517 occurs when a `#[repr(..)]` attribute is placed on an unsupported item. Currently, the explanation of the error implies that `#[repr(u*/i*)]` cannot be placed on fieldful enums, which is no longer the case since [RFC 2195](rust-lang/rfcs#2195) was [stabilized](rust-lang#60553), which allows placing `#[repr(u*/i*)]` and/or `#[repr(C)]` on fieldful enums to produce a defined layout. This PR doesn't (currently) add a description of the semantics of placing `#[repr(u*/i*)]` on a fieldful enum to the error explanation, it just removes the claims/implications that it is not allowed.
… r=jieyouxu Update E0517 message to reflect RFC 2195. E0517 occurs when a `#[repr(..)]` attribute is placed on an unsupported item. Currently, the explanation of the error implies that `#[repr(u*/i*)]` cannot be placed on fieldful enums, which is no longer the case since [RFC 2195](rust-lang/rfcs#2195) was [stabilized](rust-lang#60553), which allows placing `#[repr(u*/i*)]` and/or `#[repr(C)]` on fieldful enums to produce a defined layout. This PR doesn't (currently) add a description of the semantics of placing `#[repr(u*/i*)]` on a fieldful enum to the error explanation, it just removes the claims/implications that it is not allowed.
Rollup merge of rust-lang#128795 - zachs18:e0517-update-for-rfc-2195, r=jieyouxu Update E0517 message to reflect RFC 2195. E0517 occurs when a `#[repr(..)]` attribute is placed on an unsupported item. Currently, the explanation of the error implies that `#[repr(u*/i*)]` cannot be placed on fieldful enums, which is no longer the case since [RFC 2195](rust-lang/rfcs#2195) was [stabilized](rust-lang#60553), which allows placing `#[repr(u*/i*)]` and/or `#[repr(C)]` on fieldful enums to produce a defined layout. This PR doesn't (currently) add a description of the semantics of placing `#[repr(u*/i*)]` on a fieldful enum to the error explanation, it just removes the claims/implications that it is not allowed.
This is a tracking issue for the RFC "Allow arbitrary enums to have explicit discriminants" (rust-lang/rfcs#2363).
Steps:
arbitrary_enum_discriminant
#86860Unresolved questions:
The text was updated successfully, but these errors were encountered: