diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/transmutability | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/transmutability')
74 files changed, 4128 insertions, 0 deletions
diff --git a/src/test/ui/transmutability/abstraction/abstracted_assume.rs b/src/test/ui/transmutability/abstraction/abstracted_assume.rs new file mode 100644 index 000000000..2abbbf3c1 --- /dev/null +++ b/src/test/ui/transmutability/abstraction/abstracted_assume.rs @@ -0,0 +1,73 @@ +// check-pass +//! The implementation should behave correctly when the `ASSUME` parameters are +//! provided indirectly through an abstraction. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable< + Src, + Dst, + Context, + const ASSUME_ALIGNMENT: bool, + const ASSUME_LIFETIMES: bool, + const ASSUME_VALIDITY: bool, + const ASSUME_VISIBILITY: bool, + >() + where + Dst: BikeshedIntrinsicFrom< + Src, + Context, + ASSUME_ALIGNMENT, + ASSUME_LIFETIMES, + ASSUME_VALIDITY, + ASSUME_VISIBILITY, + >, + {} +} + +fn direct() { + struct Context; + #[repr(C)] struct Src; + #[repr(C)] struct Dst; + + assert::is_transmutable::<Src, Dst, Context, false, false, false, false>(); +} + +fn via_const() { + struct Context; + #[repr(C)] struct Src; + #[repr(C)] struct Dst; + + const FALSE: bool = false; + + assert::is_transmutable::<Src, Dst, Context, FALSE, FALSE, FALSE, FALSE>(); +} + +fn via_associated_const() { + struct Context; + #[repr(C)] struct Src; + #[repr(C)] struct Dst; + + trait Trait { + const FALSE: bool = true; + } + + struct Ty; + + impl Trait for Ty {} + + assert::is_transmutable::< + Src, + Dst, + Context, + {Ty::FALSE}, + {Ty::FALSE}, + {Ty::FALSE}, + {Ty::FALSE} + >(); +} diff --git a/src/test/ui/transmutability/abstraction/const_generic_fn.rs b/src/test/ui/transmutability/abstraction/const_generic_fn.rs new file mode 100644 index 000000000..94c38bb28 --- /dev/null +++ b/src/test/ui/transmutability/abstraction/const_generic_fn.rs @@ -0,0 +1,41 @@ +// check-pass +//! An array must have the correct length. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn array_like<T, E, const N: usize>() + where + T: BikeshedIntrinsicFrom<[E; N], Context, false, false, false, true>, + [E; N]: BikeshedIntrinsicFrom<T, Context, false, false, false, true> + {} +} + +fn len_0() { + type Array = [u8; 0]; + #[repr(C)] struct Struct(); + assert::array_like::<Struct, u8, 0>(); +} + +fn len_1() { + type Array = [u8; 1]; + #[repr(C)] struct Struct(u8); + assert::array_like::<Struct, u8, 1>(); +} + +fn len_2() { + type Array = [u8; 2]; + #[repr(C)] struct Struct(u8, u8); + assert::array_like::<Struct, u8, 2>(); +} + +fn len_3() { + type Array = [u8; 3]; + #[repr(C)] struct Struct(u8, u8, u8); + assert::array_like::<Struct, u8, 3>(); +} diff --git a/src/test/ui/transmutability/arrays/should_have_correct_length.rs b/src/test/ui/transmutability/arrays/should_have_correct_length.rs new file mode 100644 index 000000000..bfe6d830a --- /dev/null +++ b/src/test/ui/transmutability/arrays/should_have_correct_length.rs @@ -0,0 +1,44 @@ +// check-pass +//! An array must have the correct length. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +fn should_have_len_0() { + type Array = [u8; 0]; + #[repr(C)] struct Struct(); + assert::is_maybe_transmutable::<Array, Struct>(); + assert::is_maybe_transmutable::<Struct, Array>(); +} + +fn should_have_len_1() { + type Array = [u8; 1]; + #[repr(C)] struct Struct(u8); + assert::is_maybe_transmutable::<Array, Struct>(); + assert::is_maybe_transmutable::<Struct, Array>(); +} + +fn should_have_len_2() { + type Array = [u8; 2]; + #[repr(C)] struct Struct(u8, u8); + assert::is_maybe_transmutable::<Array, Struct>(); + assert::is_maybe_transmutable::<Struct, Array>(); +} + +fn should_have_len_3() { + type Array = [u8; 3]; + #[repr(C)] struct Struct(u8, u8, u8); + assert::is_maybe_transmutable::<Array, Struct>(); + assert::is_maybe_transmutable::<Struct, Array>(); +} diff --git a/src/test/ui/transmutability/arrays/should_inherit_alignment.rs b/src/test/ui/transmutability/arrays/should_inherit_alignment.rs new file mode 100644 index 000000000..fcb1765ea --- /dev/null +++ b/src/test/ui/transmutability/arrays/should_inherit_alignment.rs @@ -0,0 +1,55 @@ +// check-pass +//! An array must inherit the alignment of its inner type. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +#[derive(Clone, Copy)] #[repr(u8)] enum Ox00 { V = 0x00 } +#[derive(Clone, Copy)] #[repr(u8)] enum Ox01 { V = 0x01 } +#[derive(Clone, Copy)] #[repr(u8)] enum OxFF { V = 0xFF } + +#[repr(C)] +union Uninit { + a: (), + b: OxFF, +} + +#[repr(C, align(2))] struct align_2(Ox00); + +fn len_0() { + #[repr(C)] struct ImplicitlyPadded([align_2; 0], Ox01); + #[repr(C)] struct ExplicitlyPadded(Ox01, Uninit); + + #[repr(C)] struct Struct(); + assert::is_maybe_transmutable::<ImplicitlyPadded, ExplicitlyPadded>(); + assert::is_maybe_transmutable::<ExplicitlyPadded, ImplicitlyPadded>(); +} + +fn len_1() { + #[repr(C)] struct ImplicitlyPadded([align_2; 1], Ox01); + #[repr(C)] struct ExplicitlyPadded(Ox00, Uninit, Ox01, Uninit); + + #[repr(C)] struct Struct(); + assert::is_maybe_transmutable::<ImplicitlyPadded, ExplicitlyPadded>(); + assert::is_maybe_transmutable::<ExplicitlyPadded, ImplicitlyPadded>(); +} + +fn len_2() { + #[repr(C)] struct ImplicitlyPadded([align_2; 2], Ox01); + #[repr(C)] struct ExplicitlyPadded(Ox00, Uninit, Ox00, Uninit, Ox01, Uninit); + + #[repr(C)] struct Struct(); + assert::is_maybe_transmutable::<ImplicitlyPadded, ExplicitlyPadded>(); + assert::is_maybe_transmutable::<ExplicitlyPadded, ImplicitlyPadded>(); +} diff --git a/src/test/ui/transmutability/arrays/should_require_well_defined_layout.rs b/src/test/ui/transmutability/arrays/should_require_well_defined_layout.rs new file mode 100644 index 000000000..8e69527c1 --- /dev/null +++ b/src/test/ui/transmutability/arrays/should_require_well_defined_layout.rs @@ -0,0 +1,61 @@ +//! An array must have a well-defined layout to participate in a transmutation. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +fn should_reject_repr_rust() +{ + fn unit() { + type repr_rust = [String; 0]; + assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted + } + + fn singleton() { + type repr_rust = [String; 1]; + assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted + } + + fn duplex() { + type repr_rust = [String; 2]; + 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_C() +{ + fn unit() { + #[repr(C)] struct repr_c(u8, u16, u8); + type array = [repr_c; 0]; + assert::is_maybe_transmutable::<array, ()>(); + assert::is_maybe_transmutable::<i128, array>(); + } + + fn singleton() { + #[repr(C)] struct repr_c(u8, u16, u8); + type array = [repr_c; 1]; + assert::is_maybe_transmutable::<array, repr_c>(); + assert::is_maybe_transmutable::<repr_c, array>(); + } + + fn duplex() { + #[repr(C)] struct repr_c(u8, u16, u8); + #[repr(C)] struct duplex(repr_c, repr_c); + type array = [repr_c; 2]; + assert::is_maybe_transmutable::<array, duplex>(); + assert::is_maybe_transmutable::<duplex, array>(); + } +} diff --git a/src/test/ui/transmutability/arrays/should_require_well_defined_layout.stderr b/src/test/ui/transmutability/arrays/should_require_well_defined_layout.stderr new file mode 100644 index 000000000..eae0c947d --- /dev/null +++ b/src/test/ui/transmutability/arrays/should_require_well_defined_layout.stderr @@ -0,0 +1,99 @@ +error[E0277]: `[String; 0]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:21:52 + | +LL | assert::is_maybe_transmutable::<repr_rust, ()>(); + | ^^ `[String; 0]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<[String; 0], assert::Context, true, true, true, true>` is not implemented for `()` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `u128` cannot be safely transmuted into `[String; 0]` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:22:47 + | +LL | assert::is_maybe_transmutable::<u128, repr_rust>(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `[String; 0]` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `[String; 0]` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `[String; 1]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:27:52 + | +LL | assert::is_maybe_transmutable::<repr_rust, ()>(); + | ^^ `[String; 1]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<[String; 1], assert::Context, true, true, true, true>` is not implemented for `()` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `u128` cannot be safely transmuted into `[String; 1]` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:28:47 + | +LL | assert::is_maybe_transmutable::<u128, repr_rust>(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `[String; 1]` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `[String; 1]` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `[String; 2]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:33:52 + | +LL | assert::is_maybe_transmutable::<repr_rust, ()>(); + | ^^ `[String; 2]` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<[String; 2], assert::Context, true, true, true, true>` is not implemented for `()` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `u128` cannot be safely transmuted into `[String; 2]` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:34:47 + | +LL | assert::is_maybe_transmutable::<u128, repr_rust>(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `[String; 2]` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `[String; 2]` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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/src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs b/src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs new file mode 100644 index 000000000..18e02b0d2 --- /dev/null +++ b/src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs @@ -0,0 +1,149 @@ +//! An enum with a primitive repr should have exactly the size of that primitive. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +#[repr(C)] +struct Zst; + +#[derive(Clone, Copy)] +#[repr(i8)] enum V0i8 { V } +#[repr(u8)] enum V0u8 { V } +#[repr(i16)] enum V0i16 { V } +#[repr(u16)] enum V0u16 { V } +#[repr(i32)] enum V0i32 { V } +#[repr(u32)] enum V0u32 { V } +#[repr(i64)] enum V0i64 { V } +#[repr(u64)] enum V0u64 { V } +#[repr(isize)] enum V0isize { V } +#[repr(usize)] enum V0usize { V } + +fn n8() { + struct Context; + + type Smaller = Zst; + type Analog = u8; + type Larger = u16; + + fn i_should_have_correct_length() { + type Current = V0i8; + + assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::<Current, Analog, Context>(); + assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted + } + + fn u_should_have_correct_length() { + type Current = V0u8; + + assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::<Current, Analog, Context>(); + assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted + } +} + +fn n16() { + struct Context; + + type Smaller = u8; + type Analog = u16; + type Larger = u32; + + fn i_should_have_correct_length() { + type Current = V0i16; + + assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::<Current, Analog, Context>(); + assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted + } + + fn u_should_have_correct_length() { + type Current = V0u16; + + assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::<Current, Analog, Context>(); + assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted + } +} + +fn n32() { + struct Context; + + type Smaller = u16; + type Analog = u32; + type Larger = u64; + + fn i_should_have_correct_length() { + type Current = V0i32; + + assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::<Current, Analog, Context>(); + assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted + } + + fn u_should_have_correct_length() { + type Current = V0u32; + + assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::<Current, Analog, Context>(); + assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted + } +} + +fn n64() { + struct Context; + + type Smaller = u32; + type Analog = u64; + type Larger = u128; + + fn i_should_have_correct_length() { + type Current = V0i64; + + assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::<Current, Analog, Context>(); + assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted + } + + fn u_should_have_correct_length() { + type Current = V0u64; + + assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::<Current, Analog, Context>(); + assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted + } +} + +fn nsize() { + struct Context; + + type Smaller = u8; + type Analog = usize; + type Larger = [usize; 2]; + + fn i_should_have_correct_length() { + type Current = V0isize; + + assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::<Current, Analog, Context>(); + assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted + } + + fn u_should_have_correct_length() { + type Current = V0usize; + + assert::is_transmutable::<Smaller, Current, Context>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::<Current, Analog, Context>(); + assert::is_transmutable::<Current, Larger, Context>(); //~ ERROR cannot be safely transmuted + } +} diff --git a/src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr b/src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr new file mode 100644 index 000000000..fa2e3b89b --- /dev/null +++ b/src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr @@ -0,0 +1,323 @@ +error[E0277]: `Zst` cannot be safely transmuted into `V0i8` in the defining scope of `n8::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:41:44 + | +LL | assert::is_transmutable::<Smaller, Current, Context>(); + | ^^^^^^^ `Zst` cannot be safely transmuted into `V0i8` in the defining scope of `n8::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<Zst, n8::Context, true, true, true, true>` is not implemented for `V0i8` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `V0i8` cannot be safely transmuted into `u16` in the defining scope of `n8::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:43:44 + | +LL | assert::is_transmutable::<Current, Larger, Context>(); + | ^^^^^^ `V0i8` cannot be safely transmuted into `u16` in the defining scope of `n8::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<V0i8, n8::Context, true, true, true, true>` is not implemented for `u16` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `Zst` cannot be safely transmuted into `V0u8` in the defining scope of `n8::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:49:44 + | +LL | assert::is_transmutable::<Smaller, Current, Context>(); + | ^^^^^^^ `Zst` cannot be safely transmuted into `V0u8` in the defining scope of `n8::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<Zst, n8::Context, true, true, true, true>` is not implemented for `V0u8` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `V0u8` cannot be safely transmuted into `u16` in the defining scope of `n8::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:51:44 + | +LL | assert::is_transmutable::<Current, Larger, Context>(); + | ^^^^^^ `V0u8` cannot be safely transmuted into `u16` in the defining scope of `n8::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<V0u8, n8::Context, true, true, true, true>` is not implemented for `u16` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `V0i16` in the defining scope of `n16::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:65:44 + | +LL | assert::is_transmutable::<Smaller, Current, Context>(); + | ^^^^^^^ `u8` cannot be safely transmuted into `V0i16` in the defining scope of `n16::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u8, n16::Context, true, true, true, true>` is not implemented for `V0i16` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `V0i16` cannot be safely transmuted into `u32` in the defining scope of `n16::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:67:44 + | +LL | assert::is_transmutable::<Current, Larger, Context>(); + | ^^^^^^ `V0i16` cannot be safely transmuted into `u32` in the defining scope of `n16::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<V0i16, n16::Context, true, true, true, true>` is not implemented for `u32` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `V0u16` in the defining scope of `n16::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:73:44 + | +LL | assert::is_transmutable::<Smaller, Current, Context>(); + | ^^^^^^^ `u8` cannot be safely transmuted into `V0u16` in the defining scope of `n16::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u8, n16::Context, true, true, true, true>` is not implemented for `V0u16` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `V0u16` cannot be safely transmuted into `u32` in the defining scope of `n16::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:75:44 + | +LL | assert::is_transmutable::<Current, Larger, Context>(); + | ^^^^^^ `V0u16` cannot be safely transmuted into `u32` in the defining scope of `n16::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<V0u16, n16::Context, true, true, true, true>` is not implemented for `u32` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `V0i32` in the defining scope of `n32::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:89:44 + | +LL | assert::is_transmutable::<Smaller, Current, Context>(); + | ^^^^^^^ `u16` cannot be safely transmuted into `V0i32` in the defining scope of `n32::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u16, n32::Context, true, true, true, true>` is not implemented for `V0i32` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `V0i32` cannot be safely transmuted into `u64` in the defining scope of `n32::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:91:44 + | +LL | assert::is_transmutable::<Current, Larger, Context>(); + | ^^^^^^ `V0i32` cannot be safely transmuted into `u64` in the defining scope of `n32::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<V0i32, n32::Context, true, true, true, true>` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `V0u32` in the defining scope of `n32::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:97:44 + | +LL | assert::is_transmutable::<Smaller, Current, Context>(); + | ^^^^^^^ `u16` cannot be safely transmuted into `V0u32` in the defining scope of `n32::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u16, n32::Context, true, true, true, true>` is not implemented for `V0u32` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `V0u32` cannot be safely transmuted into `u64` in the defining scope of `n32::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:99:44 + | +LL | assert::is_transmutable::<Current, Larger, Context>(); + | ^^^^^^ `V0u32` cannot be safely transmuted into `u64` in the defining scope of `n32::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<V0u32, n32::Context, true, true, true, true>` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u32` cannot be safely transmuted into `V0i64` in the defining scope of `n64::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:113:44 + | +LL | assert::is_transmutable::<Smaller, Current, Context>(); + | ^^^^^^^ `u32` cannot be safely transmuted into `V0i64` in the defining scope of `n64::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u32, n64::Context, true, true, true, true>` is not implemented for `V0i64` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `V0i64` cannot be safely transmuted into `u128` in the defining scope of `n64::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:115:44 + | +LL | assert::is_transmutable::<Current, Larger, Context>(); + | ^^^^^^ `V0i64` cannot be safely transmuted into `u128` in the defining scope of `n64::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<V0i64, n64::Context, true, true, true, true>` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u32` cannot be safely transmuted into `V0u64` in the defining scope of `n64::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:121:44 + | +LL | assert::is_transmutable::<Smaller, Current, Context>(); + | ^^^^^^^ `u32` cannot be safely transmuted into `V0u64` in the defining scope of `n64::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u32, n64::Context, true, true, true, true>` is not implemented for `V0u64` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `V0u64` cannot be safely transmuted into `u128` in the defining scope of `n64::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:123:44 + | +LL | assert::is_transmutable::<Current, Larger, Context>(); + | ^^^^^^ `V0u64` cannot be safely transmuted into `u128` in the defining scope of `n64::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<V0u64, n64::Context, true, true, true, true>` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `V0isize` in the defining scope of `nsize::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:137:44 + | +LL | assert::is_transmutable::<Smaller, Current, Context>(); + | ^^^^^^^ `u8` cannot be safely transmuted into `V0isize` in the defining scope of `nsize::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u8, nsize::Context, true, true, true, true>` is not implemented for `V0isize` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `V0isize` cannot be safely transmuted into `[usize; 2]` in the defining scope of `nsize::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:139:44 + | +LL | assert::is_transmutable::<Current, Larger, Context>(); + | ^^^^^^ `V0isize` cannot be safely transmuted into `[usize; 2]` in the defining scope of `nsize::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<V0isize, nsize::Context, true, true, true, true>` is not implemented for `[usize; 2]` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `V0usize` in the defining scope of `nsize::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:145:44 + | +LL | assert::is_transmutable::<Smaller, Current, Context>(); + | ^^^^^^^ `u8` cannot be safely transmuted into `V0usize` in the defining scope of `nsize::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u8, nsize::Context, true, true, true, true>` is not implemented for `V0usize` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `V0usize` cannot be safely transmuted into `[usize; 2]` in the defining scope of `nsize::Context`. + --> $DIR/primitive_reprs_should_have_correct_length.rs:147:44 + | +LL | assert::is_transmutable::<Current, Larger, Context>(); + | ^^^^^^ `V0usize` cannot be safely transmuted into `[usize; 2]` in the defining scope of `nsize::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<V0usize, nsize::Context, true, true, true, true>` is not implemented for `[usize; 2]` +note: required by a bound in `is_transmutable` + --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to 20 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.rs b/src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.rs new file mode 100644 index 000000000..978a12648 --- /dev/null +++ b/src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.rs @@ -0,0 +1,117 @@ +//! An enum must have a well-defined layout to participate in a transmutation. + +#![crate_type = "lib"] +#![feature(repr128)] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +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 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 + } + + 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 + } +} + +fn should_accept_primitive_reprs() +{ + fn should_accept_repr_i8() { + #[repr(i8)] enum repr_i8 { V } + assert::is_maybe_transmutable::<repr_i8, ()>(); + assert::is_maybe_transmutable::<i8, repr_i8>(); + } + + fn should_accept_repr_u8() { + #[repr(u8)] enum repr_u8 { V } + assert::is_maybe_transmutable::<repr_u8, ()>(); + assert::is_maybe_transmutable::<u8, repr_u8>(); + } + + fn should_accept_repr_i16() { + #[repr(i16)] enum repr_i16 { V } + assert::is_maybe_transmutable::<repr_i16, ()>(); + assert::is_maybe_transmutable::<i16, repr_i16>(); + } + + fn should_accept_repr_u16() { + #[repr(u16)] enum repr_u16 { V } + assert::is_maybe_transmutable::<repr_u16, ()>(); + assert::is_maybe_transmutable::<u16, repr_u16>(); + } + + fn should_accept_repr_i32() { + #[repr(i32)] enum repr_i32 { V } + assert::is_maybe_transmutable::<repr_i32, ()>(); + assert::is_maybe_transmutable::<i32, repr_i32>(); + } + + fn should_accept_repr_u32() { + #[repr(u32)] enum repr_u32 { V } + assert::is_maybe_transmutable::<repr_u32, ()>(); + assert::is_maybe_transmutable::<u32, repr_u32>(); + } + + fn should_accept_repr_i64() { + #[repr(i64)] enum repr_i64 { V } + assert::is_maybe_transmutable::<repr_i64, ()>(); + assert::is_maybe_transmutable::<i64, repr_i64>(); + } + + fn should_accept_repr_u64() { + #[repr(u64)] enum repr_u64 { V } + assert::is_maybe_transmutable::<repr_u64, ()>(); + assert::is_maybe_transmutable::<u64, repr_u64>(); + } + + fn should_accept_repr_i128() { + #[repr(i128)] enum repr_i128 { V } + assert::is_maybe_transmutable::<repr_i128, ()>(); + assert::is_maybe_transmutable::<i128, repr_i128>(); + } + + fn should_accept_repr_u128() { + #[repr(u128)] enum repr_u128 { V } + assert::is_maybe_transmutable::<repr_u128, ()>(); + assert::is_maybe_transmutable::<u128, repr_u128>(); + } + + fn should_accept_repr_isize() { + #[repr(isize)] enum repr_isize { V } + assert::is_maybe_transmutable::<repr_isize, ()>(); + assert::is_maybe_transmutable::<isize, repr_isize>(); + } + + fn should_accept_repr_usize() { + #[repr(usize)] enum repr_usize { V } + assert::is_maybe_transmutable::<repr_usize, ()>(); + assert::is_maybe_transmutable::<usize, repr_usize>(); + } +} + +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/src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr b/src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr new file mode 100644 index 000000000..3273e87c8 --- /dev/null +++ b/src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr @@ -0,0 +1,99 @@ +error[E0277]: `void::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:21:52 + | +LL | assert::is_maybe_transmutable::<repr_rust, ()>(); + | ^^ `void::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<void::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:14:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `u128` cannot be safely transmuted into `void::repr_rust` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:22:47 + | +LL | assert::is_maybe_transmutable::<u128, repr_rust>(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `void::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `void::repr_rust` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:14:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `singleton::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:27:52 + | +LL | assert::is_maybe_transmutable::<repr_rust, ()>(); + | ^^ `singleton::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<singleton::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:14:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `u128` cannot be safely transmuted into `singleton::repr_rust` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:28:47 + | +LL | assert::is_maybe_transmutable::<u128, repr_rust>(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `singleton::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `singleton::repr_rust` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:14:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `duplex::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:33:52 + | +LL | assert::is_maybe_transmutable::<repr_rust, ()>(); + | ^^ `duplex::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<duplex::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:14:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `u128` cannot be safely transmuted into `duplex::repr_rust` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:34:47 + | +LL | assert::is_maybe_transmutable::<u128, repr_rust>(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `duplex::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `duplex::repr_rust` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_require_well_defined_layout.rs:14:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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/src/test/ui/transmutability/enums/should_order_correctly.rs b/src/test/ui/transmutability/enums/should_order_correctly.rs new file mode 100644 index 000000000..6558d2658 --- /dev/null +++ b/src/test/ui/transmutability/enums/should_order_correctly.rs @@ -0,0 +1,32 @@ +// check-pass +//! The payloads of an enum variant should be ordered after its tag. + +#![crate_type = "lib"] +#![feature(arbitrary_enum_discriminant)] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +#[repr(u8)] enum V0 { V = 0 } +#[repr(u8)] enum V1 { V = 1 } +#[repr(u8)] enum V2 { V = 2 } + +#[repr(u8)] enum E01 { V0(V1) = 0u8 } +#[repr(u8)] enum E012 { V0(V1, V2) = 0u8 } + +fn should_order_tag_and_fields_correctly() { + // An implementation that (incorrectly) arranges E01 as [0x01, 0x00] will, + // in principle, reject this transmutation. + assert::is_transmutable::<E01, V0>(); + // Again, but with one more field. + assert::is_transmutable::<E012, E01>(); +} diff --git a/src/test/ui/transmutability/enums/should_pad_variants.rs b/src/test/ui/transmutability/enums/should_pad_variants.rs new file mode 100644 index 000000000..466b6c8a1 --- /dev/null +++ b/src/test/ui/transmutability/enums/should_pad_variants.rs @@ -0,0 +1,40 @@ +//! The variants of an enum must be padded with uninit bytes such that they have +//! the same length (in bytes). + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +#[derive(Clone, Copy)] +#[repr(C)] struct Zst; + +#[derive(Clone, Copy)] +#[repr(u8)] enum V0 { V = 0 } + +#[derive(Clone, Copy)] +#[repr(u8)] enum V2 { V = 2 } + +#[repr(C, u8)] +enum Lopsided { + Smol(Zst), + Lorg(V0), +} + +#[repr(C)] struct Src(V0, Zst, V2); +#[repr(C)] struct Dst(Lopsided, V2); + +fn should_pad_variants() { + struct Context; + // If the implementation (incorrectly) fails to pad `Lopsided::Smol` with + // an uninitialized byte, this transmutation might be (wrongly) accepted: + assert::is_transmutable::<Src, Dst, Context>(); //~ ERROR cannot be safely transmuted +} diff --git a/src/test/ui/transmutability/enums/should_pad_variants.stderr b/src/test/ui/transmutability/enums/should_pad_variants.stderr new file mode 100644 index 000000000..429f7211d --- /dev/null +++ b/src/test/ui/transmutability/enums/should_pad_variants.stderr @@ -0,0 +1,19 @@ +error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_pad_variants::Context`. + --> $DIR/should_pad_variants.rs:39:36 + | +LL | assert::is_transmutable::<Src, Dst, Context>(); + | ^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_pad_variants::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<Src, should_pad_variants::Context, true, true, true, true>` is not implemented for `Dst` +note: required by a bound in `is_transmutable` + --> $DIR/should_pad_variants.rs:13:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/transmutability/enums/should_respect_endianness.rs b/src/test/ui/transmutability/enums/should_respect_endianness.rs new file mode 100644 index 000000000..67a3c4e94 --- /dev/null +++ b/src/test/ui/transmutability/enums/should_respect_endianness.rs @@ -0,0 +1,33 @@ +//! The target endianness should be a consideration in computing the layout of +//! an enum with a multi-byte tag. + +#![crate_type = "lib"] +#![feature(arbitrary_enum_discriminant)] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +#[repr(u16)] enum Src { V = 0xCAFE } + +#[repr(u8)] enum OxCA { V = 0xCA } +#[repr(u8)] enum OxFE { V = 0xFE } + +#[cfg(target_endian = "big")] #[repr(C)] struct Expected(OxCA, OxFE); +#[cfg(target_endian = "big")] #[repr(C)] struct Unexpected(OxFE, OxCA); + +#[cfg(target_endian = "little")] #[repr(C)] struct Expected(OxFE, OxCA); +#[cfg(target_endian = "little")] #[repr(C)] struct Unexpected(OxCA, OxFE); + +fn should_respect_endianness() { + assert::is_transmutable::<Src, Expected>(); + assert::is_transmutable::<Src, Unexpected>(); //~ ERROR cannot be safely transmuted +} diff --git a/src/test/ui/transmutability/enums/should_respect_endianness.stderr b/src/test/ui/transmutability/enums/should_respect_endianness.stderr new file mode 100644 index 000000000..78023cb37 --- /dev/null +++ b/src/test/ui/transmutability/enums/should_respect_endianness.stderr @@ -0,0 +1,19 @@ +error[E0277]: `Src` cannot be safely transmuted into `Unexpected` in the defining scope of `assert::Context`. + --> $DIR/should_respect_endianness.rs:32:36 + | +LL | assert::is_transmutable::<Src, Unexpected>(); + | ^^^^^^^^^^ `Src` cannot be safely transmuted into `Unexpected` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<Src, assert::Context, true, true, true, true>` is not implemented for `Unexpected` +note: required by a bound in `is_transmutable` + --> $DIR/should_respect_endianness.rs:15:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/transmutability/malformed-program-gracefulness/feature-missing.rs b/src/test/ui/transmutability/malformed-program-gracefulness/feature-missing.rs new file mode 100644 index 000000000..30c381745 --- /dev/null +++ b/src/test/ui/transmutability/malformed-program-gracefulness/feature-missing.rs @@ -0,0 +1,9 @@ +// The trait must not be available if its feature flag is absent. + +#![crate_type = "lib"] + +use std::mem::BikeshedIntrinsicFrom; +//~^ ERROR use of unstable library feature 'transmutability' [E0658] + +use std::mem::Assume; +//~^ ERROR use of unstable library feature 'transmutability' [E0658] diff --git a/src/test/ui/transmutability/malformed-program-gracefulness/feature-missing.stderr b/src/test/ui/transmutability/malformed-program-gracefulness/feature-missing.stderr new file mode 100644 index 000000000..ba8093f86 --- /dev/null +++ b/src/test/ui/transmutability/malformed-program-gracefulness/feature-missing.stderr @@ -0,0 +1,21 @@ +error[E0658]: use of unstable library feature 'transmutability' + --> $DIR/feature-missing.rs:5:5 + | +LL | use std::mem::BikeshedIntrinsicFrom; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #99571 <https://github.com/rust-lang/rust/issues/99571> for more information + = help: add `#![feature(transmutability)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'transmutability' + --> $DIR/feature-missing.rs:8:5 + | +LL | use std::mem::Assume; + | ^^^^^^^^^^^^^^^^ + | + = note: see issue #99571 <https://github.com/rust-lang/rust/issues/99571> for more information + = help: add `#![feature(transmutability)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs new file mode 100644 index 000000000..e13462d39 --- /dev/null +++ b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs @@ -0,0 +1,21 @@ +// An unknown destination type should be gracefully handled. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + {} +} + +fn should_gracefully_handle_unknown_dst() { + struct Context; + struct Src; + assert::is_transmutable::<Src, Dst, Context>(); //~ cannot find type +} diff --git a/src/test/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr new file mode 100644 index 000000000..85087282d --- /dev/null +++ b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr @@ -0,0 +1,12 @@ +error[E0412]: cannot find type `Dst` in this scope + --> $DIR/unknown_dst.rs:20:36 + | +LL | fn should_gracefully_handle_unknown_dst() { + | - help: you might be missing a type parameter: `<Dst>` +... +LL | assert::is_transmutable::<Src, Dst, Context>(); + | ^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src.rs b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src.rs new file mode 100644 index 000000000..dc51e2a8f --- /dev/null +++ b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src.rs @@ -0,0 +1,21 @@ +// An unknown source type should be gracefully handled. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + {} +} + +fn should_gracefully_handle_unknown_src() { + struct Context; + #[repr(C)] struct Dst; + assert::is_transmutable::<Src, Dst, Context>(); //~ cannot find type +} diff --git a/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr new file mode 100644 index 000000000..9bedbe87c --- /dev/null +++ b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr @@ -0,0 +1,12 @@ +error[E0412]: cannot find type `Src` in this scope + --> $DIR/unknown_src.rs:20:31 + | +LL | fn should_gracefully_handle_unknown_src() { + | - help: you might be missing a type parameter: `<Src>` +... +LL | assert::is_transmutable::<Src, Dst, Context>(); + | ^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs new file mode 100644 index 000000000..86fc8bd6b --- /dev/null +++ b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs @@ -0,0 +1,22 @@ +// An unknown destination type should be gracefully handled. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + {} +} + +fn should_gracefully_handle_unknown_dst_field() { + struct Context; + #[repr(C)] struct Src; + #[repr(C)] struct Dst(Missing); //~ cannot find type + assert::is_transmutable::<Src, Dst, Context>(); +} diff --git a/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr new file mode 100644 index 000000000..475e6f429 --- /dev/null +++ b/src/test/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Missing` in this scope + --> $DIR/unknown_src_field.rs:20:27 + | +LL | #[repr(C)] struct Dst(Missing); + | ^^^^^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0412`. diff --git a/src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs b/src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs new file mode 100644 index 000000000..bd36748e7 --- /dev/null +++ b/src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs @@ -0,0 +1,40 @@ +//! The implementation must behave well if const values of wrong types are +//! provided. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable< + Src, + Dst, + Context, + const ASSUME_ALIGNMENT: bool, + const ASSUME_LIFETIMES: bool, + const ASSUME_VALIDITY: bool, + const ASSUME_VISIBILITY: bool, + >() + where + Dst: BikeshedIntrinsicFrom< + Src, + Context, + ASSUME_ALIGNMENT, + ASSUME_LIFETIMES, + ASSUME_VALIDITY, + ASSUME_VISIBILITY, + >, + {} +} + +fn test() { + struct Context; + #[repr(C)] struct Src; + #[repr(C)] struct Dst; + assert::is_transmutable::<Src, Dst, Context, {0u8}, false, false, false>(); //~ ERROR mismatched types + assert::is_transmutable::<Src, Dst, Context, false, {0u8}, false, false>(); //~ ERROR mismatched types + assert::is_transmutable::<Src, Dst, Context, false, false, {0u8}, false>(); //~ ERROR mismatched types + assert::is_transmutable::<Src, Dst, Context, false, false, false, {0u8}>(); //~ ERROR mismatched types +} diff --git a/src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.stderr b/src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.stderr new file mode 100644 index 000000000..e1464e023 --- /dev/null +++ b/src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.stderr @@ -0,0 +1,27 @@ +error[E0308]: mismatched types + --> $DIR/wrong-type-assume.rs:36:51 + | +LL | assert::is_transmutable::<Src, Dst, Context, {0u8}, false, false, false>(); + | ^^^ expected `bool`, found `u8` + +error[E0308]: mismatched types + --> $DIR/wrong-type-assume.rs:37:58 + | +LL | assert::is_transmutable::<Src, Dst, Context, false, {0u8}, false, false>(); + | ^^^ expected `bool`, found `u8` + +error[E0308]: mismatched types + --> $DIR/wrong-type-assume.rs:38:65 + | +LL | assert::is_transmutable::<Src, Dst, Context, false, false, {0u8}, false>(); + | ^^^ expected `bool`, found `u8` + +error[E0308]: mismatched types + --> $DIR/wrong-type-assume.rs:39:72 + | +LL | assert::is_transmutable::<Src, Dst, Context, false, false, false, {0u8}>(); + | ^^^ expected `bool`, found `u8` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/transmutability/primitives/bool.rs b/src/test/ui/transmutability/primitives/bool.rs new file mode 100644 index 000000000..4f79bc253 --- /dev/null +++ b/src/test/ui/transmutability/primitives/bool.rs @@ -0,0 +1,25 @@ +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] +#![allow(incomplete_features)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true> + {} + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, true, true> + {} +} + +fn contrast_with_u8() { + assert::is_transmutable::<u8, bool>(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::<u8, bool>(); + assert::is_transmutable::<bool, u8>(); +} diff --git a/src/test/ui/transmutability/primitives/bool.stderr b/src/test/ui/transmutability/primitives/bool.stderr new file mode 100644 index 000000000..dc740251c --- /dev/null +++ b/src/test/ui/transmutability/primitives/bool.stderr @@ -0,0 +1,19 @@ +error[E0277]: `u8` cannot be safely transmuted into `bool` in the defining scope of `assert::Context`. + --> $DIR/bool.rs:22:35 + | +LL | assert::is_transmutable::<u8, bool>(); + | ^^^^ `u8` cannot be safely transmuted into `bool` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, true>` is not implemented for `bool` +note: required by a bound in `is_transmutable` + --> $DIR/bool.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/transmutability/primitives/numbers.rs b/src/test/ui/transmutability/primitives/numbers.rs new file mode 100644 index 000000000..a5f79065d --- /dev/null +++ b/src/test/ui/transmutability/primitives/numbers.rs @@ -0,0 +1,128 @@ +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] +#![allow(incomplete_features)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + struct Context; + + pub fn is_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + {} +} + +fn should_accept_identity() { + assert::is_transmutable::< i8, i8>(); + assert::is_transmutable::< u8, u8>(); + assert::is_transmutable::< i16, i16>(); + assert::is_transmutable::< u16, u16>(); + assert::is_transmutable::< i32, i32>(); + assert::is_transmutable::< f32, f32>(); + assert::is_transmutable::< u32, u32>(); + assert::is_transmutable::< i64, i64>(); + assert::is_transmutable::< f64, f64>(); + assert::is_transmutable::< u64, u64>(); + assert::is_transmutable::< i128, i128>(); + assert::is_transmutable::< u128, u128>(); + assert::is_transmutable::<isize, isize>(); + assert::is_transmutable::<usize, usize>(); +} + +fn should_be_bitransmutable() { + assert::is_transmutable::< i8, u8>(); + assert::is_transmutable::< u8, i8>(); + + assert::is_transmutable::< i16, u16>(); + assert::is_transmutable::< u16, i16>(); + + assert::is_transmutable::< i32, f32>(); + assert::is_transmutable::< i32, u32>(); + assert::is_transmutable::< f32, i32>(); + assert::is_transmutable::< f32, u32>(); + assert::is_transmutable::< u32, i32>(); + assert::is_transmutable::< u32, f32>(); + + assert::is_transmutable::< u64, i64>(); + assert::is_transmutable::< u64, f64>(); + assert::is_transmutable::< i64, u64>(); + assert::is_transmutable::< i64, f64>(); + assert::is_transmutable::< f64, u64>(); + assert::is_transmutable::< f64, i64>(); + + assert::is_transmutable::< u128, i128>(); + assert::is_transmutable::< i128, u128>(); + + assert::is_transmutable::<isize, usize>(); + assert::is_transmutable::<usize, isize>(); +} + +fn should_reject_extension() { + assert::is_transmutable::< i8, i16>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, u16>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, i32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, f32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, u32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, u64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, i64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, f64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i8, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< u8, i16>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, u16>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, i32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, f32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, u32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, u64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, i64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, f64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u8, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< i16, i32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i16, f32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i16, u32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i16, u64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i16, i64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i16, f64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i16, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i16, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< u16, i32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u16, f32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u16, u32>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u16, u64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u16, i64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u16, f64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u16, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u16, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< i32, u64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i32, i64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i32, f64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i32, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i32, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< f32, u64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< f32, i64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< f32, f64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< f32, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< f32, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< u32, u64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u32, i64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u32, f64>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u32, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u32, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< u64, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< u64, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< i64, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< i64, i128>(); //~ ERROR cannot be safely transmuted + + assert::is_transmutable::< f64, u128>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::< f64, i128>(); //~ ERROR cannot be safely transmuted +} diff --git a/src/test/ui/transmutability/primitives/numbers.stderr b/src/test/ui/transmutability/primitives/numbers.stderr new file mode 100644 index 000000000..9b802a444 --- /dev/null +++ b/src/test/ui/transmutability/primitives/numbers.stderr @@ -0,0 +1,915 @@ +error[E0277]: `i8` cannot be safely transmuted into `i16` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:62:40 + | +LL | assert::is_transmutable::< i8, i16>(); + | ^^^ `i8` cannot be safely transmuted into `i16` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `i16` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `u16` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:63:40 + | +LL | assert::is_transmutable::< i8, u16>(); + | ^^^ `i8` cannot be safely transmuted into `u16` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `u16` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:64:40 + | +LL | assert::is_transmutable::< i8, i32>(); + | ^^^ `i8` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `i32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:65:40 + | +LL | assert::is_transmutable::< i8, f32>(); + | ^^^ `i8` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `f32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:66:40 + | +LL | assert::is_transmutable::< i8, u32>(); + | ^^^ `i8` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `u32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:67:40 + | +LL | assert::is_transmutable::< i8, u64>(); + | ^^^ `i8` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:68:40 + | +LL | assert::is_transmutable::< i8, i64>(); + | ^^^ `i8` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `i64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:69:40 + | +LL | assert::is_transmutable::< i8, f64>(); + | ^^^ `i8` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `f64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:70:39 + | +LL | assert::is_transmutable::< i8, u128>(); + | ^^^^ `i8` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i8` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:71:39 + | +LL | assert::is_transmutable::< i8, i128>(); + | ^^^^ `i8` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i8, assert::Context, false, false, false, false>` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `i16` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:73:40 + | +LL | assert::is_transmutable::< u8, i16>(); + | ^^^ `u8` cannot be safely transmuted into `i16` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `i16` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `u16` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:74:40 + | +LL | assert::is_transmutable::< u8, u16>(); + | ^^^ `u8` cannot be safely transmuted into `u16` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `u16` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:75:40 + | +LL | assert::is_transmutable::< u8, i32>(); + | ^^^ `u8` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `i32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:76:40 + | +LL | assert::is_transmutable::< u8, f32>(); + | ^^^ `u8` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `f32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:77:40 + | +LL | assert::is_transmutable::< u8, u32>(); + | ^^^ `u8` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `u32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:78:40 + | +LL | assert::is_transmutable::< u8, u64>(); + | ^^^ `u8` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:79:40 + | +LL | assert::is_transmutable::< u8, i64>(); + | ^^^ `u8` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `i64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:80:40 + | +LL | assert::is_transmutable::< u8, f64>(); + | ^^^ `u8` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `f64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:81:39 + | +LL | assert::is_transmutable::< u8, u128>(); + | ^^^^ `u8` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u8` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:82:39 + | +LL | assert::is_transmutable::< u8, i128>(); + | ^^^^ `u8` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u8, assert::Context, false, false, false, false>` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:84:40 + | +LL | assert::is_transmutable::< i16, i32>(); + | ^^^ `i16` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `i32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:85:40 + | +LL | assert::is_transmutable::< i16, f32>(); + | ^^^ `i16` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `f32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:86:40 + | +LL | assert::is_transmutable::< i16, u32>(); + | ^^^ `i16` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `u32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:87:40 + | +LL | assert::is_transmutable::< i16, u64>(); + | ^^^ `i16` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:88:40 + | +LL | assert::is_transmutable::< i16, i64>(); + | ^^^ `i16` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `i64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:89:40 + | +LL | assert::is_transmutable::< i16, f64>(); + | ^^^ `i16` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `f64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:90:39 + | +LL | assert::is_transmutable::< i16, u128>(); + | ^^^^ `i16` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i16` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:91:39 + | +LL | assert::is_transmutable::< i16, i128>(); + | ^^^^ `i16` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i16, assert::Context, false, false, false, false>` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:93:40 + | +LL | assert::is_transmutable::< u16, i32>(); + | ^^^ `u16` cannot be safely transmuted into `i32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `i32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:94:40 + | +LL | assert::is_transmutable::< u16, f32>(); + | ^^^ `u16` cannot be safely transmuted into `f32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `f32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:95:40 + | +LL | assert::is_transmutable::< u16, u32>(); + | ^^^ `u16` cannot be safely transmuted into `u32` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `u32` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:96:40 + | +LL | assert::is_transmutable::< u16, u64>(); + | ^^^ `u16` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:97:40 + | +LL | assert::is_transmutable::< u16, i64>(); + | ^^^ `u16` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `i64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:98:40 + | +LL | assert::is_transmutable::< u16, f64>(); + | ^^^ `u16` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `f64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:99:39 + | +LL | assert::is_transmutable::< u16, u128>(); + | ^^^^ `u16` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u16` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:100:39 + | +LL | assert::is_transmutable::< u16, i128>(); + | ^^^^ `u16` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u16, assert::Context, false, false, false, false>` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:102:40 + | +LL | assert::is_transmutable::< i32, u64>(); + | ^^^ `i32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i32, assert::Context, false, false, false, false>` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:103:40 + | +LL | assert::is_transmutable::< i32, i64>(); + | ^^^ `i32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i32, assert::Context, false, false, false, false>` is not implemented for `i64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:104:40 + | +LL | assert::is_transmutable::< i32, f64>(); + | ^^^ `i32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i32, assert::Context, false, false, false, false>` is not implemented for `f64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:105:39 + | +LL | assert::is_transmutable::< i32, u128>(); + | ^^^^ `i32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i32, assert::Context, false, false, false, false>` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:106:39 + | +LL | assert::is_transmutable::< i32, i128>(); + | ^^^^ `i32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i32, assert::Context, false, false, false, false>` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `f32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:108:40 + | +LL | assert::is_transmutable::< f32, u64>(); + | ^^^ `f32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<f32, assert::Context, false, false, false, false>` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `f32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:109:40 + | +LL | assert::is_transmutable::< f32, i64>(); + | ^^^ `f32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<f32, assert::Context, false, false, false, false>` is not implemented for `i64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `f32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:110:40 + | +LL | assert::is_transmutable::< f32, f64>(); + | ^^^ `f32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<f32, assert::Context, false, false, false, false>` is not implemented for `f64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `f32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:111:39 + | +LL | assert::is_transmutable::< f32, u128>(); + | ^^^^ `f32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<f32, assert::Context, false, false, false, false>` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `f32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:112:39 + | +LL | assert::is_transmutable::< f32, i128>(); + | ^^^^ `f32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<f32, assert::Context, false, false, false, false>` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:114:40 + | +LL | assert::is_transmutable::< u32, u64>(); + | ^^^ `u32` cannot be safely transmuted into `u64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u32, assert::Context, false, false, false, false>` is not implemented for `u64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:115:40 + | +LL | assert::is_transmutable::< u32, i64>(); + | ^^^ `u32` cannot be safely transmuted into `i64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u32, assert::Context, false, false, false, false>` is not implemented for `i64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:116:40 + | +LL | assert::is_transmutable::< u32, f64>(); + | ^^^ `u32` cannot be safely transmuted into `f64` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u32, assert::Context, false, false, false, false>` is not implemented for `f64` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:117:39 + | +LL | assert::is_transmutable::< u32, u128>(); + | ^^^^ `u32` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u32, assert::Context, false, false, false, false>` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:118:39 + | +LL | assert::is_transmutable::< u32, i128>(); + | ^^^^ `u32` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u32, assert::Context, false, false, false, false>` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:120:39 + | +LL | assert::is_transmutable::< u64, u128>(); + | ^^^^ `u64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u64, assert::Context, false, false, false, false>` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `u64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:121:39 + | +LL | assert::is_transmutable::< u64, i128>(); + | ^^^^ `u64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u64, assert::Context, false, false, false, false>` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:123:39 + | +LL | assert::is_transmutable::< i64, u128>(); + | ^^^^ `i64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i64, assert::Context, false, false, false, false>` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `i64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:124:39 + | +LL | assert::is_transmutable::< i64, i128>(); + | ^^^^ `i64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<i64, assert::Context, false, false, false, false>` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `f64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:126:39 + | +LL | assert::is_transmutable::< f64, u128>(); + | ^^^^ `f64` cannot be safely transmuted into `u128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<f64, assert::Context, false, false, false, false>` is not implemented for `u128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `f64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + --> $DIR/numbers.rs:127:39 + | +LL | assert::is_transmutable::< f64, i128>(); + | ^^^^ `f64` cannot be safely transmuted into `i128` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<f64, assert::Context, false, false, false, false>` is not implemented for `i128` +note: required by a bound in `is_transmutable` + --> $DIR/numbers.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to 57 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/transmutability/primitives/unit.rs b/src/test/ui/transmutability/primitives/unit.rs new file mode 100644 index 000000000..86d474030 --- /dev/null +++ b/src/test/ui/transmutability/primitives/unit.rs @@ -0,0 +1,24 @@ +//! The unit type, `()`, should be one byte. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +#[repr(C)] +struct Zst; + +fn should_have_correct_size() { + struct Context; + assert::is_transmutable::<(), Zst, Context>(); + assert::is_transmutable::<Zst, (), Context>(); + assert::is_transmutable::<(), u8, Context>(); //~ ERROR cannot be safely transmuted +} diff --git a/src/test/ui/transmutability/primitives/unit.stderr b/src/test/ui/transmutability/primitives/unit.stderr new file mode 100644 index 000000000..cf27c0d17 --- /dev/null +++ b/src/test/ui/transmutability/primitives/unit.stderr @@ -0,0 +1,19 @@ +error[E0277]: `()` cannot be safely transmuted into `u8` in the defining scope of `should_have_correct_size::Context`. + --> $DIR/unit.rs:23:35 + | +LL | assert::is_transmutable::<(), u8, Context>(); + | ^^ `()` cannot be safely transmuted into `u8` in the defining scope of `should_have_correct_size::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<(), should_have_correct_size::Context, true, true, true, true>` is not implemented for `u8` +note: required by a bound in `is_transmutable` + --> $DIR/unit.rs:12:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/transmutability/references.rs b/src/test/ui/transmutability/references.rs new file mode 100644 index 000000000..c6fd4c43e --- /dev/null +++ b/src/test/ui/transmutability/references.rs @@ -0,0 +1,20 @@ +//! Transmutations involving references are not yet supported. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +fn not_yet_implemented() { + #[repr(C)] struct Unit; + assert::is_maybe_transmutable::<&'static Unit, &'static Unit>(); //~ ERROR cannot be safely transmuted +} diff --git a/src/test/ui/transmutability/references.stderr b/src/test/ui/transmutability/references.stderr new file mode 100644 index 000000000..b1359ea58 --- /dev/null +++ b/src/test/ui/transmutability/references.stderr @@ -0,0 +1,19 @@ +error[E0277]: `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context`. + --> $DIR/references.rs:19:37 + | +LL | assert::is_maybe_transmutable::<&'static Unit, &'static Unit>(); + | ^^^^^^^^^^^^^ `&'static Unit` cannot be safely transmuted into `&'static Unit` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<&'static Unit, assert::Context, true, true, true, true>` is not implemented for `&'static Unit` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/references.rs:13:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/transmutability/structs/repr/should_handle_align.rs b/src/test/ui/transmutability/structs/repr/should_handle_align.rs new file mode 100644 index 000000000..71720165a --- /dev/null +++ b/src/test/ui/transmutability/structs/repr/should_handle_align.rs @@ -0,0 +1,36 @@ +// check-pass +//! The presence of an `align(X)` annotation must be accounted for. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +fn should_pad_explicitly_aligned_field() { + #[derive(Clone, Copy)] #[repr(u8)] enum V0u8 { V = 0 } + + #[repr(C)] + pub union Uninit { + a: (), + b: V0u8, + } + + #[repr(C, align(2))] struct align_2(V0u8); + + #[repr(C)] struct ImplicitlyPadded(align_2, V0u8); + #[repr(C)] struct ExplicitlyPadded(V0u8, Uninit, V0u8); + + // An implementation that (incorrectly) does not place a padding byte after + // `align_2` will, incorrectly, reject the following transmutations. + assert::is_maybe_transmutable::<ImplicitlyPadded, ExplicitlyPadded>(); + assert::is_maybe_transmutable::<ExplicitlyPadded, ImplicitlyPadded>(); +} diff --git a/src/test/ui/transmutability/structs/repr/should_handle_packed.rs b/src/test/ui/transmutability/structs/repr/should_handle_packed.rs new file mode 100644 index 000000000..ae8acf504 --- /dev/null +++ b/src/test/ui/transmutability/structs/repr/should_handle_packed.rs @@ -0,0 +1,35 @@ +// check-pass +//! The presence of an `align(X)` annotation must be accounted for. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +fn should_pad_explicitly_packed_field() { + #[derive(Clone, Copy)] #[repr(u8)] enum V0u8 { V = 0 } + #[derive(Clone, Copy)] #[repr(u32)] enum V0u32 { V = 0 } + + #[repr(C)] + pub union Uninit { + a: (), + b: V0u8, + } + + #[repr(C, packed(2))] struct ImplicitlyPadded(V0u8, V0u32); + #[repr(C)] struct ExplicitlyPadded(V0u8, Uninit, V0u8, V0u8, V0u8, V0u8); + + // An implementation that (incorrectly) does not place a padding byte after + // `align_2` will, incorrectly, reject the following transmutations. + assert::is_maybe_transmutable::<ImplicitlyPadded, ExplicitlyPadded>(); + assert::is_maybe_transmutable::<ExplicitlyPadded, ImplicitlyPadded>(); +} diff --git a/src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.rs b/src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.rs new file mode 100644 index 000000000..556be989d --- /dev/null +++ b/src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.rs @@ -0,0 +1,76 @@ +//! A struct must have a well-defined layout to participate in a transmutation. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +fn should_reject_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 + } + + 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 + } + + 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 + } + + 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 + } + + 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 + } + + 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 + } +} + +fn should_accept_repr_C() +{ + fn unit() { + #[repr(C)] struct repr_c; + assert::is_maybe_transmutable::<repr_c, ()>(); + assert::is_maybe_transmutable::<i128, repr_c>(); + } + + fn tuple() { + #[repr(C)] struct repr_c(); + assert::is_maybe_transmutable::<repr_c, ()>(); + assert::is_maybe_transmutable::<i128, repr_c>(); + } + + fn braces() { + #[repr(C)] struct repr_c{} + assert::is_maybe_transmutable::<repr_c, ()>(); + assert::is_maybe_transmutable::<i128, repr_c>(); + } +} diff --git a/src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr b/src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr new file mode 100644 index 000000000..07355f7c2 --- /dev/null +++ b/src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr @@ -0,0 +1,195 @@ +error[E0277]: `should_reject_repr_rust::unit::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:21:52 + | +LL | assert::is_maybe_transmutable::<repr_rust, ()>(); + | ^^ `should_reject_repr_rust::unit::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<should_reject_repr_rust::unit::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::unit::repr_rust` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:22:47 + | +LL | assert::is_maybe_transmutable::<u128, repr_rust>(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `should_reject_repr_rust::unit::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `should_reject_repr_rust::unit::repr_rust` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `should_reject_repr_rust::tuple::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:27:52 + | +LL | assert::is_maybe_transmutable::<repr_rust, ()>(); + | ^^ `should_reject_repr_rust::tuple::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<should_reject_repr_rust::tuple::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::tuple::repr_rust` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:28:47 + | +LL | assert::is_maybe_transmutable::<u128, repr_rust>(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `should_reject_repr_rust::tuple::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `should_reject_repr_rust::tuple::repr_rust` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `should_reject_repr_rust::braces::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:33:52 + | +LL | assert::is_maybe_transmutable::<repr_rust, ()>(); + | ^^ `should_reject_repr_rust::braces::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<should_reject_repr_rust::braces::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::braces::repr_rust` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:34:47 + | +LL | assert::is_maybe_transmutable::<u128, repr_rust>(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `should_reject_repr_rust::braces::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `should_reject_repr_rust::braces::repr_rust` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `aligned::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:39:52 + | +LL | assert::is_maybe_transmutable::<repr_rust, ()>(); + | ^^ `aligned::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<aligned::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `u128` cannot be safely transmuted into `aligned::repr_rust` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:40:47 + | +LL | assert::is_maybe_transmutable::<u128, repr_rust>(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `aligned::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `aligned::repr_rust` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `packed::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:45:52 + | +LL | assert::is_maybe_transmutable::<repr_rust, ()>(); + | ^^ `packed::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<packed::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `u128` cannot be safely transmuted into `packed::repr_rust` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:46:47 + | +LL | assert::is_maybe_transmutable::<u128, repr_rust>(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `packed::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `packed::repr_rust` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `nested::repr_c` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:52:49 + | +LL | assert::is_maybe_transmutable::<repr_c, ()>(); + | ^^ `nested::repr_c` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<nested::repr_c, assert::Context, true, true, true, true>` is not implemented for `()` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `u128` cannot be safely transmuted into `nested::repr_c` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:53:47 + | +LL | assert::is_maybe_transmutable::<u128, repr_c>(); + | ^^^^^^ `u128` cannot be safely transmuted into `nested::repr_c` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `nested::repr_c` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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/src/test/ui/transmutability/structs/should_order_fields_correctly.rs b/src/test/ui/transmutability/structs/should_order_fields_correctly.rs new file mode 100644 index 000000000..db49b914f --- /dev/null +++ b/src/test/ui/transmutability/structs/should_order_fields_correctly.rs @@ -0,0 +1,31 @@ +// check-pass +//! The fields of a struct should be laid out in lexical order. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +#[repr(u8)] enum V0 { V = 0 } +#[repr(u8)] enum V1 { V = 1 } +#[repr(u8)] enum V2 { V = 2 } + +#[repr(C)] struct S01(V0, V1); +#[repr(C)] struct S012(V0, V1, V2); + +fn should_order_tag_and_fields_correctly() { + // An implementation that (incorrectly) arranges S01 as [0x01, 0x00] will, + // in principle, reject this transmutation. + assert::is_transmutable::<S01, V0>(); + // Again, but with one more field. + assert::is_transmutable::<S012, S01>(); +} diff --git a/src/test/ui/transmutability/unions/boolish.rs b/src/test/ui/transmutability/unions/boolish.rs new file mode 100644 index 000000000..975118b99 --- /dev/null +++ b/src/test/ui/transmutability/unions/boolish.rs @@ -0,0 +1,31 @@ +// check-pass + +#![crate_type = "lib"] +#![feature(transmutability)] +#![feature(marker_trait_attr)] +#![allow(dead_code)] +#![allow(incomplete_features)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true> + {} +} + +fn should_match_bool() { + #[derive(Copy, Clone)] #[repr(u8)] pub enum False { V = 0 } + #[derive(Copy, Clone)] #[repr(u8)] pub enum True { V = 1 } + + #[repr(C)] + pub union Bool { + pub f: False, + pub t: True, + } + + assert::is_transmutable::<Bool, bool>(); + assert::is_transmutable::<bool, Bool>(); +} diff --git a/src/test/ui/transmutability/unions/repr/should_handle_align.rs b/src/test/ui/transmutability/unions/repr/should_handle_align.rs new file mode 100644 index 000000000..e215799a2 --- /dev/null +++ b/src/test/ui/transmutability/unions/repr/should_handle_align.rs @@ -0,0 +1,40 @@ +// check-pass +//! The presence of an `align(X)` annotation must be accounted for. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +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)] + pub union Uninit { + a: (), + b: V1u8, + } + + #[repr(C, align(2))] + pub union align_2 { + a: V0u8, + } + + #[repr(C)] struct ImplicitlyPadded(align_2, V0u8); + #[repr(C)] struct ExplicitlyPadded(V0u8, Uninit, V0u8); + + // An implementation that (incorrectly) does not place a padding byte after + // `align_2` will, incorrectly, reject the following transmutations. + assert::is_maybe_transmutable::<ImplicitlyPadded, ExplicitlyPadded>(); + assert::is_maybe_transmutable::<ExplicitlyPadded, ImplicitlyPadded>(); +} diff --git a/src/test/ui/transmutability/unions/repr/should_handle_packed.rs b/src/test/ui/transmutability/unions/repr/should_handle_packed.rs new file mode 100644 index 000000000..34a53c7a8 --- /dev/null +++ b/src/test/ui/transmutability/unions/repr/should_handle_packed.rs @@ -0,0 +1,41 @@ +// check-pass +//! The presence of an `align(X)` annotation must be accounted for. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +fn should_pad_explicitly_packed_field() { + #[derive(Clone, Copy)] #[repr(u8)] enum V0u8 { V = 0 } + #[derive(Clone, Copy)] #[repr(u8)] enum V1u8 { V = 1 } + #[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, + } + + #[repr(C, packed(2))] + pub union Packed { + a: [V3u32; 0], + b: V0u8, + } + + #[repr(C)] struct ImplicitlyPadded(Packed, V2u8); + #[repr(C)] struct ExplicitlyPadded(V0u8, Uninit, V2u8); + + assert::is_maybe_transmutable::<ImplicitlyPadded, ExplicitlyPadded>(); + assert::is_maybe_transmutable::<ExplicitlyPadded, ImplicitlyPadded>(); +} diff --git a/src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.rs b/src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.rs new file mode 100644 index 000000000..cec8e389f --- /dev/null +++ b/src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.rs @@ -0,0 +1,37 @@ +//! A struct must have a well-defined layout to participate in a transmutation. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +fn should_reject_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 +} + +fn should_accept_repr_C() +{ + #[repr(C)] + union repr_c { + a: u8 + } + + struct repr_rust; + assert::is_maybe_transmutable::<repr_c, ()>(); + assert::is_maybe_transmutable::<u128, repr_c>(); +} diff --git a/src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr b/src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr new file mode 100644 index 000000000..2ed01b159 --- /dev/null +++ b/src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr @@ -0,0 +1,35 @@ +error[E0277]: `should_reject_repr_rust::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:23:48 + | +LL | assert::is_maybe_transmutable::<repr_rust, ()>(); + | ^^ `should_reject_repr_rust::repr_rust` cannot be safely transmuted into `()` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<should_reject_repr_rust::repr_rust, assert::Context, true, true, true, true>` is not implemented for `()` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::repr_rust` in the defining scope of `assert::Context`. + --> $DIR/should_require_well_defined_layout.rs:24:43 + | +LL | assert::is_maybe_transmutable::<u128, repr_rust>(); + | ^^^^^^^^^ `u128` cannot be safely transmuted into `should_reject_repr_rust::repr_rust` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<u128, assert::Context, true, true, true, true>` is not implemented for `should_reject_repr_rust::repr_rust` +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 +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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/src/test/ui/transmutability/unions/should_pad_variants.rs b/src/test/ui/transmutability/unions/should_pad_variants.rs new file mode 100644 index 000000000..c4757900f --- /dev/null +++ b/src/test/ui/transmutability/unions/should_pad_variants.rs @@ -0,0 +1,40 @@ +//! The variants of a union must be padded with uninit bytes such that they have +//! the same length (in bytes). + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + {} +} + +#[derive(Clone, Copy)] +#[repr(C)] struct Zst; + +#[derive(Clone, Copy)] +#[repr(u8)] enum V0 { V = 0 } + +#[derive(Clone, Copy)] +#[repr(u8)] enum V2 { V = 2 } + +#[repr(C)] +union Lopsided { + smol: Zst, + lorg: V0, +} + +#[repr(C)] struct Src(V0, Zst, V2); +#[repr(C)] struct Dst(V0, Lopsided, V2); + +fn should_pad_variants() { + struct Context; + // If the implementation (incorrectly) fails to pad `Lopsided::smol` with + // an uninitialized byte, this transmutation might be (wrongly) accepted: + assert::is_transmutable::<Src, Dst, Context>(); //~ ERROR cannot be safely transmuted +} diff --git a/src/test/ui/transmutability/unions/should_pad_variants.stderr b/src/test/ui/transmutability/unions/should_pad_variants.stderr new file mode 100644 index 000000000..429f7211d --- /dev/null +++ b/src/test/ui/transmutability/unions/should_pad_variants.stderr @@ -0,0 +1,19 @@ +error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_pad_variants::Context`. + --> $DIR/should_pad_variants.rs:39:36 + | +LL | assert::is_transmutable::<Src, Dst, Context>(); + | ^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_pad_variants::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<Src, should_pad_variants::Context, true, true, true, true>` is not implemented for `Dst` +note: required by a bound in `is_transmutable` + --> $DIR/should_pad_variants.rs:13:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, true, true, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs b/src/test/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs new file mode 100644 index 000000000..2493d7155 --- /dev/null +++ b/src/test/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs @@ -0,0 +1,39 @@ +// check-pass +//! If validity is assumed, there need only be one matching bit-pattern between +//! the source and destination types. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, true, true> + // validity IS assumed --------------------------------^^^^ + {} +} + +#[derive(Clone, Copy)] #[repr(u8)] enum Ox00 { V = 0x00 } +#[derive(Clone, Copy)] #[repr(u8)] enum Ox7F { V = 0x7F } +#[derive(Clone, Copy)] #[repr(u8)] enum OxFF { V = 0xFF } + +fn test() { + #[repr(C)] + union A { + a: Ox00, + b: Ox7F, + } + + #[repr(C)] + union B { + a: Ox7F, + b: OxFF, + } + + assert::is_maybe_transmutable::<A, B>(); + assert::is_maybe_transmutable::<B, A>(); +} diff --git a/src/test/ui/transmutability/unions/should_reject_contraction.rs b/src/test/ui/transmutability/unions/should_reject_contraction.rs new file mode 100644 index 000000000..e8138d0e0 --- /dev/null +++ b/src/test/ui/transmutability/unions/should_reject_contraction.rs @@ -0,0 +1,36 @@ +//! Validity may not be contracted, unless validity is assumed. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true> + {} +} + +#[derive(Clone, Copy)] #[repr(u8)] enum Ox00 { V = 0x00 } +#[derive(Clone, Copy)] #[repr(u8)] enum Ox01 { V = 0x01 } +#[derive(Clone, Copy)] #[repr(u8)] enum OxFF { V = 0xFF } + +fn test() { + #[repr(C)] + union Subset { + a: Ox00, + b: OxFF, + } + + #[repr(C)] + union Superset { + a: Ox00, + b: OxFF, + c: Ox01, + } + + assert::is_transmutable::<Superset, Subset>(); //~ ERROR cannot be safely transmuted +} diff --git a/src/test/ui/transmutability/unions/should_reject_contraction.stderr b/src/test/ui/transmutability/unions/should_reject_contraction.stderr new file mode 100644 index 000000000..99f589008 --- /dev/null +++ b/src/test/ui/transmutability/unions/should_reject_contraction.stderr @@ -0,0 +1,19 @@ +error[E0277]: `Superset` cannot be safely transmuted into `Subset` in the defining scope of `assert::Context`. + --> $DIR/should_reject_contraction.rs:35:41 + | +LL | assert::is_transmutable::<Superset, Subset>(); + | ^^^^^^ `Superset` cannot be safely transmuted into `Subset` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<Superset, assert::Context, false, false, false, true>` is not implemented for `Subset` +note: required by a bound in `is_transmutable` + --> $DIR/should_reject_contraction.rs:13:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/transmutability/unions/should_reject_disjoint.rs b/src/test/ui/transmutability/unions/should_reject_disjoint.rs new file mode 100644 index 000000000..16160e29a --- /dev/null +++ b/src/test/ui/transmutability/unions/should_reject_disjoint.rs @@ -0,0 +1,36 @@ +//! Validity must be satisfiable, even if validity is assumed. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_maybe_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, true, true> + // validity IS assumed --------------------------------^^^^ + {} +} + +#[derive(Clone, Copy)] #[repr(u8)] enum Ox00 { V = 0x00 } +#[derive(Clone, Copy)] #[repr(u8)] enum Ox01 { V = 0x01 } +#[derive(Clone, Copy)] #[repr(u8)] enum OxFF { V = 0xFF } + +fn test() { + #[repr(C)] + union A { + a: Ox00, + b: OxFF, + } + + #[repr(C)] + union B { + c: Ox01, + } + + assert::is_maybe_transmutable::<A, B>(); //~ ERROR cannot be safely transmuted + assert::is_maybe_transmutable::<B, A>(); //~ ERROR cannot be safely transmuted +} diff --git a/src/test/ui/transmutability/unions/should_reject_disjoint.stderr b/src/test/ui/transmutability/unions/should_reject_disjoint.stderr new file mode 100644 index 000000000..5714e2bf3 --- /dev/null +++ b/src/test/ui/transmutability/unions/should_reject_disjoint.stderr @@ -0,0 +1,35 @@ +error[E0277]: `A` cannot be safely transmuted into `B` in the defining scope of `assert::Context`. + --> $DIR/should_reject_disjoint.rs:34:40 + | +LL | assert::is_maybe_transmutable::<A, B>(); + | ^ `A` cannot be safely transmuted into `B` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<A, assert::Context, false, false, true, true>` is not implemented for `B` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_reject_disjoint.rs:13:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` + +error[E0277]: `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`. + --> $DIR/should_reject_disjoint.rs:35:40 + | +LL | assert::is_maybe_transmutable::<B, A>(); + | ^ `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<B, assert::Context, false, false, true, true>` is not implemented for `A` +note: required by a bound in `is_maybe_transmutable` + --> $DIR/should_reject_disjoint.rs:13:14 + | +LL | pub fn is_maybe_transmutable<Src, Dst>() + | --------------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, true, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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/src/test/ui/transmutability/unions/should_reject_intersecting.rs b/src/test/ui/transmutability/unions/should_reject_intersecting.rs new file mode 100644 index 000000000..58e399fb9 --- /dev/null +++ b/src/test/ui/transmutability/unions/should_reject_intersecting.rs @@ -0,0 +1,38 @@ +//! ALL valid bit patterns of the source must be valid bit patterns of the +//! destination type, unless validity is assumed. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + pub struct Context; + + pub fn is_transmutable<Src, Dst>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true> + // validity is NOT assumed ----------------------------^^^^^ + {} +} + +#[derive(Clone, Copy)] #[repr(u8)] enum Ox00 { V = 0x00 } +#[derive(Clone, Copy)] #[repr(u8)] enum Ox7F { V = 0x7F } +#[derive(Clone, Copy)] #[repr(u8)] enum OxFF { V = 0xFF } + +fn test() { + #[repr(C)] + union A { + a: Ox00, + b: Ox7F, + } + + #[repr(C)] + union B { + a: Ox7F, + b: OxFF, + } + + assert::is_transmutable::<A, B>(); //~ ERROR cannot be safely transmuted + assert::is_transmutable::<B, A>(); //~ ERROR cannot be safely transmuted +} diff --git a/src/test/ui/transmutability/unions/should_reject_intersecting.stderr b/src/test/ui/transmutability/unions/should_reject_intersecting.stderr new file mode 100644 index 000000000..92689a5f8 --- /dev/null +++ b/src/test/ui/transmutability/unions/should_reject_intersecting.stderr @@ -0,0 +1,35 @@ +error[E0277]: `A` cannot be safely transmuted into `B` in the defining scope of `assert::Context`. + --> $DIR/should_reject_intersecting.rs:36:34 + | +LL | assert::is_transmutable::<A, B>(); + | ^ `A` cannot be safely transmuted into `B` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<A, assert::Context, false, false, false, true>` is not implemented for `B` +note: required by a bound in `is_transmutable` + --> $DIR/should_reject_intersecting.rs:14:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error[E0277]: `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`. + --> $DIR/should_reject_intersecting.rs:37:34 + | +LL | assert::is_transmutable::<B, A>(); + | ^ `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<B, assert::Context, false, false, false, true>` is not implemented for `A` +note: required by a bound in `is_transmutable` + --> $DIR/should_reject_intersecting.rs:14:14 + | +LL | pub fn is_transmutable<Src, Dst>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_field.rs b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_field.rs new file mode 100644 index 000000000..5a8c81049 --- /dev/null +++ b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_field.rs @@ -0,0 +1,38 @@ +// check-pass +//! If visibility is assumed, a transmutation should be accepted even if the +//! destination type contains a private field. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true> + // visibility IS assumed -------------------------------------^^^^ + {} +} + +mod src { + #[repr(C)] pub(self) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(self) field: Zst, + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Dst { + pub(self) field: Zst, // <- private field + } +} + +fn test() { + struct Context; + assert::is_transmutable::<src::Src, dst::Dst, Context>(); +} diff --git a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_variant.rs b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_variant.rs new file mode 100644 index 000000000..77ab4fa6b --- /dev/null +++ b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_variant.rs @@ -0,0 +1,39 @@ +// check-pass +//! If visibility is assumed, a transmutation should be accepted even if the +//! destination type contains a private variant. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true> + // visibility IS assumed -------------------------------------^^^^ + {} +} + +mod src { + #[repr(C)] pub(self) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(self) field: Zst, + } +} + +mod dst { + #[derive(Copy, Clone)] + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) union Dst { + pub(self) field: Zst, // <- private variant + } +} + +fn test() { + struct Context; + assert::is_transmutable::<src::Src, dst::Dst, Context>(); +} diff --git a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_tricky_unreachable_field.rs b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_tricky_unreachable_field.rs new file mode 100644 index 000000000..2421b24cb --- /dev/null +++ b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_tricky_unreachable_field.rs @@ -0,0 +1,46 @@ +// check-pass +//! Unless visibility is assumed, a transmutation should be rejected if the +//! destination type contains an unreachable field (e.g., a public field with a +//! private type). (This rule is distinct from type privacy, which still may +//! forbid naming such types.) +//! +//! This test exercises a tricky-to-implement instance of this principle: the +//! "pub-in-priv trick". In the below example, the type `dst::private::Zst` is +//! unreachable from `Context`. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true> + // visibility IS assumed -------------------------------------^^^^ + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(in super) field: Zst, + } +} + +mod dst { + mod private { + #[repr(C)] pub struct Zst; // <- unreachable type + } + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: private::Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::<src::Src, dst::Dst, Context>(); +} diff --git a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs new file mode 100644 index 000000000..80b454fda --- /dev/null +++ b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs @@ -0,0 +1,39 @@ +//! If visibility is assumed, a transmutation should be accepted even if the +//! destination type contains an unreachable field (e.g., a public field with a +//! private type). (This rule is distinct from type privacy, which still may +//! forbid naming such types.) + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true> + // visibility IS assumed -------------------------------------^^^^ + {} +} + +mod src { + #[repr(C)] pub(self) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(self) field: Zst, + } +} + +mod dst { + #[repr(C)] pub(self) struct Zst; // <- unreachable type + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: Zst, //~ ERROR private type + } +} + +fn test() { + struct Context; + assert::is_transmutable::<src::Src, dst::Dst, Context>(); +} diff --git a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr new file mode 100644 index 000000000..be83b7ce3 --- /dev/null +++ b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr @@ -0,0 +1,12 @@ +error[E0446]: private type `dst::Zst` in public interface + --> $DIR/should_accept_if_dst_has_unreachable_field.rs:32:9 + | +LL | #[repr(C)] pub(self) struct Zst; // <- unreachable type + | -------------------- `dst::Zst` declared as private +... +LL | pub(in super) field: Zst, + | ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0446`. diff --git a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.rs b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.rs new file mode 100644 index 000000000..7c53c91e4 --- /dev/null +++ b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.rs @@ -0,0 +1,40 @@ +//! If visibility is assumed, a transmutation should be accepted even if the +//! destination type contains an unreachable field (e.g., a public field with a +//! private type). (This rule is distinct from type privacy, which still may +//! forbid naming such types.) + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, true> + // visibility IS assumed -------------------------------------^^^^ + {} +} + +mod src { + #[repr(C)] pub(self) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(self) field: Zst, + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + // unreachable type + #[repr(C)] pub(self) struct Dst { + pub(in super) field: Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::<src::Src, dst::Dst, Context>(); //~ ERROR `Dst` is private +} diff --git a/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.stderr b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.stderr new file mode 100644 index 000000000..827df05de --- /dev/null +++ b/src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.stderr @@ -0,0 +1,15 @@ +error[E0603]: struct `Dst` is private + --> $DIR/should_accept_if_dst_has_unreachable_ty.rs:39:46 + | +LL | assert::is_transmutable::<src::Src, dst::Dst, Context>(); + | ^^^ private struct + | +note: the struct `Dst` is defined here + --> $DIR/should_accept_if_dst_has_unreachable_ty.rs:32:16 + | +LL | #[repr(C)] pub(self) struct Dst { + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0603`. diff --git a/src/test/ui/transmutability/visibility/should_accept_if_src_has_private_field.rs b/src/test/ui/transmutability/visibility/should_accept_if_src_has_private_field.rs new file mode 100644 index 000000000..c3f298f01 --- /dev/null +++ b/src/test/ui/transmutability/visibility/should_accept_if_src_has_private_field.rs @@ -0,0 +1,38 @@ +// check-pass +//! The presence of a private field in the source type does not affect +//! transmutability. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + // visibility is NOT assumed ---------------------------------^^^^^ + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(self) field: Zst, // <- private field + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::<src::Src, dst::Dst, Context>(); +} diff --git a/src/test/ui/transmutability/visibility/should_accept_if_src_has_private_variant.rs b/src/test/ui/transmutability/visibility/should_accept_if_src_has_private_variant.rs new file mode 100644 index 000000000..73f6aece5 --- /dev/null +++ b/src/test/ui/transmutability/visibility/should_accept_if_src_has_private_variant.rs @@ -0,0 +1,39 @@ +// check-pass +//! The presence of a private variant in the source type does not affect +//! transmutability. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + // visibility is NOT assumed ---------------------------------^^^^^ + {} +} + +mod src { + #[derive(Copy, Clone)] + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) union Src { + pub(self) field: Zst, // <- private variant + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::<src::Src, dst::Dst, Context>(); +} diff --git a/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs new file mode 100644 index 000000000..6d602601e --- /dev/null +++ b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs @@ -0,0 +1,38 @@ +//! The presence of an unreachable field in the source type (e.g., a public +//! field with a private type does not affect transmutability. (This rule is +//! distinct from type privacy, which still may forbid naming such types.) + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + // visibility is NOT assumed ---------------------------------^^^^^ + {} +} + +mod src { + #[repr(C)] pub(self) struct Zst; // <- unreachable type + + #[repr(C)] pub(in super) struct Src { + pub(in super) field: Zst, //~ ERROR private type + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::<src::Src, dst::Dst, Context>(); +} diff --git a/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr new file mode 100644 index 000000000..3f7d08d0a --- /dev/null +++ b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr @@ -0,0 +1,12 @@ +error[E0446]: private type `src::Zst` in public interface + --> $DIR/should_accept_if_src_has_unreachable_field.rs:23:9 + | +LL | #[repr(C)] pub(self) struct Zst; // <- unreachable type + | -------------------- `src::Zst` declared as private +... +LL | pub(in super) field: Zst, + | ^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0446`. diff --git a/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.rs b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.rs new file mode 100644 index 000000000..1943fb871 --- /dev/null +++ b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.rs @@ -0,0 +1,39 @@ +//! The presence of an unreachable source type (i.e., the source type is +//! private) does not affect transmutability. (This rule is distinct from type +//! privacy, which still may forbid naming such types.) + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + // visibility is NOT assumed ---------------------------------^^^^^ + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + // unreachable type + #[repr(C)] pub(self) struct Src { + pub(in super) field: Zst, + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::<src::Src, dst::Dst, Context>(); //~ ERROR `Src` is private +} diff --git a/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.stderr b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.stderr new file mode 100644 index 000000000..e961984e1 --- /dev/null +++ b/src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.stderr @@ -0,0 +1,15 @@ +error[E0603]: struct `Src` is private + --> $DIR/should_accept_if_src_has_unreachable_ty.rs:38:36 + | +LL | assert::is_transmutable::<src::Src, dst::Dst, Context>(); + | ^^^ private struct + | +note: the struct `Src` is defined here + --> $DIR/should_accept_if_src_has_unreachable_ty.rs:23:16 + | +LL | #[repr(C)] pub(self) struct Src { + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0603`. diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.rs b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.rs new file mode 100644 index 000000000..fcf3f3a52 --- /dev/null +++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.rs @@ -0,0 +1,37 @@ +//! Unless visibility is assumed, a transmutation should be rejected if the +//! destination type contains a private field. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + // visibility is NOT assumed ---------------------------------^^^^^ + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(in super) field: Zst, + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Dst { + pub(self) field: Zst, // <- private field + } +} + +fn test() { + struct Context; + assert::is_transmutable::<src::Src, dst::Dst, Context>(); //~ ERROR cannot be safely transmuted +} diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr new file mode 100644 index 000000000..85124019e --- /dev/null +++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr @@ -0,0 +1,19 @@ +error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + --> $DIR/should_reject_if_dst_has_private_field.rs:36:41 + | +LL | assert::is_transmutable::<src::Src, dst::Dst, Context>(); + | ^^^^^^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<Src, test::Context, false, false, false, false>` is not implemented for `Dst` +note: required by a bound in `is_transmutable` + --> $DIR/should_reject_if_dst_has_private_field.rs:13:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.rs b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.rs new file mode 100644 index 000000000..566b56467 --- /dev/null +++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.rs @@ -0,0 +1,38 @@ +//! Unless visibility is assumed, a transmutation should be rejected if the +//! destination type contains a private variant. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + // visibility is NOT assumed ---------------------------------^^^^^ + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(in super) field: Zst, + } +} + +mod dst { + #[derive(Copy, Clone)] + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) union Dst { + pub(self) field: Zst, // <- private variant + } +} + +fn test() { + struct Context; + assert::is_transmutable::<src::Src, dst::Dst, Context>(); //~ ERROR cannot be safely transmuted +} diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr new file mode 100644 index 000000000..0be564d93 --- /dev/null +++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr @@ -0,0 +1,19 @@ +error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + --> $DIR/should_reject_if_dst_has_private_variant.rs:37:41 + | +LL | assert::is_transmutable::<src::Src, dst::Dst, Context>(); + | ^^^^^^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<Src, test::Context, false, false, false, false>` is not implemented for `Dst` +note: required by a bound in `is_transmutable` + --> $DIR/should_reject_if_dst_has_private_variant.rs:13:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_tricky_unreachable_field.rs b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_tricky_unreachable_field.rs new file mode 100644 index 000000000..35fff5966 --- /dev/null +++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_tricky_unreachable_field.rs @@ -0,0 +1,52 @@ +// check-pass +//! NOTE: This test documents a known-bug in the implementation of the +//! transmutability trait. Once fixed, the above "check-pass" header should be +//! removed, and an "ERROR cannot be safely transmuted" annotation should be added at the end +//! of the line starting with `assert::is_transmutable`. +//! +//! Unless visibility is assumed, a transmutation should be rejected if the +//! destination type contains an unreachable field (e.g., a public field with a +//! private type). (This rule is distinct from type privacy, which still may +//! forbid naming such types.) +//! +//! This test exercises a tricky-to-implement instance of this principle: the +//! "pub-in-priv trick". In the below example, the type `dst::private::Zst` is +//! unreachable from `Context`. Consequently, the transmute from `Src` to `Dst` +//! SHOULD be rejected. + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + // visibility is NOT assumed ---------------------------------^^^^^ + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(in super) field: Zst, + } +} + +mod dst { + mod private { + #[repr(C)] pub struct Zst; // <- unreachable type + } + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: private::Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::<src::Src, dst::Dst, Context>(); +} diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.rs b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.rs new file mode 100644 index 000000000..42799d803 --- /dev/null +++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.rs @@ -0,0 +1,39 @@ +//! Unless visibility is assumed, a transmutation should be rejected if the +//! destination type contains an unreachable field (e.g., a public field with a +//! private type). (This rule is distinct from type privacy, which still may +//! forbid naming such types.) + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + // visibility is NOT assumed ---------------------------------^^^^^ + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(in super) field: Zst, + } +} + +mod dst { + #[repr(C)] pub(self) struct Zst; // <- unreachable type + + #[repr(C)] pub(in super) struct Dst { + pub(in super) field: Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::<src::Src, dst::Dst, Context>(); //~ ERROR cannot be safely transmuted +} diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr new file mode 100644 index 000000000..95c68d452 --- /dev/null +++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr @@ -0,0 +1,19 @@ +error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + --> $DIR/should_reject_if_dst_has_unreachable_field.rs:38:41 + | +LL | assert::is_transmutable::<src::Src, dst::Dst, Context>(); + | ^^^^^^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<Src, test::Context, false, false, false, false>` is not implemented for `Dst` +note: required by a bound in `is_transmutable` + --> $DIR/should_reject_if_dst_has_unreachable_field.rs:15:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.rs b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.rs new file mode 100644 index 000000000..e13b32b30 --- /dev/null +++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.rs @@ -0,0 +1,42 @@ +//! Unless visibility is assumed, a transmutation should be rejected if the +//! destination type contains an unreachable field (e.g., a public field with a +//! private type). (This rule is distinct from type privacy, which still may +//! forbid naming such types.) + +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Dst, Context>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + // visibility is NOT assumed ---------------------------------^^^^^ + {} +} + +mod src { + #[repr(C)] pub(in super) struct Zst; + + #[repr(C)] pub(in super) struct Src { + pub(in super) field: Zst, + } +} + +mod dst { + #[repr(C)] pub(in super) struct Zst; + + // unreachable type + #[repr(C)] pub(self) struct Dst { + pub(in super) field: Zst, + } +} + +fn test() { + struct Context; + assert::is_transmutable::<src::Src, dst::Dst, Context>(); + //~^ ERROR `Dst` is private + //~| ERROR cannot be safely transmuted +} diff --git a/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr new file mode 100644 index 000000000..3391839e3 --- /dev/null +++ b/src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr @@ -0,0 +1,32 @@ +error[E0603]: struct `Dst` is private + --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:39:46 + | +LL | assert::is_transmutable::<src::Src, dst::Dst, Context>(); + | ^^^ private struct + | +note: the struct `Dst` is defined here + --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:32:16 + | +LL | #[repr(C)] pub(self) struct Dst { + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:39:41 + | +LL | assert::is_transmutable::<src::Src, dst::Dst, Context>(); + | ^^^^^^^^ `Src` cannot be safely transmuted into `Dst` in the defining scope of `test::Context`. + | + = help: the trait `BikeshedIntrinsicFrom<Src, test::Context, false, false, false, false>` is not implemented for `Dst` +note: required by a bound in `is_transmutable` + --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:15:14 + | +LL | pub fn is_transmutable<Src, Dst, Context>() + | --------------- required by a bound in this +LL | where +LL | Dst: BikeshedIntrinsicFrom<Src, Context, false, false, false, false> + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0603. +For more information about an error, try `rustc --explain E0277`. |