diff options
Diffstat (limited to 'tests')
23 files changed, 611 insertions, 520 deletions
diff --git a/tests/ui/transmutability/arrays/huge-len.stderr b/tests/ui/transmutability/arrays/huge-len.stderr index 37160c5c959..3fc652f47c1 100644 --- a/tests/ui/transmutability/arrays/huge-len.stderr +++ b/tests/ui/transmutability/arrays/huge-len.stderr @@ -2,7 +2,7 @@ error[E0277]: `()` cannot be safely transmuted into `ExplicitlyPadded` --> $DIR/huge-len.rs:21:41 | LL | assert::is_maybe_transmutable::<(), ExplicitlyPadded>(); - | ^^^^^^^^^^^^^^^^ values of the type `ExplicitlyPadded` are too big for the current architecture + | ^^^^^^^^^^^^^^^^ analyzing the transmutability of `ExplicitlyPadded` is not yet supported | note: required by a bound in `is_maybe_transmutable` --> $DIR/huge-len.rs:8:14 @@ -17,7 +17,7 @@ error[E0277]: `ExplicitlyPadded` cannot be safely transmuted into `()` --> $DIR/huge-len.rs:24:55 | LL | assert::is_maybe_transmutable::<ExplicitlyPadded, ()>(); - | ^^ values of the type `ExplicitlyPadded` are too big for the current architecture + | ^^ analyzing the transmutability of `ExplicitlyPadded` is not yet supported | note: required by a bound in `is_maybe_transmutable` --> $DIR/huge-len.rs:8:14 diff --git a/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr index e486928a445..b4cd70142c4 100644 --- a/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr +++ b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr @@ -2,7 +2,7 @@ error[E0277]: `[String; 0]` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:25:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ analyzing the transmutability of `[String; 0]` is not yet supported. + | ^^ analyzing the transmutability of `[String; 0]` is not yet supported | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -23,7 +23,7 @@ error[E0277]: `u128` cannot be safely transmuted into `[String; 0]` --> $DIR/should_require_well_defined_layout.rs:26:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ analyzing the transmutability of `[String; 0]` is not yet supported. + | ^^^^^^^^^ analyzing the transmutability of `[String; 0]` is not yet supported | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -44,7 +44,7 @@ error[E0277]: `[String; 1]` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:31:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ analyzing the transmutability of `[String; 1]` is not yet supported. + | ^^ analyzing the transmutability of `[String; 1]` is not yet supported | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -65,7 +65,7 @@ error[E0277]: `u128` cannot be safely transmuted into `[String; 1]` --> $DIR/should_require_well_defined_layout.rs:32:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ analyzing the transmutability of `[String; 1]` is not yet supported. + | ^^^^^^^^^ analyzing the transmutability of `[String; 1]` is not yet supported | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -86,7 +86,7 @@ error[E0277]: `[String; 2]` cannot be safely transmuted into `()` --> $DIR/should_require_well_defined_layout.rs:37:52 | LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ analyzing the transmutability of `[String; 2]` is not yet supported. + | ^^ analyzing the transmutability of `[String; 2]` is not yet supported | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 @@ -107,7 +107,7 @@ error[E0277]: `u128` cannot be safely transmuted into `[String; 2]` --> $DIR/should_require_well_defined_layout.rs:38:47 | LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ analyzing the transmutability of `[String; 2]` is not yet supported. + | ^^^^^^^^^ analyzing the transmutability of `[String; 2]` is not yet supported | note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:12:14 diff --git a/tests/ui/transmutability/enums/niche_optimization.rs b/tests/ui/transmutability/enums/niche_optimization.rs new file mode 100644 index 00000000000..23f57ecad75 --- /dev/null +++ b/tests/ui/transmutability/enums/niche_optimization.rs @@ -0,0 +1,156 @@ +//@ check-pass +//! Checks that niche optimizations are encoded correctly. +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, { + Assume { + alignment: false, + lifetimes: false, + safety: true, + validity: false, + } + }> + {} + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, { + Assume { + alignment: false, + lifetimes: false, + safety: true, + validity: true, + } + }> + {} +} + +#[repr(u8)] enum V0 { V = 0 } +#[repr(u8)] enum V1 { V = 1 } +#[repr(u8)] enum V2 { V = 2 } +#[repr(u8)] enum V253 { V = 253 } +#[repr(u8)] enum V254 { V = 254 } +#[repr(u8)] enum V255 { V = 255 } + +fn bool() { + enum OptionLike { + A(bool), + B, + } + + const _: () = { + assert!(std::mem::size_of::<OptionLike>() == 1); + }; + + assert::is_transmutable::<OptionLike, u8>(); + + assert::is_transmutable::<bool, OptionLike>(); + assert::is_transmutable::<V0, OptionLike>(); + assert::is_transmutable::<V1, OptionLike>(); + assert::is_transmutable::<V2, OptionLike>(); +} + +fn one_niche() { + #[repr(u8)] + enum N1 { + S = 0, + E = 255 - 1, + } + + enum OptionLike { + A(N1), + B, + } + + const _: () = { + assert!(std::mem::size_of::<OptionLike>() == 1); + }; + + assert::is_transmutable::<OptionLike, u8>(); + assert::is_transmutable::<V0, OptionLike>(); + assert::is_transmutable::<V254, OptionLike>(); + assert::is_transmutable::<V255, OptionLike>(); +} + +fn one_niche_alt() { + #[repr(u8)] + enum N1 { + S = 1, + E = 255 - 1, + } + + enum OptionLike { + A(N1), + B, + C, + } + + const _: () = { + assert!(std::mem::size_of::<OptionLike>() == 1); + }; + + assert::is_transmutable::<OptionLike, u8>(); + assert::is_transmutable::<V0, OptionLike>(); + assert::is_transmutable::<V254, OptionLike>(); + assert::is_transmutable::<V255, OptionLike>(); +} + +fn two_niche() { + #[repr(u8)] + enum Niche { + S = 0, + E = 255 - 2, + } + + enum OptionLike { + A(Niche), + B, + C, + } + + const _: () = { + assert!(std::mem::size_of::<OptionLike>() == 1); + }; + + assert::is_transmutable::<OptionLike, u8>(); + assert::is_transmutable::<V0, OptionLike>(); + assert::is_transmutable::<V253, OptionLike>(); + assert::is_transmutable::<V254, OptionLike>(); + assert::is_transmutable::<V255, OptionLike>(); +} + +fn no_niche() { + use std::mem::MaybeUninit; + + #[repr(u8)] + enum Niche { + S = 0, + E = 255 - 1, + } + + enum OptionLike { + A(Niche), + B, + C, + } + + const _: () = { + assert!(std::mem::size_of::<OptionLike>() == 2); + }; + + #[repr(C)] + struct Pair<T, U>(T, U); + + assert::is_transmutable::<V0, Niche>(); + assert::is_transmutable::<V254, Niche>(); + assert::is_transmutable::<Pair<V0, Niche>, OptionLike>(); + assert::is_transmutable::<Pair<V1, MaybeUninit<u8>>, OptionLike>(); + assert::is_transmutable::<Pair<V2, MaybeUninit<u8>>, OptionLike>(); +} diff --git a/tests/ui/transmutability/enums/repr/padding_differences.rs b/tests/ui/transmutability/enums/repr/padding_differences.rs new file mode 100644 index 00000000000..d0e1502b5e2 --- /dev/null +++ b/tests/ui/transmutability/enums/repr/padding_differences.rs @@ -0,0 +1,80 @@ +//@ check-pass +//! Adapted from https://rust-lang.github.io/unsafe-code-guidelines/layout/enums.html#explicit-repr-annotation-without-c-compatibility +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +use std::mem::MaybeUninit; + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, { + Assume { + alignment: false, + lifetimes: false, + safety: true, + validity: false, + } + }> + {} + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, { + Assume { + alignment: false, + lifetimes: false, + safety: true, + validity: true, + } + }> + {} +} + +#[repr(u8)] enum V0 { V = 0 } +#[repr(u8)] enum V1 { V = 1 } + +fn repr_u8() { + #[repr(u8)] + enum TwoCases { + A(u8, u16), // 0x00 INIT INIT INIT + B(u16), // 0x01 PADD INIT INIT + } + + const _: () = { + assert!(std::mem::size_of::<TwoCases>() == 4); + }; + + #[repr(C)] struct TwoCasesA(V0, u8, u8, u8); + #[repr(C)] struct TwoCasesB(V1, MaybeUninit<u8>, u8, u8); + + assert::is_transmutable::<TwoCasesA, TwoCases>(); + assert::is_transmutable::<TwoCasesB, TwoCases>(); + + assert::is_maybe_transmutable::<TwoCases, TwoCasesA>(); + assert::is_maybe_transmutable::<TwoCases, TwoCasesB>(); +} + +fn repr_c_u8() { + #[repr(C, u8)] + enum TwoCases { + A(u8, u16), // 0x00 PADD INIT PADD INIT INIT + B(u16), // 0x01 PADD INIT INIT PADD PADD + } + + const _: () = { + assert!(std::mem::size_of::<TwoCases>() == 6); + }; + + #[repr(C)] struct TwoCasesA(V0, MaybeUninit<u8>, u8, MaybeUninit<u8>, u8, u8); + #[repr(C)] struct TwoCasesB(V1, MaybeUninit<u8>, u8, u8, MaybeUninit<u8>, MaybeUninit<u8>); + + assert::is_transmutable::<TwoCasesA, TwoCases>(); + assert::is_transmutable::<TwoCasesB, TwoCases>(); + + assert::is_maybe_transmutable::<TwoCases, TwoCasesA>(); + assert::is_maybe_transmutable::<TwoCases, TwoCasesB>(); +} diff --git a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.rs b/tests/ui/transmutability/enums/repr/should_handle_all.rs index 630e662b926..a8ec86fa40d 100644 --- a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.rs +++ b/tests/ui/transmutability/enums/repr/should_handle_all.rs @@ -1,5 +1,4 @@ -//! An enum must have a well-defined layout to participate in a transmutation. - +//@ check-pass #![crate_type = "lib"] #![feature(repr128)] #![feature(transmutability)] @@ -21,23 +20,17 @@ mod assert { {} } -fn should_reject_repr_rust() { - fn void() { - enum repr_rust {} - assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted - assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted - } - +fn should_accept_repr_rust() { fn singleton() { enum repr_rust { V } - assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted - assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::<repr_rust, ()>(); + assert::is_maybe_transmutable::<u128, repr_rust>(); } fn duplex() { enum repr_rust { A, B } - assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted - assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::<repr_rust, ()>(); + assert::is_maybe_transmutable::<u128, repr_rust>(); } } @@ -116,7 +109,7 @@ fn should_accept_primitive_reprs() } } -fn should_accept_repr_C() { +fn should_accept_repr_c() { #[repr(C)] enum repr_c { V } assert::is_maybe_transmutable::<repr_c, ()>(); assert::is_maybe_transmutable::<i128, repr_c>(); diff --git a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr deleted file mode 100644 index 2a683de6a65..00000000000 --- a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr +++ /dev/null @@ -1,135 +0,0 @@ -error[E0277]: `void::repr_rust` cannot be safely transmuted into `()` - --> $DIR/should_require_well_defined_layout.rs:27:52 - | -LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ analyzing the transmutability of `void::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:13:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `u128` cannot be safely transmuted into `void::repr_rust` - --> $DIR/should_require_well_defined_layout.rs:28:47 - | -LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ analyzing the transmutability of `void::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:13:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `singleton::repr_rust` cannot be safely transmuted into `()` - --> $DIR/should_require_well_defined_layout.rs:33:52 - | -LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ analyzing the transmutability of `singleton::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:13:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `u128` cannot be safely transmuted into `singleton::repr_rust` - --> $DIR/should_require_well_defined_layout.rs:34:47 - | -LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ analyzing the transmutability of `singleton::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:13:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `duplex::repr_rust` cannot be safely transmuted into `()` - --> $DIR/should_require_well_defined_layout.rs:39:52 - | -LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ analyzing the transmutability of `duplex::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:13:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `u128` cannot be safely transmuted into `duplex::repr_rust` - --> $DIR/should_require_well_defined_layout.rs:40:47 - | -LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ analyzing the transmutability of `duplex::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:13:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr index eeed8a62a2a..cabc7bcfef7 100644 --- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr +++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr @@ -8,7 +8,7 @@ error[E0277]: `Src` cannot be safely transmuted into `Dst` --> $DIR/unknown_src_field.rs:19:36 | LL | assert::is_transmutable::<Src, Dst>(); - | ^^^ `Dst` has an unknown layout + | ^^^ analyzing the transmutability of `Dst` is not yet supported | note: required by a bound in `is_transmutable` --> $DIR/unknown_src_field.rs:12:14 diff --git a/tests/ui/transmutability/maybeuninit.rs b/tests/ui/transmutability/maybeuninit.rs new file mode 100644 index 00000000000..77c3381c774 --- /dev/null +++ b/tests/ui/transmutability/maybeuninit.rs @@ -0,0 +1,43 @@ +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +use std::mem::MaybeUninit; + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }> + {} +} + +fn validity() { + // An initialized byte is a valid uninitialized byte. + assert::is_maybe_transmutable::<u8, MaybeUninit<u8>>(); + + // An uninitialized byte is never a valid initialized byte. + assert::is_maybe_transmutable::<MaybeUninit<u8>, u8>(); //~ ERROR: cannot be safely transmuted +} + +fn padding() { + #[repr(align(8))] + struct Align8; + + #[repr(u8)] + enum ImplicitlyPadded { + A(Align8), + } + + #[repr(u8)] + enum V0 { + V0 = 0, + } + + #[repr(C)] + struct ExplicitlyPadded(V0, MaybeUninit<[u8; 7]>); + + assert::is_maybe_transmutable::<ExplicitlyPadded, ImplicitlyPadded>(); + assert::is_maybe_transmutable::<ImplicitlyPadded, ExplicitlyPadded>(); +} diff --git a/tests/ui/transmutability/maybeuninit.stderr b/tests/ui/transmutability/maybeuninit.stderr new file mode 100644 index 00000000000..be7dcaf35ea --- /dev/null +++ b/tests/ui/transmutability/maybeuninit.stderr @@ -0,0 +1,18 @@ +error[E0277]: `MaybeUninit<u8>` cannot be safely transmuted into `u8` + --> $DIR/maybeuninit.rs:21:54 + | +LL | assert::is_maybe_transmutable::<MaybeUninit<u8>, u8>(); + | ^^ at least one value of `MaybeUninit<u8>` isn't a bit-valid value of `u8` + | +note: required by a bound in `is_maybe_transmutable` + --> $DIR/maybeuninit.rs:12:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/references/unsafecell.rs b/tests/ui/transmutability/references/unsafecell.rs new file mode 100644 index 00000000000..a8a1f969fb4 --- /dev/null +++ b/tests/ui/transmutability/references/unsafecell.rs @@ -0,0 +1,47 @@ +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +use std::cell::UnsafeCell; + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }> + {} +} + +fn value_to_value() { + // We accept value-to-value transmutations of `UnsafeCell`-containing types, + // because owning a value implies exclusive access. + assert::is_maybe_transmutable::<UnsafeCell<u8>, u8>(); + assert::is_maybe_transmutable::<u8, UnsafeCell<u8>>(); + assert::is_maybe_transmutable::<UnsafeCell<u8>, UnsafeCell<u8>>(); +} + +fn ref_to_ref() { + // We forbid `UnsafeCell`-containing ref-to-ref transmutations, because the + // two types may use different, incompatible synchronization strategies. + assert::is_maybe_transmutable::<&'static u8, &'static UnsafeCell<u8>>(); //~ ERROR: cannot be safely transmuted + + assert::is_maybe_transmutable::<&'static UnsafeCell<u8>, &'static UnsafeCell<u8>>(); //~ ERROR: cannot be safely transmuted +} + +fn mut_to_mut() { + // `UnsafeCell` does't matter for `&mut T` to `&mut U`, since exclusive + // borrows can't be used for shared access. + assert::is_maybe_transmutable::<&'static mut u8, &'static mut UnsafeCell<u8>>(); + assert::is_maybe_transmutable::<&'static mut UnsafeCell<u8>, &'static mut u8>(); + assert::is_maybe_transmutable::<&'static mut UnsafeCell<u8>, &'static mut UnsafeCell<u8>>(); +} + +fn mut_to_ref() { + // We don't care about `UnsafeCell` for transmutations in the form `&mut T + // -> &U`, because downgrading a `&mut T` to a `&U` deactivates `&mut T` for + // the lifetime of `&U`. + assert::is_maybe_transmutable::<&'static mut u8, &'static UnsafeCell<u8>>(); + assert::is_maybe_transmutable::<&'static mut UnsafeCell<u8>, &'static u8>(); + assert::is_maybe_transmutable::<&'static mut UnsafeCell<u8>, &'static UnsafeCell<u8>>(); +} diff --git a/tests/ui/transmutability/references/unsafecell.stderr b/tests/ui/transmutability/references/unsafecell.stderr new file mode 100644 index 00000000000..651eb8ceb26 --- /dev/null +++ b/tests/ui/transmutability/references/unsafecell.stderr @@ -0,0 +1,33 @@ +error[E0277]: `&u8` cannot be safely transmuted into `&UnsafeCell<u8>` + --> $DIR/unsafecell.rs:27:50 + | +LL | assert::is_maybe_transmutable::<&'static u8, &'static UnsafeCell<u8>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `&'static UnsafeCell<u8>` + | +note: required by a bound in `is_maybe_transmutable` + --> $DIR/unsafecell.rs:12:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `&UnsafeCell<u8>` cannot be safely transmuted into `&UnsafeCell<u8>` + --> $DIR/unsafecell.rs:29:62 + | +LL | assert::is_maybe_transmutable::<&'static UnsafeCell<u8>, &'static UnsafeCell<u8>>(); + | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `&'static UnsafeCell<u8>` + | +note: required by a bound in `is_maybe_transmutable` + --> $DIR/unsafecell.rs:12:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.rs b/tests/ui/transmutability/structs/repr/should_handle_all.rs index 2e673601baf..52c24eecf12 100644 --- a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.rs +++ b/tests/ui/transmutability/structs/repr/should_handle_all.rs @@ -1,3 +1,4 @@ +//@ check-pass //! A struct must have a well-defined layout to participate in a transmutation. #![crate_type = "lib"] @@ -20,47 +21,47 @@ mod assert { {} } -fn should_reject_repr_rust() +fn should_accept_repr_rust() { fn unit() { struct repr_rust; - assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted - assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::<repr_rust, ()>(); + assert::is_maybe_transmutable::<u128, repr_rust>(); } fn tuple() { struct repr_rust(); - assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted - assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::<repr_rust, ()>(); + assert::is_maybe_transmutable::<u128, repr_rust>(); } fn braces() { struct repr_rust{} - assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted - assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::<repr_rust, ()>(); + assert::is_maybe_transmutable::<u128, repr_rust>(); } fn aligned() { #[repr(align(1))] struct repr_rust{} - assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted - assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::<repr_rust, ()>(); + assert::is_maybe_transmutable::<u128, repr_rust>(); } fn packed() { #[repr(packed)] struct repr_rust{} - assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted - assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::<repr_rust, ()>(); + assert::is_maybe_transmutable::<u128, repr_rust>(); } fn nested() { struct repr_rust; #[repr(C)] struct repr_c(repr_rust); - assert::is_maybe_transmutable::<repr_c, ()>(); //~ ERROR cannot be safely transmuted - assert::is_maybe_transmutable::<u128, repr_c>(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::<repr_c, ()>(); + assert::is_maybe_transmutable::<u128, repr_c>(); } } -fn should_accept_repr_C() +fn should_accept_repr_c() { fn unit() { #[repr(C)] struct repr_c; diff --git a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr deleted file mode 100644 index 77788f72c21..00000000000 --- a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr +++ /dev/null @@ -1,267 +0,0 @@ -error[E0277]: `should_reject_repr_rust::unit::repr_rust` cannot be safely transmuted into `()` - --> $DIR/should_require_well_defined_layout.rs:27:52 - | -LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ analyzing the transmutability of `should_reject_repr_rust::unit::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:12:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::unit::repr_rust` - --> $DIR/should_require_well_defined_layout.rs:28:47 - | -LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::unit::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:12:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `should_reject_repr_rust::tuple::repr_rust` cannot be safely transmuted into `()` - --> $DIR/should_require_well_defined_layout.rs:33:52 - | -LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ analyzing the transmutability of `should_reject_repr_rust::tuple::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:12:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::tuple::repr_rust` - --> $DIR/should_require_well_defined_layout.rs:34:47 - | -LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::tuple::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:12:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `should_reject_repr_rust::braces::repr_rust` cannot be safely transmuted into `()` - --> $DIR/should_require_well_defined_layout.rs:39:52 - | -LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ analyzing the transmutability of `should_reject_repr_rust::braces::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:12:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::braces::repr_rust` - --> $DIR/should_require_well_defined_layout.rs:40:47 - | -LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::braces::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:12:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `aligned::repr_rust` cannot be safely transmuted into `()` - --> $DIR/should_require_well_defined_layout.rs:45:52 - | -LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ analyzing the transmutability of `aligned::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:12:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `u128` cannot be safely transmuted into `aligned::repr_rust` - --> $DIR/should_require_well_defined_layout.rs:46:47 - | -LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ analyzing the transmutability of `aligned::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:12:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `packed::repr_rust` cannot be safely transmuted into `()` - --> $DIR/should_require_well_defined_layout.rs:51:52 - | -LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ analyzing the transmutability of `packed::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:12:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `u128` cannot be safely transmuted into `packed::repr_rust` - --> $DIR/should_require_well_defined_layout.rs:52:47 - | -LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ analyzing the transmutability of `packed::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:12:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `nested::repr_c` cannot be safely transmuted into `()` - --> $DIR/should_require_well_defined_layout.rs:58:49 - | -LL | assert::is_maybe_transmutable::<repr_c, ()>(); - | ^^ analyzing the transmutability of `nested::repr_c` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:12:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `u128` cannot be safely transmuted into `nested::repr_c` - --> $DIR/should_require_well_defined_layout.rs:59:47 - | -LL | assert::is_maybe_transmutable::<u128, repr_c>(); - | ^^^^^^ analyzing the transmutability of `nested::repr_c` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:12:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error: aborting due to 12 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.rs b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.rs index 4c285a616b3..64110753832 100644 --- a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.rs +++ b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.rs @@ -22,4 +22,5 @@ fn should_pad_explicitly_packed_field() { //~^ ERROR: recursive type assert::is_maybe_transmutable::<ExplicitlyPadded, ()>(); + //~^ ERROR: cannot be safely transmuted } diff --git a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr index 7fb051f6625..ebfb5361143 100644 --- a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr +++ b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr @@ -15,7 +15,22 @@ error[E0391]: cycle detected when computing layout of `should_pad_explicitly_pac = note: cycle used when evaluating trait selection obligation `(): core::mem::transmutability::BikeshedIntrinsicFrom<should_pad_explicitly_packed_field::ExplicitlyPadded, core::mem::transmutability::Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error: aborting due to 2 previous errors +error[E0277]: `ExplicitlyPadded` cannot be safely transmuted into `()` + --> $DIR/transmute_infinitely_recursive_type.rs:24:55 + | +LL | assert::is_maybe_transmutable::<ExplicitlyPadded, ()>(); + | ^^ analyzing the transmutability of `ExplicitlyPadded` is not yet supported + | +note: required by a bound in `is_maybe_transmutable` + --> $DIR/transmute_infinitely_recursive_type.rs:14:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0072, E0391. +Some errors have detailed explanations: E0072, E0277, E0391. For more information about an error, try `rustc --explain E0072`. diff --git a/tests/ui/transmutability/transmute-padding-ice.rs b/tests/ui/transmutability/transmute-padding-ice.rs index 3f3f75bc086..f5935a0009e 100644 --- a/tests/ui/transmutability/transmute-padding-ice.rs +++ b/tests/ui/transmutability/transmute-padding-ice.rs @@ -1,7 +1,13 @@ +//@ check-pass +//! This UI test was introduced as check-fail by a buggy bug-fix for an ICE. In +//! fact, this transmutation should be valid. + #![crate_type = "lib"] #![feature(transmutability)] #![allow(dead_code)] +use std::mem::size_of; + mod assert { use std::mem::{Assume, BikeshedIntrinsicFrom}; @@ -22,6 +28,7 @@ fn test() { #[repr(C)] struct B(u8, u8); + assert_eq!(size_of::<A>(), size_of::<B>()); + assert::is_maybe_transmutable::<B, A>(); - //~^ ERROR cannot be safely transmuted } diff --git a/tests/ui/transmutability/transmute-padding-ice.stderr b/tests/ui/transmutability/transmute-padding-ice.stderr deleted file mode 100644 index 4c121d463c6..00000000000 --- a/tests/ui/transmutability/transmute-padding-ice.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0277]: `B` cannot be safely transmuted into `A` - --> $DIR/transmute-padding-ice.rs:25:40 - | -LL | assert::is_maybe_transmutable::<B, A>(); - | ^ the size of `B` is smaller than the size of `A` - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/transmute-padding-ice.rs:10:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom< - | ______________^ -LL | | Src, -LL | | { Assume { alignment: true, lifetimes: true, safety: true, validity: true } }, -LL | | >, - | |_________^ required by this bound in `is_maybe_transmutable` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/transmutability/uninhabited.rs b/tests/ui/transmutability/uninhabited.rs new file mode 100644 index 00000000000..b61b110f6a1 --- /dev/null +++ b/tests/ui/transmutability/uninhabited.rs @@ -0,0 +1,71 @@ +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::{Assume, BikeshedIntrinsicFrom}; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, { + Assume { + alignment: true, + lifetimes: true, + safety: true, + validity: true, + } + }> + {} +} + +fn void() { + enum Void {} + + // This transmutation is vacuously acceptable; since one cannot construct a + // `Void`, unsoundness cannot directly arise from transmuting a void into + // anything else. + assert::is_maybe_transmutable::<Void, u128>(); + + assert::is_maybe_transmutable::<(), Void>(); //~ ERROR: cannot be safely transmuted +} + +// Non-ZST uninhabited types are, nonetheless, uninhabited. +fn yawning_void() { + enum Void {} + + struct YawningVoid(Void, u128); + + const _: () = { + assert!(std::mem::size_of::<YawningVoid>() == std::mem::size_of::<u128>()); + // Just to be sure the above constant actually evaluated: + assert!(false); //~ ERROR: evaluation of constant value failed + }; + + // This transmutation is vacuously acceptable; since one cannot construct a + // `Void`, unsoundness cannot directly arise from transmuting a void into + // anything else. + assert::is_maybe_transmutable::<YawningVoid, u128>(); + + assert::is_maybe_transmutable::<(), Void>(); //~ ERROR: cannot be safely transmuted +} + +// References to uninhabited types are, logically, uninhabited, but for layout +// purposes are not ZSTs, and aren't treated as uninhabited when they appear in +// enum variants. +fn distant_void() { + enum Void {} + + enum DistantVoid { + A(&'static Void) + } + + const _: () = { + assert!(std::mem::size_of::<DistantVoid>() == std::mem::size_of::<usize>()); + // Just to be sure the above constant actually evaluated: + assert!(false); //~ ERROR: evaluation of constant value failed + }; + + assert::is_maybe_transmutable::<DistantVoid, ()>(); + assert::is_maybe_transmutable::<DistantVoid, &'static Void>(); + assert::is_maybe_transmutable::<u128, DistantVoid>(); //~ ERROR: cannot be safely transmuted +} diff --git a/tests/ui/transmutability/uninhabited.stderr b/tests/ui/transmutability/uninhabited.stderr new file mode 100644 index 00000000000..60219b0f263 --- /dev/null +++ b/tests/ui/transmutability/uninhabited.stderr @@ -0,0 +1,86 @@ +error[E0080]: evaluation of constant value failed + --> $DIR/uninhabited.rs:41:9 + | +LL | assert!(false); + | ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/uninhabited.rs:41:9 + | + = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0080]: evaluation of constant value failed + --> $DIR/uninhabited.rs:65:9 + | +LL | assert!(false); + | ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/uninhabited.rs:65:9 + | + = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: `()` cannot be safely transmuted into `void::Void` + --> $DIR/uninhabited.rs:29:41 + | +LL | assert::is_maybe_transmutable::<(), Void>(); + | ^^^^ `void::Void` is uninhabited + | +note: required by a bound in `is_maybe_transmutable` + --> $DIR/uninhabited.rs:10:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, { + | ______________^ +LL | | Assume { +LL | | alignment: true, +LL | | lifetimes: true, +... | +LL | | } +LL | | }> + | |__________^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `()` cannot be safely transmuted into `yawning_void::Void` + --> $DIR/uninhabited.rs:49:41 + | +LL | assert::is_maybe_transmutable::<(), Void>(); + | ^^^^ `yawning_void::Void` is uninhabited + | +note: required by a bound in `is_maybe_transmutable` + --> $DIR/uninhabited.rs:10:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, { + | ______________^ +LL | | Assume { +LL | | alignment: true, +LL | | lifetimes: true, +... | +LL | | } +LL | | }> + | |__________^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `u128` cannot be safely transmuted into `DistantVoid` + --> $DIR/uninhabited.rs:70:43 + | +LL | assert::is_maybe_transmutable::<u128, DistantVoid>(); + | ^^^^^^^^^^^ at least one value of `u128` isn't a bit-valid value of `DistantVoid` + | +note: required by a bound in `is_maybe_transmutable` + --> $DIR/uninhabited.rs:10:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this function +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, { + | ______________^ +LL | | Assume { +LL | | alignment: true, +LL | | lifetimes: true, +... | +LL | | } +LL | | }> + | |__________^ required by this bound in `is_maybe_transmutable` + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0080, E0277. +For more information about an error, try `rustc --explain E0080`. diff --git a/tests/ui/transmutability/unions/repr/should_handle_align.rs b/tests/ui/transmutability/unions/repr/should_handle_align.rs index 8668cca3cb5..ba4e904e161 100644 --- a/tests/ui/transmutability/unions/repr/should_handle_align.rs +++ b/tests/ui/transmutability/unions/repr/should_handle_align.rs @@ -25,13 +25,13 @@ fn should_pad_explicitly_aligned_field() { #[derive(Clone, Copy)] #[repr(u8)] enum V0u8 { V = 0 } #[derive(Clone, Copy)] #[repr(u8)] enum V1u8 { V = 1 } - #[repr(C)] + #[repr(align(1))] pub union Uninit { a: (), b: V1u8, } - #[repr(C, align(2))] + #[repr(align(2))] pub union align_2 { a: V0u8, } diff --git a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.rs b/tests/ui/transmutability/unions/repr/should_handle_all.rs index 8495b0ea88f..85d48dd9b7f 100644 --- a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.rs +++ b/tests/ui/transmutability/unions/repr/should_handle_all.rs @@ -1,7 +1,7 @@ -//! A struct must have a well-defined layout to participate in a transmutation. +//@ check-pass #![crate_type = "lib"] -#![feature(transmutability)] +#![feature(transmutability, transparent_unions)] #![allow(dead_code, incomplete_features, non_camel_case_types)] mod assert { @@ -20,17 +20,17 @@ mod assert { {} } -fn should_reject_repr_rust() +fn should_accept_repr_rust() { union repr_rust { a: u8 } - assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted - assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::<repr_rust, ()>(); + assert::is_maybe_transmutable::<u128, repr_rust>(); } -fn should_accept_repr_C() +fn should_accept_repr_c() { #[repr(C)] union repr_c { @@ -41,3 +41,15 @@ fn should_accept_repr_C() assert::is_maybe_transmutable::<repr_c, ()>(); assert::is_maybe_transmutable::<u128, repr_c>(); } + + +fn should_accept_transparent() +{ + #[repr(transparent)] + union repr_transparent { + a: u8 + } + + assert::is_maybe_transmutable::<repr_transparent, ()>(); + assert::is_maybe_transmutable::<u128, repr_transparent>(); +} diff --git a/tests/ui/transmutability/unions/repr/should_handle_packed.rs b/tests/ui/transmutability/unions/repr/should_handle_packed.rs index 4af6c1d3a61..fc06eba4353 100644 --- a/tests/ui/transmutability/unions/repr/should_handle_packed.rs +++ b/tests/ui/transmutability/unions/repr/should_handle_packed.rs @@ -27,7 +27,6 @@ fn should_pad_explicitly_packed_field() { #[derive(Clone, Copy)] #[repr(u8)] enum V2u8 { V = 2 } #[derive(Clone, Copy)] #[repr(u32)] enum V3u32 { V = 3 } - #[repr(C)] pub union Uninit { a: (), b: V1u8, diff --git a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr deleted file mode 100644 index bec07f13103..00000000000 --- a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr +++ /dev/null @@ -1,47 +0,0 @@ -error[E0277]: `should_reject_repr_rust::repr_rust` cannot be safely transmuted into `()` - --> $DIR/should_require_well_defined_layout.rs:29:48 - | -LL | assert::is_maybe_transmutable::<repr_rust, ()>(); - | ^^ analyzing the transmutability of `should_reject_repr_rust::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:12:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::repr_rust` - --> $DIR/should_require_well_defined_layout.rs:30:43 - | -LL | assert::is_maybe_transmutable::<u128, repr_rust>(); - | ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::repr_rust` is not yet supported. - | -note: required by a bound in `is_maybe_transmutable` - --> $DIR/should_require_well_defined_layout.rs:12:14 - | -LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this function -LL | where -LL | Dst: BikeshedIntrinsicFrom<Src, { - | ______________^ -LL | | Assume { -LL | | alignment: true, -LL | | lifetimes: true, -... | -LL | | } -LL | | }> - | |__________^ required by this bound in `is_maybe_transmutable` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. |
