summaryrefslogtreecommitdiffstats
path: root/src/test/ui/transmutability/enums
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/transmutability/enums')
-rw-r--r--src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.rs149
-rw-r--r--src/test/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr323
-rw-r--r--src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.rs117
-rw-r--r--src/test/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr99
-rw-r--r--src/test/ui/transmutability/enums/should_order_correctly.rs32
-rw-r--r--src/test/ui/transmutability/enums/should_pad_variants.rs40
-rw-r--r--src/test/ui/transmutability/enums/should_pad_variants.stderr19
-rw-r--r--src/test/ui/transmutability/enums/should_respect_endianness.rs33
-rw-r--r--src/test/ui/transmutability/enums/should_respect_endianness.stderr19
9 files changed, 831 insertions, 0 deletions
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`.