Skip to content
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

Implement arbitrary_enum_discriminant #60732

Merged
merged 1 commit into from
Jun 25, 2019
Merged

Implement arbitrary_enum_discriminant #60732

merged 1 commit into from
Jun 25, 2019

Conversation

jswrenn
Copy link
Member

@jswrenn jswrenn commented May 11, 2019

Implements RFC rust-lang/rfcs#2363 (tracking issue #60553).

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @pnkfelix (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 11, 2019
@rust-highfive

This comment has been minimized.

@rust-highfive

This comment has been minimized.

@RalfJung
Copy link
Member

Would be nice to get a test case that has some CTFE code involving the new discriminants, just to make sure that works, too.

Cc @oli-obk do you know if this needs adjustments in Miri (specifically in read_discriminant and write_discriminant)?

@bors

This comment has been minimized.

@oli-obk
Copy link
Contributor

oli-obk commented May 13, 2019

do you know if this needs adjustments in Miri (specifically in read_discriminant and write_discriminant)?

No, this requires no changes for anything beyond the AST. Everything else is already setup to handle this.

Some const eval tests would be nice though.

@oli-obk
Copy link
Contributor

oli-obk commented May 13, 2019

So... there's this fun comment in the layouting source:

// The current code for niche-filling relies on variant indices
// instead of actual discriminants, so dataful enums with
// explicit discriminants (RFC #2363) would misbehave.
let no_explicit_discriminants = def.variants.iter_enumerated()
.all(|(i, v)| v.discr == ty::VariantDiscr::Relative(i.as_u32()));

I'm guessing you can observe this as follows:

enum Foo {
    A(&'static i32),
    B,
}
enum Bar {
    A(&'static i32) = 0,
    B = 1,
}
assert_eq!(std::mem::size_of::<Foo>() == std::mem::size_of::<usize>());
assert_eq!(std::mem::size_of::<Bar>() > std::mem::size_of::<usize>());

@jswrenn
Copy link
Member Author

jswrenn commented May 13, 2019

@ralph

Would be nice to get a test case that has some CTFE code involving the new discriminants, just to make sure that works, too.

Would something like this fit the bill?

#![feature(arbitrary_enum_discriminant,const_raw_ptr_deref)]

#[allow(dead_code)]
#[repr(u8)]
enum Enum {
    Unit = 3,
    Tuple(u16) = 2,
    Struct {
        a: u8,
        b: u16,
    } = 1,
}

impl Enum {
    const unsafe fn tag(&self) -> u8 {
        *(self as *const Self as *const u8)
    }
}

const UNIT_TAG:   u8 = unsafe { Enum::Unit.tag() };
const TUPLE_TAG:  u8 = unsafe { Enum::Tuple(5).tag() };
const STRUCT_TAG: u8 = unsafe { Enum::Struct{a: 7, b: 11}.tag() };

fn main() {
    assert_eq!(3, UNIT_TAG);
    assert_eq!(2, TUPLE_TAG);
    assert_eq!(1, STRUCT_TAG);
}

@jswrenn
Copy link
Member Author

jswrenn commented May 13, 2019

@oli-obk To be sure I understand correctly: is the expected behavior that both Foo and Bar (being #[repr(Rust)]) should have the same size in that example?

@oli-obk
Copy link
Contributor

oli-obk commented May 13, 2019

No, it is perfectly fine for them to have different sizes for now, it's just an implementation detail that we can fix in the future. Maybe add my code as a canary test?

One thing that I'm wondering: the RFC states that the only legal way to get the discriminant back is to start out with a repr(some_int) enum. Would it make sense to forbid arbitrary enum discriminants on other repr enums for now?

One thing that I think should also have a test, too: code matching on an enum with both fields and explicit discriminants.

@RalfJung
Copy link
Member

Would something like this fit the bill?

Looks great!
Aren't there also safe conversion casts (x as i32)?

@jswrenn
Copy link
Member Author

jswrenn commented May 13, 2019

@oli-obk

One thing that I'm wondering: the RFC states that the only legal way to get the discriminant back is to start out with a repr(some_int) enum. Would it make sense to forbid arbitrary enum discriminants on other repr enums for now?

I think you're referring to the stipulation that:

enumerations with fields still can't be casted to numeric types with the as operator

As it stands, the functionality enabled by this PR forbids you from as-casting a variant of an enum if any variant has data associated with it. For instance, this is already forbidden:

#![feature(arbitrary_enum_discriminant)]

#[repr(u8)]
#[allow(dead_code)]
enum Enum {
  Unit = 3,
  Tuple(()) = 2,
  Struct {
    a: (),
    b: (),
  } = 1,
}

fn main() {
  println!("{:?}", Enum::Unit as u8);
}

and produces this error:

(Click to Expand)
error[E0605]: non-primitive cast: `Enum` as `u8`
  --> src/main.rs:21:20
   |
21 |   println!("{:?}", Enum::Unit as u8);
   |                    ^^^^^^^^^^^^^^^^
   |
   = note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait

But this is permitted:

#![feature(arbitrary_enum_discriminant)]

#[allow(dead_code)]
enum Enum {
  Unit = 3,
  Tuple() = 2,
  Struct {} = 1,
}

fn main() {
  assert_eq!(3, Enum::Unit as u8);
  assert_eq!(2, Enum::Tuple() as u8);
  assert_eq!(1, Enum::Struct{} as u8);
}

...and I think it's reasonable and consistent to permit that, since rust already permits writing:

#[allow(dead_code)]
enum Enum {
  Unit,
  Tuple(),
  Struct{},
}

fn main() {
  assert_eq!(0, Enum::Unit as u8);
  assert_eq!(1, Enum::Tuple() as u8);
  assert_eq!(2, Enum::Struct{} as u8);
}

I can't think of a compelling reason to add an explicit repr requirement given the above restrictions.

However, although the RFC explicitly does not enable this functionality, it seems to me like as-casting variants with fields (or something analogous) should be permitted on enums with fields when an explicit repr(inttype) is provided. Since specifying a repr(inttype) enforces both the location and size of the discriminant, and the whole point of this RFC is to let the user explicitly enforce that the discriminant is a particular value, it really seems like there should be a safe, ergonomic mechanism for getting that value back out—unsafe { *(value as *const Self as *const u8) } is quite a mouthful!

@oli-obk
Copy link
Contributor

oli-obk commented May 13, 2019

unsafe { *(value as *const Self as *const u8) } is only valid if you are using repr(u8). This is mainly what I was referring to. Since the unsafe pointer magic is the only thing making it possible right now to extract he discriminant value, and it requires repr(u8), I was wondering if we may as well require repr(u8) (or other ints) for enums with variants with fields and explicit discriminants.

@rust-highfive

This comment has been minimized.

@rust-highfive

This comment has been minimized.

@jswrenn
Copy link
Member Author

jswrenn commented May 20, 2019

@oli-obk

unsafe { *(value as *const Self as *const u8) } is only valid if you are using repr(u8). This is mainly what I was referring to. Since the unsafe pointer magic is the only thing making it possible right now to extract he discriminant value, and it requires repr(u8), I was wondering if we may as well require repr(u8) (or other ints) for enums with variants with fields and explicit discriminants.

I see your point. I think this is a good idea, and I'll take a stab at it in the next few days!

Implementation wise, I think rustc_typeck::check::check_enum is the best place to add this check.

@pnkfelix
Copy link
Member

pnkfelix commented May 22, 2019

(hmm, i'm sorry: I meant to post my change to your doc ( 6c09c00a66dd76107fbdf2ef5b62427095844f5c ) as a suggestion, not as a commit on its own. Feel free to revise that as you like. I'll try to ensure my future suggestions are deployed as intended: i.e., as suggestions, not commits.)

@pnkfelix
Copy link
Member

I have one minor question about the diagnostic code; once that is addressed, r=me.

@pnkfelix pnkfelix added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 22, 2019
@pnkfelix
Copy link
Member

@jswrenn wrote:

@oli-obk

unsafe { *(value as *const Self as *const u8) } is only valid if you are using repr(u8). This is mainly what I was referring to. Since the unsafe pointer magic is the only thing making it possible right now to extract he discriminant value, and it requires repr(u8), I was wondering if we may as well require repr(u8) (or other ints) for enums with variants with fields and explicit discriminants.

I see your point. I think this is a good idea, and I'll take a stab at it in the next few days!

Implementation wise, I think rustc_typeck::check::check_enum is the best place to add this check.

i don't mind landing the bulk of the code as is and landing the change suggested here in a later PR. I'll let @jswrenn decide which approach they would prefer to take.

@bors

This comment has been minimized.

@bors

This comment has been minimized.

@bors

This comment has been minimized.

@jswrenn
Copy link
Member Author

jswrenn commented Jun 12, 2019

@Centril, github still lists you as 'Requesting Changes', but the unresolved suggestion isn't reachable (because of a rebase), so I cannot mark it as resolved. To the best of my knowledge, I've resolved all issues raised so far.

@bors
Copy link
Contributor

bors commented Jun 16, 2019

☔ The latest upstream changes (presumably #61347) made this pull request unmergeable. Please resolve the merge conflicts.

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:058c8c1b:start=1560792532644621900,finish=1560792533506075123,duration=861453223
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
$ export GCP_CACHE_BUCKET=rust-lang-ci-cache
$ export AWS_ACCESS_KEY_ID=AKIA46X5W6CZEJZ6XT55
---
[01:00:17] ....................................................................ii...i..ii...................... 3600/5685
[01:00:21] .................................................................................................... 3700/5685
[01:00:25] .................................................................................................... 3800/5685
[01:00:28] ..............................................................................ii.................... 3900/5685
[01:00:31] ...................................................................................................i 4000/5685
[01:00:33] ..........................................................F......................................... 4100/5685
[01:00:35] ...............................................................i.................................... 4200/5685
[01:00:38] ................................................F................................................... 4300/5685
[01:00:56] .................................................................................................... 4500/5685
[01:00:59] .................................................................................................... 4600/5685
[01:01:03] .................................................................................................... 4700/5685
[01:01:07] .................................................................................................... 4800/5685
---
[01:01:43] 
[01:01:43] ---- [ui] ui/parser/issue-17383.rs stdout ----
[01:01:43] diff of stderr:
[01:01:43] 
[01:01:43] - error[E0658]: custom discriminant values are not allowed in enums with fields
[01:01:43] + error[E0658]: custom discriminant values are not allowed in enums with tuple or struct variants
[01:01:43] 3    |
[01:01:43] 4 LL |     A = 3,
[01:01:43] 
[01:01:43] -    |         ^ invalid custom discriminant
[01:01:43] -    |         ^ invalid custom discriminant
[01:01:43] +    |         ^ disallowed custom discriminant
[01:01:43] 7 LL |     B(usize)
[01:01:43] -    |     -------- variant with a field defined here
[01:01:43] +    |     -------- tuple variant defined here
[01:01:43] 9    |
[01:01:43] 9    |
[01:01:43] 10    = note: for more information, see https://github.com/rust-lang/rust/issues/60553
[01:01:43] 11    = help: add #![feature(arbitrary_enum_discriminant)] to the crate attributes to enable
[01:01:43] 
[01:01:43] The actual stderr differed from the expected stderr.
[01:01:43] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/parser/issue-17383/issue-17383.stderr
[01:01:43] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/parser/issue-17383/issue-17383.stderr
[01:01:43] To update references, rerun the tests and pass the `--bless` flag
[01:01:43] To only update this specific test, also pass `--test-args parser/issue-17383.rs`
[01:01:43] error: 1 errors occurred comparing output.
[01:01:43] status: exit code: 1
[01:01:43] status: exit code: 1
[01:01:43] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/parser/issue-17383.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/parser/issue-17383" "-Crpath" "-O" "-Cdebuginfo=0" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/parser/issue-17383/auxiliary" "-A" "unused"
[01:01:43] ------------------------------------------
[01:01:43] 
[01:01:43] ------------------------------------------
[01:01:43] stderr:
[01:01:43] stderr:
[01:01:43] ------------------------------------------
[01:01:43] error[E0658]: custom discriminant values are not allowed in enums with tuple or struct variants
[01:01:43]   --> /checkout/src/test/ui/parser/issue-17383.rs:2:9
[01:01:43]    |
[01:01:43] LL |     A = 3,
[01:01:43]    |         ^ disallowed custom discriminant
[01:01:43] LL |     //~^ ERROR custom discriminant values are not allowed in enums with fields
[01:01:43] LL |     B(usize)
[01:01:43]    |     -------- tuple variant defined here
[01:01:43]    = note: for more information, see https://github.com/rust-lang/rust/issues/60553
[01:01:43]    = note: for more information, see https://github.com/rust-lang/rust/issues/60553
[01:01:43]    = help: add #![feature(arbitrary_enum_discriminant)] to the crate attributes to enable
[01:01:43] error: aborting due to previous error
[01:01:43] 
[01:01:43] For more information about this error, try `rustc --explain E0658`.
[01:01:43] 
[01:01:43] 
[01:01:43] ------------------------------------------
[01:01:43] 
[01:01:43] 
[01:01:43] ---- [ui] ui/parser/tag-variant-disr-non-nullary.rs stdout ----
[01:01:43] diff of stderr:
[01:01:43] 
[01:01:43] - error[E0658]: custom discriminant values are not allowed in enums with fields
[01:01:43] + error[E0658]: custom discriminant values are not allowed in enums with tuple or struct variants
[01:01:43] 3    |
[01:01:43] 4 LL |     Red = 0xff0000,
[01:01:43] 
[01:01:43] -    |           ^^^^^^^^ invalid custom discriminant
[01:01:43] -    |           ^^^^^^^^ invalid custom discriminant
[01:01:43] +    |           ^^^^^^^^ disallowed custom discriminant
[01:01:43] 6 LL |
[01:01:43] 7 LL |     Green = 0x00ff00,
[01:01:43] -    |             ^^^^^^^^ invalid custom discriminant
[01:01:43] +    |             ^^^^^^^^ disallowed custom discriminant
[01:01:43] 9 LL |     Blue = 0x0000ff,
[01:01:43] -    |            ^^^^^^^^ invalid custom discriminant
[01:01:43] +    |            ^^^^^^^^ disallowed custom discriminant
[01:01:43] 11 LL |     Black = 0x000000,
[01:01:43] -    |             ^^^^^^^^ invalid custom discriminant
[01:01:43] +    |             ^^^^^^^^ disallowed custom discriminant
[01:01:43] 13 LL |     White = 0xffffff,
[01:01:43] -    |             ^^^^^^^^ invalid custom discriminant
[01:01:43] +    |             ^^^^^^^^ disallowed custom discriminant
[01:01:43] 15 LL |     Other(usize),
[01:01:43] -    |     ------------ variant with a field defined here
[01:01:43] +    |     ------------ tuple variant defined here
[01:01:43] 17 LL |     Other2(usize, usize),
[01:01:43] -    |     -------------------- variant with fields defined here
[01:01:43] +    |     -------------------- tuple variant defined here
[01:01:43] 20    = note: for more information, see https://github.com/rust-lang/rust/issues/60553
[01:01:43] 20    = note: for more information, see https://github.com/rust-lang/rust/issues/60553
[01:01:43] 21    = help: add #![feature(arbitrary_enum_discriminant)] to the crate attributes to enable
[01:01:43] 
[01:01:43] The actual stderr differed from the expected stderr.
[01:01:43] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/parser/tag-variant-disr-non-nullary/tag-variant-disr-non-nullary.stderr
[01:01:43] Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/parser/tag-variant-disr-non-nullary/tag-variant-disr-non-nullary.stderr
[01:01:43] To update references, rerun the tests and pass the `--bless` flag
[01:01:43] To only update this specific test, also pass `--test-args parser/tag-variant-disr-non-nullary.rs`
[01:01:43] error: 1 errors occurred comparing output.
[01:01:43] status: exit code: 1
[01:01:43] status: exit code: 1
[01:01:43] command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/parser/tag-variant-disr-non-nullary.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "-Zui-testing" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/parser/tag-variant-disr-non-nullary" "-Crpath" "-O" "-Cdebuginfo=0" "-Zunstable-options" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/parser/tag-variant-disr-non-nullary/auxiliary" "-A" "unused"
[01:01:43] ------------------------------------------
[01:01:43] 
[01:01:43] ------------------------------------------
[01:01:43] stderr:
[01:01:43] stderr:
[01:01:43] ------------------------------------------
[01:01:43] error[E0658]: custom discriminant values are not allowed in enums with tuple or struct variants
[01:01:43]   --> /checkout/src/test/ui/parser/tag-variant-disr-non-nullary.rs:2:11
[01:01:43]    |
[01:01:43] LL |     Red = 0xff0000,
[01:01:43]    |           ^^^^^^^^ disallowed custom discriminant
[01:01:43] LL |     //~^ ERROR custom discriminant values are not allowed in enums with fields
[01:01:43] LL |     Green = 0x00ff00,
[01:01:43]    |             ^^^^^^^^ disallowed custom discriminant
[01:01:43] LL |     Blue = 0x0000ff,
[01:01:43]    |            ^^^^^^^^ disallowed custom discriminant
[01:01:43] LL |     Black = 0x000000,
[01:01:43]    |             ^^^^^^^^ disallowed custom discriminant
[01:01:43] LL |     White = 0xffffff,
[01:01:43]    |             ^^^^^^^^ disallowed custom discriminant
[01:01:43] LL |     Other(usize),
[01:01:43]    |     ------------ tuple variant defined here
[01:01:43] LL |     Other2(usize, usize),
[01:01:43]    |     -------------------- tuple variant defined here
[01:01:43]    = note: for more information, see https://github.com/rust-lang/rust/issues/60553
[01:01:43]    = note: for more information, see https://github.com/rust-lang/rust/issues/60553
[01:01:43]    = help: add #![feature(arbitrary_enum_discriminant)] to the crate attributes to enable
[01:01:43] error: aborting due to previous error
[01:01:43] 
[01:01:43] For more information about this error, try `rustc --explain E0658`.
[01:01:43] 
---
[01:01:43] thread 'main' panicked at 'Some tests failed', src/tools/compiletest/src/main.rs:521:22
[01:01:43] note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
[01:01:43] 
[01:01:43] 
[01:01:43] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/compiletest" "--compile-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib" "--run-lib-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" "--rustc-path" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "--src-base" "/checkout/src/test/ui" "--build-base" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui" "--stage-id" "stage2-x86_64-unknown-linux-gnu" "--mode" "ui" "--target" "x86_64-unknown-linux-gnu" "--host" "x86_64-unknown-linux-gnu" "--llvm-filecheck" "/usr/lib/llvm-6.0/bin/FileCheck" "--host-rustcflags" "-Crpath -O -Cdebuginfo=0 -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--target-rustcflags" "-Crpath -O -Cdebuginfo=0 -Zunstable-options  -Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "--docck-python" "/usr/bin/python2.7" "--lldb-python" "/usr/bin/python2.7" "--gdb" "/usr/bin/gdb" "--quiet" "--llvm-version" "6.0.0\n" "--system-llvm" "--cc" "" "--cxx" "" "--cflags" "" "--llvm-components" "" "--llvm-cxxflags" "" "--adb-path" "adb" "--adb-test-dir" "/data/tmp/work" "--android-cross-path" "" "--color" "always"
[01:01:43] 
[01:01:43] 
[01:01:43] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test
[01:01:43] Build completed unsuccessfully in 0:56:44
---
travis_time:end:02a5a270:start=1560796250145676851,finish=1560796250151208923,duration=5532072
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:05c1281a
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:0afdf67c
travis_time:start:0afdf67c
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:20e9186d
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@lucab
Copy link
Contributor

lucab commented Jun 19, 2019

(I think this may be waiting for another review round after updates, despite what the label says)

@oli-obk oli-obk added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 21, 2019
Copy link
Contributor

@oli-obk oli-obk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just some stylistic nits, then this lgtm

src/librustc_typeck/check/mod.rs Outdated Show resolved Hide resolved
src/librustc_typeck/check/mod.rs Outdated Show resolved Hide resolved
src/librustc_typeck/check/mod.rs Outdated Show resolved Hide resolved
src/libsyntax/feature_gate.rs Outdated Show resolved Hide resolved
@pnkfelix
Copy link
Member

@bors r+

@bors
Copy link
Contributor

bors commented Jun 25, 2019

📌 Commit ac98342 has been approved by pnkfelix

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 25, 2019
@bors
Copy link
Contributor

bors commented Jun 25, 2019

⌛ Testing commit ac98342 with merge 303f77e...

bors added a commit that referenced this pull request Jun 25, 2019
Implement arbitrary_enum_discriminant

Implements RFC rust-lang/rfcs#2363 (tracking issue #60553).
@bors
Copy link
Contributor

bors commented Jun 25, 2019

☀️ Test successful - checks-travis, status-appveyor
Approved by: pnkfelix
Pushing 303f77e to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jun 25, 2019
@bors bors merged commit ac98342 into rust-lang:master Jun 25, 2019
bors bot added a commit to intellij-rust/intellij-rust that referenced this pull request Jul 4, 2019
4056: INT: Fix creation of new module if no corresponding directory exists r=mchernyavsky a=mchernyavsky

Fixes #3995.


4069: Support for arbitrary enum discriminants r=mchernyavsky a=mibac138

Reference: rust-lang/rust#60732


Co-authored-by: mchernyavsky <chemike47@gmail.com>
Co-authored-by: mibac138 <5672750+mibac138@users.noreply.github.com>
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 18, 2021
Stabilize `arbitrary_enum_discriminant`

Closes rust-lang#60553.

----

## Stabilization Report

_copied from rust-lang#60553 (comment)

### Summary

Enables a user to specify *explicit* discriminants on arbitrary enums.

Previously, this was hard to achieve:

```rust
#[repr(u8)]
enum Foo {
    A(u8) = 0,
    B(i8) = 1,
    C(bool) = 42,
}
```

Someone would need to add 41 hidden variants in between as a workaround with implicit discriminants.

In conjunction with [RFC 2195](https://github.com/rust-lang/rfcs/blob/master/text/2195-really-tagged-unions.md), this feature would provide more flexibility for FFI and unsafe code involving enums.

### Test cases

Most tests are in [`src/test/ui/enum-discriminant`](https://github.com/rust-lang/rust/tree/master/src/test/ui/enum-discriminant), there are two [historical](https://github.com/rust-lang/rust/blob/master/src/test/ui/parser/tag-variant-disr-non-nullary.rs) [tests](https://github.com/rust-lang/rust/blob/master/src/test/ui/parser/issue-17383.rs) that are now covered by the feature (removed by this pr due to them being obsolete).

### Edge cases

The feature is well defined and does not have many edge cases.
One [edge case](rust-lang#70509) was related to another unstable feature named `repr128` and is resolved.

### Previous PRs

The [implementation PR](rust-lang#60732) added documentation to the Unstable Book, rust-lang/reference#1055 was opened as a continuation of rust-lang/reference#639.

### Resolution of unresolved questions

The questions are resolved in rust-lang#60553 (comment).

----

(someone please add `needs-fcp`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants