stabilize transparent_enums
This commit is contained in:
parent
900811e430
commit
93efe41b4e
12 changed files with 8 additions and 130 deletions
|
@ -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<T> {
|
|
||||||
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.
|
|
|
@ -257,6 +257,8 @@ declare_features! (
|
||||||
/// Allows relaxing the coherence rules such that
|
/// Allows relaxing the coherence rules such that
|
||||||
/// `impl<T> ForeignTrait<LocalType> for ForeignType<T>` is permitted.
|
/// `impl<T> ForeignTrait<LocalType> for ForeignType<T>` is permitted.
|
||||||
(accepted, re_rebalance_coherence, "1.41.0", Some(55437), None),
|
(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]`.
|
/// Allows using subslice patterns, `[a, .., b]` and `[a, xs @ .., b]`.
|
||||||
(accepted, slice_patterns, "1.42.0", Some(62254), None),
|
(accepted, slice_patterns, "1.42.0", Some(62254), None),
|
||||||
|
|
||||||
|
|
|
@ -468,9 +468,6 @@ declare_features! (
|
||||||
/// Allows `if/while p && let q = r && ...` chains.
|
/// Allows `if/while p && let q = r && ...` chains.
|
||||||
(active, let_chains, "1.37.0", Some(53667), None),
|
(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).
|
/// Allows #[repr(transparent)] on unions (RFC 2645).
|
||||||
(active, transparent_unions, "1.37.0", Some(60405), None),
|
(active, transparent_unions, "1.37.0", Some(60405), None),
|
||||||
|
|
||||||
|
|
|
@ -2433,16 +2433,6 @@ fn check_transparent(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
|
||||||
}
|
}
|
||||||
let sp = tcx.sess.source_map().def_span(sp);
|
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 {
|
if adt.is_union() && !tcx.features().transparent_unions {
|
||||||
feature_err(
|
feature_err(
|
||||||
&tcx.sess.parse_sess,
|
&tcx.sess.parse_sess,
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
// ignore-windows
|
// ignore-windows
|
||||||
// See repr-transparent.rs
|
// See repr-transparent.rs
|
||||||
|
|
||||||
#![feature(transparent_enums, transparent_unions)]
|
#![feature(transparent_unions)]
|
||||||
|
|
||||||
#![crate_type="lib"]
|
#![crate_type="lib"]
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// ignore-x86_64
|
// ignore-x86_64
|
||||||
// See repr-transparent.rs
|
// See repr-transparent.rs
|
||||||
|
|
||||||
#![feature(transparent_enums, transparent_unions)]
|
#![feature(transparent_unions)]
|
||||||
|
|
||||||
#![crate_type="lib"]
|
#![crate_type="lib"]
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// only-mips64
|
// only-mips64
|
||||||
// See repr-transparent.rs
|
// See repr-transparent.rs
|
||||||
|
|
||||||
#![feature(transparent_enums, transparent_unions)]
|
#![feature(transparent_unions)]
|
||||||
|
|
||||||
#![crate_type="lib"]
|
#![crate_type="lib"]
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// compile-flags: -C no-prepopulate-passes
|
// compile-flags: -C no-prepopulate-passes
|
||||||
|
|
||||||
#![crate_type="lib"]
|
#![crate_type="lib"]
|
||||||
#![feature(repr_simd, transparent_enums, transparent_unions)]
|
#![feature(repr_simd, transparent_unions)]
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
#[repr(transparent)]
|
|
||||||
enum OkButUnstableEnum { //~ ERROR transparent enums are unstable
|
|
||||||
Foo((), String, ()),
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
|
|
@ -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`.
|
|
|
@ -1,4 +1,4 @@
|
||||||
#![feature(transparent_enums, transparent_unions)]
|
#![feature(transparent_unions)]
|
||||||
#![feature(ptr_internals)]
|
#![feature(ptr_internals)]
|
||||||
#![deny(improper_ctypes)]
|
#![deny(improper_ctypes)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// - repr-transparent-other-reprs.rs
|
// - repr-transparent-other-reprs.rs
|
||||||
// - repr-transparent-other-items.rs
|
// - repr-transparent-other-items.rs
|
||||||
|
|
||||||
#![feature(repr_align, transparent_enums, transparent_unions)]
|
#![feature(transparent_unions)]
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue