Skip to content

Commit c3681d6

Browse files
committed
Auto merge of #68122 - Centril:stabilize-transparent-enums, r=petrochenkov
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.
2 parents a237641 + 25460eb commit c3681d6

File tree

13 files changed

+33
-133
lines changed

13 files changed

+33
-133
lines changed

src/doc/unstable-book/src/language-features/transparent-enums.md

Lines changed: 0 additions & 93 deletions
This file was deleted.

src/librustc_feature/accepted.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ declare_features! (
257257
/// Allows relaxing the coherence rules such that
258258
/// `impl<T> ForeignTrait<LocalType> for ForeignType<T>` is permitted.
259259
(accepted, re_rebalance_coherence, "1.41.0", Some(55437), None),
260+
/// Allows #[repr(transparent)] on univariant enums (RFC 2645).
261+
(accepted, transparent_enums, "1.42.0", Some(60405), None),
260262
/// Allows using subslice patterns, `[a, .., b]` and `[a, xs @ .., b]`.
261263
(accepted, slice_patterns, "1.42.0", Some(62254), None),
262264

src/librustc_feature/active.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -468,9 +468,6 @@ declare_features! (
468468
/// Allows `if/while p && let q = r && ...` chains.
469469
(active, let_chains, "1.37.0", Some(53667), None),
470470

471-
/// Allows #[repr(transparent)] on enums (RFC 2645).
472-
(active, transparent_enums, "1.37.0", Some(60405), None),
473-
474471
/// Allows #[repr(transparent)] on unions (RFC 2645).
475472
(active, transparent_unions, "1.37.0", Some(60405), None),
476473

src/librustc_typeck/check/mod.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2434,16 +2434,6 @@ fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
24342434
}
24352435
let sp = tcx.sess.source_map().def_span(sp);
24362436

2437-
if adt.is_enum() && !tcx.features().transparent_enums {
2438-
feature_err(
2439-
&tcx.sess.parse_sess,
2440-
sym::transparent_enums,
2441-
sp,
2442-
"transparent enums are unstable",
2443-
)
2444-
.emit();
2445-
}
2446-
24472437
if adt.is_union() && !tcx.features().transparent_unions {
24482438
feature_err(
24492439
&tcx.sess.parse_sess,

src/test/codegen/repr-transparent-aggregates-1.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// ignore-windows
1111
// See repr-transparent.rs
1212

13-
#![feature(transparent_enums, transparent_unions)]
13+
#![feature(transparent_unions)]
1414

1515
#![crate_type="lib"]
1616

src/test/codegen/repr-transparent-aggregates-2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// ignore-x86_64
1414
// See repr-transparent.rs
1515

16-
#![feature(transparent_enums, transparent_unions)]
16+
#![feature(transparent_unions)]
1717

1818
#![crate_type="lib"]
1919

src/test/codegen/repr-transparent-aggregates-3.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// only-mips64
44
// See repr-transparent.rs
55

6-
#![feature(transparent_enums, transparent_unions)]
6+
#![feature(transparent_unions)]
77

88
#![crate_type="lib"]
99

src/test/codegen/repr-transparent.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// compile-flags: -C no-prepopulate-passes
22

33
#![crate_type="lib"]
4-
#![feature(repr_simd, transparent_enums, transparent_unions)]
4+
#![feature(repr_simd, transparent_unions)]
55

66
use std::marker::PhantomData;
77

src/test/ui/feature-gates/feature-gate-transparent_enums.rs

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/test/ui/feature-gates/feature-gate-transparent_enums.stderr

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)