-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Stabilize #[repr(transparent)]
on enum
s in Rust 1.42.0
#68122
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
Team member @Centril has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
r=me on the implementation, waiting for FCP |
I'm noticing this very late, but it appears we've all forgotten that, just as with transparent structs, there also needs to be an alignment requirement on the ZST fields. It's not even mentioned in the RFC as far as I can tell, and not in the unstable book chapter added in the implementation PR. The only reason it's implemented is code sharing with transparent structs. I assume this doesn't actually influence the decision to stabilize, but:
|
Thanks for noticing; I've extended the test. |
@rfcbot reviewed |
We should document the behavior of combining But the current behavior seems reasonable, so: |
Wake up bot :) @rfcbot reviewed |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
This comment has been minimized.
This comment has been minimized.
10a576f
to
25460eb
Compare
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. The RFC will be merged soon. |
@bors r=petrochenkov p=3 |
📌 Commit 25460eb has been approved by |
…enkov Stabilize `#[repr(transparent)]` on `enum`s in Rust 1.42.0 # Stabilization report The following is the stabilization report for `#![feature(transparent_enums)]`. Tracking issue: #60405 [Version target](https://forge.rust-lang.org/#current-release-versions): 1.42 (2020-01-30 => beta, 2020-03-12 => stable). ## User guide A `struct` with only a single non-ZST field (let's call it `foo`) can be marked as `#[repr(transparent)]`. Such a `struct` has the same layout and ABI as `foo`. Here, we also extend this ability to `enum`s with only one variant, subject to the same restrictions as for the equivalent `struct`. That is, you can now write: ```rust #[repr(transparent)] enum Foo { Bar(u8) } ``` which, in terms of layout and ABI, is equivalent to: ```rust #[repr(transparent)] struct Foo(u8); ``` ## Motivation This is not a major feature that will unlock new and important use-cases. The utility of `repr(transparent)` `enum`s is indeed limited. However, there is still some value in it: 1. It provides conceptual simplification of the language in terms of treating univariant `enum`s and `struct`s the same, as both are product types. Indeed, languages like Haskell only have `data` as the only way to construct user-defined ADTs in the language. 2. In rare occasions, it might be that the user started out with a univariant `enum` for whatever reason (e.g. they thought they might extend it later). Now they want to make this `enum` `transparent` without breaking users by turning it into a `struct`. By lifting the restriction here, now they can. ## Technical specification The reference specifies [`repr(transparent)` on a `struct`](https://doc.rust-lang.org/nightly/reference/type-layout.html#the-transparent-representation) as: > ### The transparent Representation > > The `transparent` representation can only be used on `struct`s that have: > - a single field with non-zero size, and > - any number of fields with size 0 and alignment 1 (e.g. `PhantomData<T>`). > > Structs with this representation have the same layout and ABI as the single non-zero sized field. > > This is different than the `C` representation because a struct with the `C` representation will always have the ABI of a `C` `struct` while, for example, a struct with the `transparent` representation with a primitive field will have the ABI of the primitive field. > > Because this representation delegates type layout to another type, it cannot be used with any other representation. Here, we amend this to include univariant `enum`s as well with the same static restrictions and the same effects on dynamic semantics. ## Tests All the relevant tests are adjusted in the PR diff but are recounted here: - `src/test/ui/repr/repr-transparent.rs` checks that `repr(transparent)` on an `enum` must be univariant, rather than having zero or more than one variant. Restrictions on the fields inside the only variants, like for those on `struct`s, are also checked here. - A number of codegen tests are provided as well: - `src/test/codegen/repr-transparent.rs` (the canonical test) - `src/test/codegen/repr-transparent-aggregates-1.rs` - `src/test/codegen/repr-transparent-aggregates-2.rs` - `src/test/codegen/repr-transparent-aggregates-3.rs` - `src/test/ui/lint/lint-ctypes-enum.rs` tests the interactions with the `improper_ctypes` lint. ## History - 2019-04-30, RFC rust-lang/rfcs#2645 Author: @mjbshaw Reviewers: The Language Team This is the RFC that proposes allowing `#[repr(transparent)]` on `enum`s and `union`. - 2019-06-11, PR #60463 Author: @mjbshaw Reviewers: @varkor and @rkruppe The PR implements the RFC aforementioned in full. - 2019, PR #67323 Author: @Centril Reviewers: @davidtwco The PR reorganizes the static checks taking advantage of the fact that `struct`s and `union`s are internally represented as ADTs with a single variant. - This PR stabilizes `transparent_enums`. ## Related / possible future work The remaining work here is to figure out the semantics of `#[repr(transparent)]` on `union`s and stabilize those. This work continues to be tracked in #60405.
☀️ Test successful - checks-azure |
Version 1.42.0 (2020-03-12) ========================== Language -------- - [You can now use the slice pattern syntax with subslices.][67712] e.g. ```rust fn foo(words: &[&str]) { match words { ["Hello", "World", "!", ..] => println!("Hello World!"), ["Foo", "Bar", ..] => println!("Baz"), rest => println!("{:?}", rest), } } ``` - [You can now use `#[repr(transparent)]` on univariant `enum`s.][68122] Meaning that you can create an enum that has the exact layout and ABI of the type it contains. - [There are some *syntax-only* changes:][67131] - `default` is syntactically allowed before items in `trait` definitions. - Items in `impl`s (i.e. `const`s, `type`s, and `fn`s) may syntactically leave out their bodies in favor of `;`. - Bounds on associated types in `impl`s are now syntactically allowed (e.g. `type Foo: Ord;`). - `...` (the C-variadic type) may occur syntactically directly as the type of any function parameter. These are still rejected *semantically*, so you will likely receive an error but these changes can be seen and parsed by procedural macros and conditional compilation. Compiler -------- - [Added tier 2* support for `armv7a-none-eabi`.][68253] - [Added tier 2 support for `riscv64gc-unknown-linux-gnu`.][68339] - [`Option::{expect,unwrap}` and `Result::{expect, expect_err, unwrap, unwrap_err}` now produce panic messages pointing to the location where they were called, rather than `core`'s internals. ][67887] * Refer to Rust's [platform support page][forge-platform-support] for more information on Rust's tiered platform support. Libraries --------- - [`iter::Empty<T>` now implements `Send` and `Sync` for any `T`.][68348] - [`Pin::{map_unchecked, map_unchecked_mut}` no longer require the return type to implement `Sized`.][67935] - [`io::Cursor` now derives `PartialEq` and `Eq`.][67233] - [`Layout::new` is now `const`.][66254] - [Added Standard Library support for `riscv64gc-unknown-linux-gnu`.][66899] Stabilized APIs --------------- - [`CondVar::wait_while`] - [`CondVar::wait_timeout_while`] - [`DebugMap::key`] - [`DebugMap::value`] - [`ManuallyDrop::take`] - [`matches!`] - [`ptr::slice_from_raw_parts_mut`] - [`ptr::slice_from_raw_parts`] Cargo ----- - [You no longer need to include `extern crate proc_macro;` to be able to `use proc_macro;` in the `2018` edition.][cargo/7700] Compatibility Notes ------------------- - [`Error::description` has been deprecated, and its use will now produce a warning.][66919] It's recommended to use `Display`/`to_string` instead. - [`use $crate;` inside macros is now a hard error.][37390] The compiler emitted forward compatibility warnings since Rust 1.14.0. - [As previously announced, this release reduces the level of support for 32-bit Apple targets to tier 3.][apple-32bit-drop]. This means that the source code is still available to build, but the targets are no longer tested and no release binary is distributed by the Rust project. Please refer to the linked blog post for more information. [37390]: rust-lang/rust#37390 [68253]: rust-lang/rust#68253 [68348]: rust-lang/rust#68348 [67935]: rust-lang/rust#67935 [68339]: rust-lang/rust#68339 [68122]: rust-lang/rust#68122 [67712]: rust-lang/rust#67712 [67887]: rust-lang/rust#67887 [67131]: rust-lang/rust#67131 [67233]: rust-lang/rust#67233 [66899]: rust-lang/rust#66899 [66919]: rust-lang/rust#66919 [66254]: rust-lang/rust#66254 [cargo/7700]: rust-lang/cargo#7700 [`DebugMap::key`]: https://doc.rust-lang.org/stable/std/fmt/struct.DebugMap.html#method.key [`DebugMap::value`]: https://doc.rust-lang.org/stable/std/fmt/struct.DebugMap.html#method.value [`ManuallyDrop::take`]: https://doc.rust-lang.org/stable/std/mem/struct.ManuallyDrop.html#method.take [`matches!`]: https://doc.rust-lang.org/stable/std/macro.matches.html [`ptr::slice_from_raw_parts_mut`]: https://doc.rust-lang.org/stable/std/ptr/fn.slice_from_raw_parts_mut.html [`ptr::slice_from_raw_parts`]: https://doc.rust-lang.org/stable/std/ptr/fn.slice_from_raw_parts.html [`CondVar::wait_while`]: https://doc.rust-lang.org/stable/std/sync/struct.Condvar.html#method.wait_while [`CondVar::wait_timeout_while`]: https://doc.rust-lang.org/stable/std/sync/struct.Condvar.html#method.wait_timeout_while
Stabilization report
The following is the stabilization report for
#![feature(transparent_enums)]
.Tracking issue: #60405
Version target: 1.42 (2020-01-30 => beta, 2020-03-12 => stable).
User guide
A
struct
with only a single non-ZST field (let's call itfoo
) can be marked as#[repr(transparent)]
. Such astruct
has the same layout and ABI asfoo
. Here, we also extend this ability toenum
s with only one variant, subject to the same restrictions as for the equivalentstruct
. That is, you can now write:which, in terms of layout and ABI, is equivalent to:
Motivation
This is not a major feature that will unlock new and important use-cases. The utility of
repr(transparent)
enum
s is indeed limited. However, there is still some value in it:It provides conceptual simplification of the language in terms of treating univariant
enum
s andstruct
s the same, as both are product types. Indeed, languages like Haskell only havedata
as the only way to construct user-defined ADTs in the language.In rare occasions, it might be that the user started out with a univariant
enum
for whatever reason (e.g. they thought they might extend it later). Now they want to make thisenum
transparent
without breaking users by turning it into astruct
. By lifting the restriction here, now they can.Technical specification
The reference specifies
repr(transparent)
on astruct
as:Here, we amend this to include univariant
enum
s as well with the same static restrictions and the same effects on dynamic semantics.Tests
All the relevant tests are adjusted in the PR diff but are recounted here:
src/test/ui/repr/repr-transparent.rs
checks thatrepr(transparent)
on anenum
must be univariant, rather than having zero or more than one variant. Restrictions on the fields inside the only variants, like for those onstruct
s, are also checked here.A number of codegen tests are provided as well:
src/test/codegen/repr-transparent.rs
(the canonical test)src/test/codegen/repr-transparent-aggregates-1.rs
src/test/codegen/repr-transparent-aggregates-2.rs
src/test/codegen/repr-transparent-aggregates-3.rs
src/test/ui/lint/lint-ctypes-enum.rs
tests the interactions with theimproper_ctypes
lint.History
2019-04-30, RFC Transparent Unions and Enums rfcs#2645
Author: @mjbshaw
Reviewers: The Language Team
This is the RFC that proposes allowing
#[repr(transparent)]
onenum
s andunion
.2019-06-11, PR Implement RFC 2645 (transparent enums and unions) #60463
Author: @mjbshaw
Reviewers: @varkor and @rkruppe
The PR implements the RFC aforementioned in full.
2019, PR make transparent enums more ordinary #67323
Author: @Centril
Reviewers: @davidtwco
The PR reorganizes the static checks taking advantage of the fact that
struct
s andunion
s are internally represented as ADTs with a single variant.This PR stabilizes
transparent_enums
.Related / possible future work
The remaining work here is to figure out the semantics of
#[repr(transparent)]
onunion
s and stabilize those. This work continues to be tracked in #60405.