about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-02 21:17:31 +0000
committerbors <bors@rust-lang.org>2022-08-02 21:17:31 +0000
commite4417cf020fbcd6182c11637bc6b8694434bd81a (patch)
tree0e57100d6b7d73ba497ea478b1aeb94739b85776 /src
parent4493a0f4724c0bae1436242d76cccc9c0a287b80 (diff)
parent965ffb0b5cf3372900ce473f244ec33270058888 (diff)
Auto merge of #92268 - jswrenn:transmute, r=oli-obk
Initial implementation of transmutability trait.

*T'was the night before Christmas and all through the codebase, not a miri was stirring — no hint of `unsafe`!*

This PR provides an initial, **incomplete** implementation of *[MCP 411: Lang Item for Transmutability](https://github.com/rust-lang/compiler-team/issues/411)*. The `core::mem::BikeshedIntrinsicFrom` trait provided by this PR is implemented on-the-fly by the compiler for types `Src` and `Dst` when the bits of all possible values of type `Src` are safely reinterpretable as a value of type `Dst`.

What this PR provides is:
- [x] [support for transmutations involving primitives](https://github.com/jswrenn/rust/tree/transmute/src/test/ui/transmutability/primitives)
- [x] [support for transmutations involving arrays](https://github.com/jswrenn/rust/tree/transmute/src/test/ui/transmutability/arrays)
- [x] [support for transmutations involving structs](https://github.com/jswrenn/rust/tree/transmute/src/test/ui/transmutability/structs)
- [x] [support for transmutations involving enums](https://github.com/jswrenn/rust/tree/transmute/src/test/ui/transmutability/enums)
- [x] [support for transmutations involving unions](https://github.com/jswrenn/rust/tree/transmute/src/test/ui/transmutability/unions)
- [x] [support for weaker validity checks](https://github.com/jswrenn/rust/blob/transmute/src/test/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs) (i.e., `Assume::VALIDITY`)
- [x] visibility checking

What isn't yet implemented:
- [ ] transmutability options passed using the `Assume` struct
- [ ] [support for references](https://github.com/jswrenn/rust/blob/transmute/src/test/ui/transmutability/references.rs)
- [ ] smarter error messages

These features will be implemented in future PRs.
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/transmutability/abstraction/abstracted_assume.rs73
-rw-r--r--src/test/ui/transmutability/abstraction/const_generic_fn.rs41
-rw-r--r--src/test/ui/transmutability/arrays/should_have_correct_length.rs44
-rw-r--r--src/test/ui/transmutability/arrays/should_inherit_alignment.rs55
-rw-r--r--src/test/ui/transmutability/arrays/should_require_well_defined_layout.rs61
-rw-r--r--src/test/ui/transmutability/arrays/should_require_well_defined_layout.stderr99
-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
-rw-r--r--src/test/ui/transmutability/malformed-program-gracefulness/feature-missing.rs9
-rw-r--r--src/test/ui/transmutability/malformed-program-gracefulness/feature-missing.stderr21
-rw-r--r--src/test/ui/transmutability/malformed-program-gracefulness/unknown_dst.rs21
-rw-r--r--src/test/ui/transmutability/malformed-program-gracefulness/unknown_dst.stderr12
-rw-r--r--src/test/ui/transmutability/malformed-program-gracefulness/unknown_src.rs21
-rw-r--r--src/test/ui/transmutability/malformed-program-gracefulness/unknown_src.stderr12
-rw-r--r--src/test/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs22
-rw-r--r--src/test/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr9
-rw-r--r--src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.rs40
-rw-r--r--src/test/ui/transmutability/malformed-program-gracefulness/wrong-type-assume.stderr27
-rw-r--r--src/test/ui/transmutability/primitives/bool.rs25
-rw-r--r--src/test/ui/transmutability/primitives/bool.stderr19
-rw-r--r--src/test/ui/transmutability/primitives/numbers.rs128
-rw-r--r--src/test/ui/transmutability/primitives/numbers.stderr915
-rw-r--r--src/test/ui/transmutability/primitives/unit.rs24
-rw-r--r--src/test/ui/transmutability/primitives/unit.stderr19
-rw-r--r--src/test/ui/transmutability/references.rs20
-rw-r--r--src/test/ui/transmutability/references.stderr19
-rw-r--r--src/test/ui/transmutability/structs/repr/should_handle_align.rs36
-rw-r--r--src/test/ui/transmutability/structs/repr/should_handle_packed.rs35
-rw-r--r--src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.rs76
-rw-r--r--src/test/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr195
-rw-r--r--src/test/ui/transmutability/structs/should_order_fields_correctly.rs31
-rw-r--r--src/test/ui/transmutability/unions/boolish.rs31
-rw-r--r--src/test/ui/transmutability/unions/repr/should_handle_align.rs40
-rw-r--r--src/test/ui/transmutability/unions/repr/should_handle_packed.rs41
-rw-r--r--src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.rs37
-rw-r--r--src/test/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr35
-rw-r--r--src/test/ui/transmutability/unions/should_pad_variants.rs40
-rw-r--r--src/test/ui/transmutability/unions/should_pad_variants.stderr19
-rw-r--r--src/test/ui/transmutability/unions/should_permit_intersecting_if_validity_is_assumed.rs39
-rw-r--r--src/test/ui/transmutability/unions/should_reject_contraction.rs36
-rw-r--r--src/test/ui/transmutability/unions/should_reject_contraction.stderr19
-rw-r--r--src/test/ui/transmutability/unions/should_reject_disjoint.rs36
-rw-r--r--src/test/ui/transmutability/unions/should_reject_disjoint.stderr35
-rw-r--r--src/test/ui/transmutability/unions/should_reject_intersecting.rs38
-rw-r--r--src/test/ui/transmutability/unions/should_reject_intersecting.stderr35
-rw-r--r--src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_field.rs38
-rw-r--r--src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_private_variant.rs39
-rw-r--r--src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_tricky_unreachable_field.rs46
-rw-r--r--src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.rs39
-rw-r--r--src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_field.stderr12
-rw-r--r--src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.rs40
-rw-r--r--src/test/ui/transmutability/visibility/assume/should_accept_if_dst_has_unreachable_ty.stderr15
-rw-r--r--src/test/ui/transmutability/visibility/should_accept_if_src_has_private_field.rs38
-rw-r--r--src/test/ui/transmutability/visibility/should_accept_if_src_has_private_variant.rs39
-rw-r--r--src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.rs38
-rw-r--r--src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_field.stderr12
-rw-r--r--src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.rs39
-rw-r--r--src/test/ui/transmutability/visibility/should_accept_if_src_has_unreachable_ty.stderr15
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.rs37
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr19
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.rs38
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr19
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_tricky_unreachable_field.rs52
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.rs39
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr19
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.rs42
-rw-r--r--src/test/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr32
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 00000000000..2abbbf3c158
--- /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 00000000000..94c38bb28f7
--- /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 00000000000..bfe6d830a1b
--- /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 00000000000..fcb1765ea6b
--- /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 00000000000..8e69527c186
--- /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 00000000000..eae0c947d42
--- /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 00000000000..18e02b0d2b9
--- /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 00000000000..fa2e3b89b07
--- /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 00000000000..978a12648f0
--- /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 00000000000..3273e87c89f
--- /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 00000000000..6558d2658ee
--- /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 00000000000..466b6c8a15b
--- /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 00000000000..429f7211d17
--- /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 00000000000..67a3c4e94ba
--- /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 00000000000..78023cb378a
--- /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 00000000000..30c381745d0
--- /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 00000000000..ba8093f8614
--- /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 00000000000..e13462d390b
--- /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 00000000000..85087282d3a
--- /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 00000000000..dc51e2a8f4d
--- /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 00000000000..9bedbe87c3f
--- /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 00000000000..86fc8bd6b28
--- /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 00000000000..475e6f429f3
--- /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 00000000000..bd36748e790
--- /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 00000000000..e1464e02352
--- /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 00000000000..4f79bc25337
--- /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 00000000000..dc740251c87
--- /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 00000000000..a5f79065d8a
--- /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 00000000000..9b802a444e8
--- /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 00000000000..86d4740300d
--- /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 00000000000..cf27c0d17b3
--- /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 00000000000..c6fd4c43e95
--- /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 00000000000..17ffcf64177
--- /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:52
+   |
+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 00000000000..71720165ab0
--- /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 00000000000..ae8acf50418
--- /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 00000000000..556be989dbc
--- /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 00000000000..07355f7c2ad
--- /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 00000000000..db49b914fe0
--- /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 00000000000..975118b99b7
--- /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 00000000000..e215799a232
--- /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 00000000000..34a53c7a80c
--- /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 00000000000..cec8e389f44
--- /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 00000000000..2ed01b159ab
--- /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 00000000000..c4757900f9c
--- /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 00000000000..429f7211d17
--- /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 00000000000..2493d71554a
--- /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 00000000000..e8138d0e046
--- /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 00000000000..99f58900817
--- /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 00000000000..16160e29a54
--- /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 00000000000..5714e2bf320
--- /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 00000000000..58e399fb962
--- /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 00000000000..92689a5f828
--- /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 00000000000..5a8c810494c
--- /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 00000000000..77ab4fa6bff
--- /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 00000000000..2421b24cbf0
--- /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 00000000000..80b454fda56
--- /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 00000000000..be83b7ce33f
--- /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 00000000000..7c53c91e4ed
--- /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 00000000000..827df05decb
--- /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 00000000000..c3f298f0163
--- /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 00000000000..73f6aece51e
--- /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 00000000000..6d602601e96
--- /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 00000000000..3f7d08d0ae2
--- /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 00000000000..1943fb8716a
--- /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 00000000000..e961984e189
--- /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 00000000000..fcf3f3a5278
--- /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 00000000000..85124019e7f
--- /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 00000000000..566b5646712
--- /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 00000000000..0be564d93e2
--- /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 00000000000..35fff5966c8
--- /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 00000000000..42799d803b0
--- /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 00000000000..95c68d45201
--- /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 00000000000..e13b32b30d9
--- /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 00000000000..3391839e39e
--- /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`.