From 93efe41b4ef9e0cccedbf962381002d48b3f780c Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sat, 11 Jan 2020 00:53:54 +0100 Subject: [PATCH 1/2] stabilize transparent_enums --- .../language-features/transparent-enums.md | 93 ------------------- src/librustc_feature/accepted.rs | 2 + src/librustc_feature/active.rs | 3 - src/librustc_typeck/check/mod.rs | 10 -- .../codegen/repr-transparent-aggregates-1.rs | 2 +- .../codegen/repr-transparent-aggregates-2.rs | 2 +- .../codegen/repr-transparent-aggregates-3.rs | 2 +- src/test/codegen/repr-transparent.rs | 2 +- .../feature-gate-transparent_enums.rs | 6 -- .../feature-gate-transparent_enums.stderr | 12 --- src/test/ui/lint/lint-ctypes-enum.rs | 2 +- src/test/ui/repr/repr-transparent.rs | 2 +- 12 files changed, 8 insertions(+), 130 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/transparent-enums.md delete mode 100644 src/test/ui/feature-gates/feature-gate-transparent_enums.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-transparent_enums.stderr diff --git a/src/doc/unstable-book/src/language-features/transparent-enums.md b/src/doc/unstable-book/src/language-features/transparent-enums.md deleted file mode 100644 index 862411ab39203..0000000000000 --- a/src/doc/unstable-book/src/language-features/transparent-enums.md +++ /dev/null @@ -1,93 +0,0 @@ -# `transparent_enums` - -The tracking issue for this feature is [#60405] - -[60405]: https://github.com/rust-lang/rust/issues/60405 - ----- - -The `transparent_enums` feature allows you mark `enum`s as -`#[repr(transparent)]`. An `enum` may be `#[repr(transparent)]` if it has -exactly one variant, and that variant matches the same conditions which `struct` -requires for transparency. Some concrete illustrations follow. - -```rust -#![feature(transparent_enums)] - -// This enum has the same representation as `f32`. -#[repr(transparent)] -enum SingleFieldEnum { - Variant(f32) -} - -// This enum has the same representation as `usize`. -#[repr(transparent)] -enum MultiFieldEnum { - Variant { field: usize, nothing: () }, -} -``` - -For consistency with transparent `struct`s, `enum`s must have exactly one -non-zero-sized field. If all fields are zero-sized, the `enum` must not be -`#[repr(transparent)]`: - -```rust -#![feature(transparent_enums)] - -// This (non-transparent) enum is already valid in stable Rust: -pub enum GoodEnum { - Nothing, -} - -// Error: transparent enum needs exactly one non-zero-sized field, but has 0 -// #[repr(transparent)] -// pub enum BadEnum { -// Nothing(()), -// } - -// Error: transparent enum needs exactly one non-zero-sized field, but has 0 -// #[repr(transparent)] -// pub enum BadEmptyEnum { -// Nothing, -// } -``` - -The one exception is if the `enum` is generic over `T` and has a field of type -`T`, it may be `#[repr(transparent)]` even if `T` is a zero-sized type: - -```rust -#![feature(transparent_enums)] - -// This enum has the same representation as `T`. -#[repr(transparent)] -pub enum GenericEnum { - Variant(T, ()), -} - -// This is okay even though `()` is a zero-sized type. -pub const THIS_IS_OKAY: GenericEnum<()> = GenericEnum::Variant((), ()); -``` - -Transparent `enum`s require exactly one variant: - -```rust -// Error: transparent enum needs exactly one variant, but has 0 -// #[repr(transparent)] -// pub enum TooFewVariants { -// } - -// Error: transparent enum needs exactly one variant, but has 2 -// #[repr(transparent)] -// pub enum TooManyVariants { -// First(usize), -// Second, -// } -``` - -Like transarent `struct`s, a transparent `enum` of type `E` has the same layout, -size, and ABI as its single non-ZST field. If it is generic over a type `T`, and -all its fields are ZSTs except for exactly one field of type `T`, then it has -the same layout and ABI as `T` (even if `T` is a ZST when monomorphized). - -Like transparent `struct`s, transparent `enum`s are FFI-safe if and only if -their underlying representation type is also FFI-safe. diff --git a/src/librustc_feature/accepted.rs b/src/librustc_feature/accepted.rs index 007cee4c76424..18dc3e30db1d4 100644 --- a/src/librustc_feature/accepted.rs +++ b/src/librustc_feature/accepted.rs @@ -257,6 +257,8 @@ declare_features! ( /// Allows relaxing the coherence rules such that /// `impl ForeignTrait for ForeignType` is permitted. (accepted, re_rebalance_coherence, "1.41.0", Some(55437), None), + /// Allows #[repr(transparent)] on univariant enums (RFC 2645). + (accepted, transparent_enums, "1.42.0", Some(60405), None), /// Allows using subslice patterns, `[a, .., b]` and `[a, xs @ .., b]`. (accepted, slice_patterns, "1.42.0", Some(62254), None), diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 6af9b6c087278..f20a57ea61c42 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -468,9 +468,6 @@ declare_features! ( /// Allows `if/while p && let q = r && ...` chains. (active, let_chains, "1.37.0", Some(53667), None), - /// Allows #[repr(transparent)] on enums (RFC 2645). - (active, transparent_enums, "1.37.0", Some(60405), None), - /// Allows #[repr(transparent)] on unions (RFC 2645). (active, transparent_unions, "1.37.0", Some(60405), None), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f7df630fb90b1..0c8830717aa3b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2433,16 +2433,6 @@ fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) { } let sp = tcx.sess.source_map().def_span(sp); - if adt.is_enum() && !tcx.features().transparent_enums { - feature_err( - &tcx.sess.parse_sess, - sym::transparent_enums, - sp, - "transparent enums are unstable", - ) - .emit(); - } - if adt.is_union() && !tcx.features().transparent_unions { feature_err( &tcx.sess.parse_sess, diff --git a/src/test/codegen/repr-transparent-aggregates-1.rs b/src/test/codegen/repr-transparent-aggregates-1.rs index 1c8959619d3b2..018a7ba4756a9 100644 --- a/src/test/codegen/repr-transparent-aggregates-1.rs +++ b/src/test/codegen/repr-transparent-aggregates-1.rs @@ -10,7 +10,7 @@ // ignore-windows // See repr-transparent.rs -#![feature(transparent_enums, transparent_unions)] +#![feature(transparent_unions)] #![crate_type="lib"] diff --git a/src/test/codegen/repr-transparent-aggregates-2.rs b/src/test/codegen/repr-transparent-aggregates-2.rs index afefb9c9f71a5..5669858672074 100644 --- a/src/test/codegen/repr-transparent-aggregates-2.rs +++ b/src/test/codegen/repr-transparent-aggregates-2.rs @@ -13,7 +13,7 @@ // ignore-x86_64 // See repr-transparent.rs -#![feature(transparent_enums, transparent_unions)] +#![feature(transparent_unions)] #![crate_type="lib"] diff --git a/src/test/codegen/repr-transparent-aggregates-3.rs b/src/test/codegen/repr-transparent-aggregates-3.rs index 1a59c9b48b976..e538be687801e 100644 --- a/src/test/codegen/repr-transparent-aggregates-3.rs +++ b/src/test/codegen/repr-transparent-aggregates-3.rs @@ -3,7 +3,7 @@ // only-mips64 // See repr-transparent.rs -#![feature(transparent_enums, transparent_unions)] +#![feature(transparent_unions)] #![crate_type="lib"] diff --git a/src/test/codegen/repr-transparent.rs b/src/test/codegen/repr-transparent.rs index e705d5ce3cd72..49fd015624ace 100644 --- a/src/test/codegen/repr-transparent.rs +++ b/src/test/codegen/repr-transparent.rs @@ -1,7 +1,7 @@ // compile-flags: -C no-prepopulate-passes #![crate_type="lib"] -#![feature(repr_simd, transparent_enums, transparent_unions)] +#![feature(repr_simd, transparent_unions)] use std::marker::PhantomData; diff --git a/src/test/ui/feature-gates/feature-gate-transparent_enums.rs b/src/test/ui/feature-gates/feature-gate-transparent_enums.rs deleted file mode 100644 index 0a7a73a168ed5..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-transparent_enums.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[repr(transparent)] -enum OkButUnstableEnum { //~ ERROR transparent enums are unstable - Foo((), String, ()), -} - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr b/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr deleted file mode 100644 index 8e727c33f20f8..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: transparent enums are unstable - --> $DIR/feature-gate-transparent_enums.rs:2:1 - | -LL | enum OkButUnstableEnum { - | ^^^^^^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/60405 - = help: add `#![feature(transparent_enums)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/lint/lint-ctypes-enum.rs b/src/test/ui/lint/lint-ctypes-enum.rs index 3898e67a07f7e..ccda005575c6e 100644 --- a/src/test/ui/lint/lint-ctypes-enum.rs +++ b/src/test/ui/lint/lint-ctypes-enum.rs @@ -1,4 +1,4 @@ -#![feature(transparent_enums, transparent_unions)] +#![feature(transparent_unions)] #![feature(ptr_internals)] #![deny(improper_ctypes)] #![allow(dead_code)] diff --git a/src/test/ui/repr/repr-transparent.rs b/src/test/ui/repr/repr-transparent.rs index 730d428ff500b..969a323238ff5 100644 --- a/src/test/ui/repr/repr-transparent.rs +++ b/src/test/ui/repr/repr-transparent.rs @@ -3,7 +3,7 @@ // - repr-transparent-other-reprs.rs // - repr-transparent-other-items.rs -#![feature(repr_align, transparent_enums, transparent_unions)] +#![feature(transparent_unions)] use std::marker::PhantomData; From 25460ebef6ae94494fc89a736a2f51bef2ea55c3 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Sun, 12 Jan 2020 16:05:18 +0100 Subject: [PATCH 2/2] transparent_enums: test alignment --- src/test/ui/repr/repr-transparent.rs | 10 ++++++++++ src/test/ui/repr/repr-transparent.stderr | 18 +++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/test/ui/repr/repr-transparent.rs b/src/test/ui/repr/repr-transparent.rs index 969a323238ff5..8fbdb4cc80b5e 100644 --- a/src/test/ui/repr/repr-transparent.rs +++ b/src/test/ui/repr/repr-transparent.rs @@ -60,6 +60,16 @@ enum TooManyVariants { //~ ERROR transparent enum needs exactly one variant, but Bar, } +#[repr(transparent)] +enum NontrivialAlignZstEnum { + Foo(u32, [u16; 0]), //~ ERROR alignment larger than 1 +} + +#[repr(transparent)] +enum GenericAlignEnum { + Foo { bar: ZstAlign32, baz: u32 } //~ ERROR alignment larger than 1 +} + #[repr(transparent)] union UnitUnion { //~ ERROR transparent union needs exactly one non-zero-sized field, but has 0 u: (), diff --git a/src/test/ui/repr/repr-transparent.stderr b/src/test/ui/repr/repr-transparent.stderr index f0c1fbe8ac9e1..cbc74fbb6a2cf 100644 --- a/src/test/ui/repr/repr-transparent.stderr +++ b/src/test/ui/repr/repr-transparent.stderr @@ -94,14 +94,26 @@ LL | Foo(String), LL | Bar, | --- too many variants in `TooManyVariants` +error[E0691]: zero-sized field in transparent enum has alignment larger than 1 + --> $DIR/repr-transparent.rs:65:14 + | +LL | Foo(u32, [u16; 0]), + | ^^^^^^^^ has alignment larger than 1 + +error[E0691]: zero-sized field in transparent enum has alignment larger than 1 + --> $DIR/repr-transparent.rs:70:11 + | +LL | Foo { bar: ZstAlign32, baz: u32 } + | ^^^^^^^^^^^^^^^^^^ has alignment larger than 1 + error[E0690]: transparent union needs exactly one non-zero-sized field, but has 0 - --> $DIR/repr-transparent.rs:64:1 + --> $DIR/repr-transparent.rs:74:1 | LL | union UnitUnion { | ^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 0 error[E0690]: transparent union needs exactly one non-zero-sized field, but has 2 - --> $DIR/repr-transparent.rs:69:1 + --> $DIR/repr-transparent.rs:79:1 | LL | union TooManyFields { | ^^^^^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 2 @@ -110,7 +122,7 @@ LL | u: u32, LL | s: i32 | ------ this field is non-zero-sized -error: aborting due to 15 previous errors +error: aborting due to 17 previous errors Some errors have detailed explanations: E0084, E0690, E0691, E0731. For more information about an error, try `rustc --explain E0084`.