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: https://github.com/rust-lang/rust/issues/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 https://github.com/rust-lang/rfcs/pull/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 https://github.com/rust-lang/rust/pull/60463 Author: @mjbshaw Reviewers: @varkor and @rkruppe The PR implements the RFC aforementioned in full. - 2019, PR https://github.com/rust-lang/rust/pull/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 https://github.com/rust-lang/rust/issues/60405. |
||
|---|---|---|
| .. | ||
| auxiliary | ||
| dllimports | ||
| intrinsics | ||
| non-terminate | ||
| remap_path_prefix | ||
| simd-intrinsic | ||
| abi-efiapi.rs | ||
| abi-main-signature-16bit-c-int.rs | ||
| abi-main-signature-32bit-c-int.rs | ||
| abi-sysv64.rs | ||
| abi-x86-interrupt.rs | ||
| abi-x86_64_sysv.rs | ||
| adjustments.rs | ||
| align-enum.rs | ||
| align-struct.rs | ||
| alloc-optimisation.rs | ||
| bool-cmp.rs | ||
| box-maybe-uninit.rs | ||
| c-variadic-copy.rs | ||
| c-variadic-opt.rs | ||
| c-variadic.rs | ||
| call-metadata.rs | ||
| coercions.rs | ||
| consts.rs | ||
| dealloc-no-unwind.rs | ||
| drop.rs | ||
| enum-bounds-check.rs | ||
| enum-debug-clike.rs | ||
| enum-debug-niche-2.rs | ||
| enum-debug-niche.rs | ||
| enum-debug-tagged.rs | ||
| export-no-mangle.rs | ||
| external-no-mangle-fns.rs | ||
| external-no-mangle-statics.rs | ||
| fastcall-inreg.rs | ||
| fatptr.rs | ||
| ffi-returns-twice.rs | ||
| float_math.rs | ||
| fn-impl-trait-self.rs | ||
| foo.s | ||
| force-frame-pointers.rs | ||
| function-arguments.rs | ||
| gdb_debug_script_load.rs | ||
| generic-debug.rs | ||
| global_asm.rs | ||
| global_asm_include.rs | ||
| global_asm_x2.rs | ||
| i686-macosx-deployment-target.rs | ||
| i686-no-macosx-deployment-target.rs | ||
| inline-always-works-always.rs | ||
| instrument-mcount.rs | ||
| integer-cmp.rs | ||
| internalize-closures.rs | ||
| intrinsic-no-unnamed-attr.rs | ||
| issue-13018.rs | ||
| issue-15953.rs | ||
| issue-32031.rs | ||
| issue-32364.rs | ||
| issue-34947-pow-i32.rs | ||
| issue-37945.rs | ||
| issue-44056-macos-tls-align.rs | ||
| issue-45222.rs | ||
| issue-45466.rs | ||
| issue-47278.rs | ||
| issue-47442.rs | ||
| issue-56267-2.rs | ||
| issue-56267.rs | ||
| issue-56927.rs | ||
| issue-58881.rs | ||
| iter-fold-closure-no-dupes.rs | ||
| iter-fold-closure-no-iterator.rs | ||
| lifetime_start_end.rs | ||
| link-dead-code.rs | ||
| link_section.rs | ||
| loads.rs | ||
| local-generics-in-exe-internalized.rs | ||
| lto-removes-invokes.rs | ||
| mainsubprogram.rs | ||
| mainsubprogramstart.rs | ||
| match-optimizes-away.rs | ||
| match.rs | ||
| mir_zst_stores.rs | ||
| naked-functions.rs | ||
| no-assumes-on-casts.rs | ||
| no-dllimport-w-cross-lang-lto.rs | ||
| no-output-asm-is-volatile.rs | ||
| no-plt.rs | ||
| noreturn-uninhabited.rs | ||
| noreturnflag.rs | ||
| nounwind.rs | ||
| optimize-attr-1.rs | ||
| packed.rs | ||
| panic-abort-windows.rs | ||
| personality_lifetimes.rs | ||
| pgo-instrumentation.rs | ||
| README.md | ||
| refs.rs | ||
| repeat-trusted-len.rs | ||
| repr-transparent-aggregates-1.rs | ||
| repr-transparent-aggregates-2.rs | ||
| repr-transparent-aggregates-3.rs | ||
| repr-transparent-sysv64.rs | ||
| repr-transparent.rs | ||
| sanitizer-memory-track-orgins.rs | ||
| sanitizer-recover.rs | ||
| scalar-pair-bool.rs | ||
| set-discriminant-invalid.rs | ||
| slice-init.rs | ||
| slice-iter-len-eq-zero.rs | ||
| slice-position-bounds-check.rs | ||
| sparc-struct-abi.rs | ||
| stack-probes.rs | ||
| stores.rs | ||
| swap-small-types.rs | ||
| target-cpu-on-functions.rs | ||
| target-feature-on-functions.rs | ||
| try_identity.rs | ||
| unchecked-float-casts.rs | ||
| union-abi.rs | ||
| unwind-extern-exports.rs | ||
| unwind-extern-imports.rs | ||
| var-names.rs | ||
| vec-clear.rs | ||
| vec-iter-collect-len.rs | ||
| vec-optimizes-away.rs | ||
| vtabletype.rs | ||
| x86_64-macosx-deployment-target.rs | ||
| x86_64-no-macosx-deployment-target.rs | ||
| x86_mmx.rs | ||
| zip.rs | ||
The files here use the LLVM FileCheck framework, documented at https://llvm.org/docs/CommandGuide/FileCheck.html.