about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-06-14 08:26:22 +0000
committerbors <bors@rust-lang.org>2023-06-14 08:26:22 +0000
commit3ed2a10d173d6c2e0232776af338ca7d080b1cd4 (patch)
tree91c79ae2593fa4cdeb38755a057feefa2594856d /tests
parent57c215b08e18054c64428e00a291b45dc690d9de (diff)
parentf4cf8f65a5e8e110c8c36469d31f16e8571e2c1a (diff)
downloadrust-3ed2a10d173d6c2e0232776af338ca7d080b1cd4.tar.gz
rust-3ed2a10d173d6c2e0232776af338ca7d080b1cd4.zip
Auto merge of #110662 - bryangarza:safe-transmute-reference-types, r=compiler-errors
Safe Transmute: Enable handling references

This patch enables support for references in Safe Transmute, by generating nested obligations during trait selection. Specifically, when we call `confirm_transmutability_candidate(...)`, we now recursively traverse the `rustc_transmute::Answer` tree and create obligations for all the `Answer` variants, some of which include multiple nested `Answer`s.
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/transmutability/alignment/align-fail.rs23
-rw-r--r--tests/ui/transmutability/alignment/align-fail.stderr30
-rw-r--r--tests/ui/transmutability/alignment/align-pass.rs23
-rw-r--r--tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr16
-rw-r--r--tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs2
-rw-r--r--tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr20
-rw-r--r--tests/ui/transmutability/primitives/bool-mut.rs17
-rw-r--r--tests/ui/transmutability/primitives/bool-mut.stderr18
-rw-r--r--tests/ui/transmutability/primitives/bool.current.stderr4
-rw-r--r--tests/ui/transmutability/primitives/bool.next.stderr4
-rw-r--r--tests/ui/transmutability/primitives/bool.rs5
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.rs25
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr25
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs26
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.stderr25
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.rs25
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr25
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types.rs27
-rw-r--r--tests/ui/transmutability/references/recursive-wrapper-types.stderr (renamed from tests/ui/transmutability/references.next.stderr)14
-rw-r--r--tests/ui/transmutability/references/u8-to-unit.rs24
-rw-r--r--tests/ui/transmutability/references/unit-to-itself.rs (renamed from tests/ui/transmutability/references.rs)16
-rw-r--r--tests/ui/transmutability/references/unit-to-u8.rs24
-rw-r--r--tests/ui/transmutability/references/unit-to-u8.stderr (renamed from tests/ui/transmutability/references.current.stderr)10
-rw-r--r--tests/ui/transmutability/region-infer.stderr2
24 files changed, 387 insertions, 43 deletions
diff --git a/tests/ui/transmutability/alignment/align-fail.rs b/tests/ui/transmutability/alignment/align-fail.rs
new file mode 100644
index 00000000000..7f6090a6e4d
--- /dev/null
+++ b/tests/ui/transmutability/alignment/align-fail.rs
@@ -0,0 +1,23 @@
+// check-fail
+#![feature(transmutability)]
+
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    pub struct Context;
+
+    pub fn is_maybe_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, Context, {
+            Assume {
+                alignment: false,
+                lifetimes: true,
+                safety: true,
+                validity: true,
+            }
+        }>
+    {}
+}
+
+fn main() {
+    assert::is_maybe_transmutable::<&'static [u8; 0], &'static [u16; 0]>(); //~ ERROR `&[u8; 0]` cannot be safely transmuted into `&[u16; 0]`
+}
diff --git a/tests/ui/transmutability/alignment/align-fail.stderr b/tests/ui/transmutability/alignment/align-fail.stderr
new file mode 100644
index 00000000000..59246fb1b03
--- /dev/null
+++ b/tests/ui/transmutability/alignment/align-fail.stderr
@@ -0,0 +1,30 @@
+error[E0277]: `&[u8; 0]` cannot be safely transmuted into `&[u16; 0]` in the defining scope of `assert::Context`
+  --> $DIR/align-fail.rs:22:55
+   |
+LL | ...tatic [u8; 0], &'static [u16; 0]>();
+   |                   ^^^^^^^^^^^^^^^^^ The minimum alignment of `&[u8; 0]` (1) should be greater than that of `&[u16; 0]` (2)
+   |
+note: required by a bound in `is_maybe_transmutable`
+  --> $DIR/align-fail.rs:10:14
+   |
+LL |       pub fn is_maybe_transmutable<Src, Dst>()
+   |              --------------------- required by a bound in this function
+LL |       where
+LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
+   |  ______________^
+LL | |             Assume {
+LL | |                 alignment: false,
+LL | |                 lifetimes: true,
+...  |
+LL | |             }
+LL | |         }>
+   | |__________^ required by this bound in `is_maybe_transmutable`
+help: consider removing the leading `&`-reference
+   |
+LL -     assert::is_maybe_transmutable::<&'static [u8; 0], &'static [u16; 0]>();
+LL +     assert::is_maybe_transmutable::<&'static [u8; 0], [u16; 0]>();
+   |
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/transmutability/alignment/align-pass.rs b/tests/ui/transmutability/alignment/align-pass.rs
new file mode 100644
index 00000000000..62dc672eacb
--- /dev/null
+++ b/tests/ui/transmutability/alignment/align-pass.rs
@@ -0,0 +1,23 @@
+// check-pass
+#![feature(transmutability)]
+
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    pub struct Context;
+
+    pub fn is_maybe_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, Context, {
+            Assume {
+                alignment: false,
+                lifetimes: false,
+                safety: true,
+                validity: false,
+            }
+        }>
+    {}
+}
+
+fn main() {
+    assert::is_maybe_transmutable::<&'static [u16; 0], &'static [u8; 0]>();
+}
diff --git a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr
index 9877a6606a9..46cdaa92563 100644
--- a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr
+++ b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr
@@ -90,7 +90,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0i16` in the defining scop
   --> $DIR/primitive_reprs_should_have_correct_length.rs:72:44
    |
 LL |         assert::is_transmutable::<Smaller, Current, Context>();
-   |                                            ^^^^^^^ At least one value of `u8` isn't a bit-valid value of `V0i16`
+   |                                            ^^^^^^^ The size of `u8` is smaller than the size of `V0i16`
    |
 note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
@@ -134,7 +134,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0u16` in the defining scop
   --> $DIR/primitive_reprs_should_have_correct_length.rs:80:44
    |
 LL |         assert::is_transmutable::<Smaller, Current, Context>();
-   |                                            ^^^^^^^ At least one value of `u8` isn't a bit-valid value of `V0u16`
+   |                                            ^^^^^^^ The size of `u8` is smaller than the size of `V0u16`
    |
 note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
@@ -178,7 +178,7 @@ error[E0277]: `u16` cannot be safely transmuted into `V0i32` in the defining sco
   --> $DIR/primitive_reprs_should_have_correct_length.rs:96:44
    |
 LL |         assert::is_transmutable::<Smaller, Current, Context>();
-   |                                            ^^^^^^^ At least one value of `u16` isn't a bit-valid value of `V0i32`
+   |                                            ^^^^^^^ The size of `u16` is smaller than the size of `V0i32`
    |
 note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
@@ -222,7 +222,7 @@ error[E0277]: `u16` cannot be safely transmuted into `V0u32` in the defining sco
   --> $DIR/primitive_reprs_should_have_correct_length.rs:104:44
    |
 LL |         assert::is_transmutable::<Smaller, Current, Context>();
-   |                                            ^^^^^^^ At least one value of `u16` isn't a bit-valid value of `V0u32`
+   |                                            ^^^^^^^ The size of `u16` is smaller than the size of `V0u32`
    |
 note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
@@ -266,7 +266,7 @@ error[E0277]: `u32` cannot be safely transmuted into `V0i64` in the defining sco
   --> $DIR/primitive_reprs_should_have_correct_length.rs:120:44
    |
 LL |         assert::is_transmutable::<Smaller, Current, Context>();
-   |                                            ^^^^^^^ At least one value of `u32` isn't a bit-valid value of `V0i64`
+   |                                            ^^^^^^^ The size of `u32` is smaller than the size of `V0i64`
    |
 note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
@@ -310,7 +310,7 @@ error[E0277]: `u32` cannot be safely transmuted into `V0u64` in the defining sco
   --> $DIR/primitive_reprs_should_have_correct_length.rs:128:44
    |
 LL |         assert::is_transmutable::<Smaller, Current, Context>();
-   |                                            ^^^^^^^ At least one value of `u32` isn't a bit-valid value of `V0u64`
+   |                                            ^^^^^^^ The size of `u32` is smaller than the size of `V0u64`
    |
 note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
@@ -354,7 +354,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0isize` in the defining sc
   --> $DIR/primitive_reprs_should_have_correct_length.rs:144:44
    |
 LL |         assert::is_transmutable::<Smaller, Current, Context>();
-   |                                            ^^^^^^^ At least one value of `u8` isn't a bit-valid value of `V0isize`
+   |                                            ^^^^^^^ The size of `u8` is smaller than the size of `V0isize`
    |
 note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
@@ -398,7 +398,7 @@ error[E0277]: `u8` cannot be safely transmuted into `V0usize` in the defining sc
   --> $DIR/primitive_reprs_should_have_correct_length.rs:152:44
    |
 LL |         assert::is_transmutable::<Smaller, Current, Context>();
-   |                                            ^^^^^^^ At least one value of `u8` isn't a bit-valid value of `V0usize`
+   |                                            ^^^^^^^ The size of `u8` is smaller than the size of `V0usize`
    |
 note: required by a bound in `is_transmutable`
   --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14
diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs
index ebe34e13432..8d19cabc0f9 100644
--- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs
+++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.rs
@@ -18,5 +18,5 @@ 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>();
+    assert::is_transmutable::<Src, Dst, Context>(); //~ ERROR cannot be safely transmuted
 }
diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr
index 475e6f429f3..c2df398b8ff 100644
--- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr
+++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr
@@ -4,6 +4,22 @@ error[E0412]: cannot find type `Missing` in this scope
 LL |     #[repr(C)] struct Dst(Missing);
    |                           ^^^^^^^ not found in this scope
 
-error: aborting due to previous error
+error[E0277]: `Src` cannot be safely transmuted into `Dst` in the defining scope of `should_gracefully_handle_unknown_dst_field::Context`
+  --> $DIR/unknown_src_field.rs:21:36
+   |
+LL |     assert::is_transmutable::<Src, Dst, Context>();
+   |                                    ^^^ `Dst` has an unknown layout
+   |
+note: required by a bound in `is_transmutable`
+  --> $DIR/unknown_src_field.rs:13:14
+   |
+LL |     pub fn is_transmutable<Src, Dst, Context>()
+   |            --------------- required by a bound in this function
+LL |     where
+LL |         Dst: BikeshedIntrinsicFrom<Src, Context>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0412`.
+Some errors have detailed explanations: E0277, E0412.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/transmutability/primitives/bool-mut.rs b/tests/ui/transmutability/primitives/bool-mut.rs
new file mode 100644
index 00000000000..49dbe90e4b8
--- /dev/null
+++ b/tests/ui/transmutability/primitives/bool-mut.rs
@@ -0,0 +1,17 @@
+// check-fail
+//[next] compile-flags: -Ztrait-solver=next
+
+#![feature(transmutability)]
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    pub struct Context;
+
+    pub fn is_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
+    {}
+}
+
+fn main() {
+    assert::is_transmutable::<&'static mut bool, &'static mut u8>() //~ ERROR cannot be safely transmuted
+}
diff --git a/tests/ui/transmutability/primitives/bool-mut.stderr b/tests/ui/transmutability/primitives/bool-mut.stderr
new file mode 100644
index 00000000000..b36991e1c01
--- /dev/null
+++ b/tests/ui/transmutability/primitives/bool-mut.stderr
@@ -0,0 +1,18 @@
+error[E0277]: `u8` cannot be safely transmuted into `bool` in the defining scope of `assert::Context`
+  --> $DIR/bool-mut.rs:16:50
+   |
+LL |     assert::is_transmutable::<&'static mut bool, &'static mut u8>()
+   |                                                  ^^^^^^^^^^^^^^^ At least one value of `u8` isn't a bit-valid value of `bool`
+   |
+note: required by a bound in `is_transmutable`
+  --> $DIR/bool-mut.rs:11:14
+   |
+LL |     pub fn is_transmutable<Src, Dst>()
+   |            --------------- required by a bound in this function
+LL |     where
+LL |         Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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/tests/ui/transmutability/primitives/bool.current.stderr b/tests/ui/transmutability/primitives/bool.current.stderr
index 47c8438a251..4b3eb6c517d 100644
--- a/tests/ui/transmutability/primitives/bool.current.stderr
+++ b/tests/ui/transmutability/primitives/bool.current.stderr
@@ -1,11 +1,11 @@
 error[E0277]: `u8` cannot be safely transmuted into `bool` in the defining scope of `assert::Context`
-  --> $DIR/bool.rs:24:35
+  --> $DIR/bool.rs:21:35
    |
 LL |     assert::is_transmutable::<u8, bool>();
    |                                   ^^^^ At least one value of `u8` isn't a bit-valid value of `bool`
    |
 note: required by a bound in `is_transmutable`
-  --> $DIR/bool.rs:14:14
+  --> $DIR/bool.rs:11:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
diff --git a/tests/ui/transmutability/primitives/bool.next.stderr b/tests/ui/transmutability/primitives/bool.next.stderr
index 47c8438a251..4b3eb6c517d 100644
--- a/tests/ui/transmutability/primitives/bool.next.stderr
+++ b/tests/ui/transmutability/primitives/bool.next.stderr
@@ -1,11 +1,11 @@
 error[E0277]: `u8` cannot be safely transmuted into `bool` in the defining scope of `assert::Context`
-  --> $DIR/bool.rs:24:35
+  --> $DIR/bool.rs:21:35
    |
 LL |     assert::is_transmutable::<u8, bool>();
    |                                   ^^^^ At least one value of `u8` isn't a bit-valid value of `bool`
    |
 note: required by a bound in `is_transmutable`
-  --> $DIR/bool.rs:14:14
+  --> $DIR/bool.rs:11:14
    |
 LL |     pub fn is_transmutable<Src, Dst>()
    |            --------------- required by a bound in this function
diff --git a/tests/ui/transmutability/primitives/bool.rs b/tests/ui/transmutability/primitives/bool.rs
index de77cfc78aa..654e7b47ede 100644
--- a/tests/ui/transmutability/primitives/bool.rs
+++ b/tests/ui/transmutability/primitives/bool.rs
@@ -1,10 +1,7 @@
 // revisions: current next
 //[next] compile-flags: -Ztrait-solver=next
 
-#![crate_type = "lib"]
 #![feature(transmutability)]
-#![allow(dead_code)]
-#![allow(incomplete_features)]
 mod assert {
     use std::mem::{Assume, BikeshedIntrinsicFrom};
     pub struct Context;
@@ -20,7 +17,7 @@ mod assert {
     {}
 }
 
-fn contrast_with_u8() {
+fn main() {
     assert::is_transmutable::<u8, bool>(); //~ ERROR cannot be safely transmuted
     assert::is_maybe_transmutable::<u8, bool>();
     assert::is_transmutable::<bool, u8>();
diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.rs b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.rs
new file mode 100644
index 00000000000..a6e2889d3f2
--- /dev/null
+++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.rs
@@ -0,0 +1,25 @@
+// check-fail
+#![feature(transmutability)]
+
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    pub struct Context;
+
+    pub fn is_maybe_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, Context, {
+            Assume {
+                alignment: true,
+                lifetimes: false,
+                safety: true,
+                validity: false,
+            }
+        }>
+    {}
+}
+
+fn main() {
+    #[repr(C)] struct A(bool, &'static A);
+    #[repr(C)] struct B(u8, &'static B);
+    assert::is_maybe_transmutable::<&'static A, &'static mut B>(); //~ ERROR cannot be safely transmuted
+}
diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr
new file mode 100644
index 00000000000..4b4d6ad0298
--- /dev/null
+++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible-mut.stderr
@@ -0,0 +1,25 @@
+error[E0277]: `&A` cannot be safely transmuted into `&mut B` in the defining scope of `assert::Context`
+  --> $DIR/recursive-wrapper-types-bit-compatible-mut.rs:24:49
+   |
+LL |     assert::is_maybe_transmutable::<&'static A, &'static mut B>();
+   |                                                 ^^^^^^^^^^^^^^ `&A` is a shared reference, but `&mut B` is a unique reference
+   |
+note: required by a bound in `is_maybe_transmutable`
+  --> $DIR/recursive-wrapper-types-bit-compatible-mut.rs:10:14
+   |
+LL |       pub fn is_maybe_transmutable<Src, Dst>()
+   |              --------------------- required by a bound in this function
+LL |       where
+LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
+   |  ______________^
+LL | |             Assume {
+LL | |                 alignment: true,
+LL | |                 lifetimes: false,
+...  |
+LL | |             }
+LL | |         }>
+   | |__________^ 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/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs
new file mode 100644
index 00000000000..3ea80173afa
--- /dev/null
+++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.rs
@@ -0,0 +1,26 @@
+// check-fail
+// FIXME(bryangarza): Change to check-pass when coinduction is supported for BikeshedIntrinsicFrom
+#![feature(transmutability)]
+
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    pub struct Context;
+
+    pub fn is_maybe_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, Context, {
+            Assume {
+                alignment: true,
+                lifetimes: false,
+                safety: true,
+                validity: false,
+            }
+        }>
+    {}
+}
+
+fn main() {
+    #[repr(C)] struct A(bool, &'static A);
+    #[repr(C)] struct B(u8, &'static B);
+    assert::is_maybe_transmutable::<&'static A, &'static B>(); //~ ERROR overflow evaluating the requirement
+}
diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.stderr b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.stderr
new file mode 100644
index 00000000000..fae332e6af9
--- /dev/null
+++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-compatible.stderr
@@ -0,0 +1,25 @@
+error[E0275]: overflow evaluating the requirement `B: BikeshedIntrinsicFrom<A, assert::Context, Assume { alignment: true, lifetimes: false, safety: true, validity: false }>`
+  --> $DIR/recursive-wrapper-types-bit-compatible.rs:25:5
+   |
+LL |     assert::is_maybe_transmutable::<&'static A, &'static B>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: required by a bound in `is_maybe_transmutable`
+  --> $DIR/recursive-wrapper-types-bit-compatible.rs:11:14
+   |
+LL |       pub fn is_maybe_transmutable<Src, Dst>()
+   |              --------------------- required by a bound in this function
+LL |       where
+LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
+   |  ______________^
+LL | |             Assume {
+LL | |                 alignment: true,
+LL | |                 lifetimes: false,
+...  |
+LL | |             }
+LL | |         }>
+   | |__________^ required by this bound in `is_maybe_transmutable`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.rs b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.rs
new file mode 100644
index 00000000000..e8582d2fd02
--- /dev/null
+++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.rs
@@ -0,0 +1,25 @@
+// check-fail
+#![feature(transmutability)]
+
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    pub struct Context;
+
+    pub fn is_maybe_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, Context, {
+            Assume {
+                alignment: true,
+                lifetimes: false,
+                safety: true,
+                validity: false,
+            }
+        }>
+    {}
+}
+
+fn main() {
+    #[repr(C)] struct A(bool, &'static A);
+    #[repr(C)] struct B(u8, &'static B);
+    assert::is_maybe_transmutable::<&'static B, &'static A>(); //~ ERROR cannot be safely transmuted
+}
diff --git a/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr
new file mode 100644
index 00000000000..ecfe4865962
--- /dev/null
+++ b/tests/ui/transmutability/references/recursive-wrapper-types-bit-incompatible.stderr
@@ -0,0 +1,25 @@
+error[E0277]: `B` cannot be safely transmuted into `A` in the defining scope of `assert::Context`
+  --> $DIR/recursive-wrapper-types-bit-incompatible.rs:24:49
+   |
+LL |     assert::is_maybe_transmutable::<&'static B, &'static A>();
+   |                                                 ^^^^^^^^^^ At least one value of `B` isn't a bit-valid value of `A`
+   |
+note: required by a bound in `is_maybe_transmutable`
+  --> $DIR/recursive-wrapper-types-bit-incompatible.rs:10:14
+   |
+LL |       pub fn is_maybe_transmutable<Src, Dst>()
+   |              --------------------- required by a bound in this function
+LL |       where
+LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
+   |  ______________^
+LL | |             Assume {
+LL | |                 alignment: true,
+LL | |                 lifetimes: false,
+...  |
+LL | |             }
+LL | |         }>
+   | |__________^ 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/tests/ui/transmutability/references/recursive-wrapper-types.rs b/tests/ui/transmutability/references/recursive-wrapper-types.rs
new file mode 100644
index 00000000000..59d1ad84a5d
--- /dev/null
+++ b/tests/ui/transmutability/references/recursive-wrapper-types.rs
@@ -0,0 +1,27 @@
+// check-fail
+// FIXME(bryangarza): Change to check-pass when coinduction is supported for BikeshedIntrinsicFrom
+#![feature(transmutability)]
+
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    pub struct Context;
+
+    pub fn is_maybe_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, Context, {
+            Assume {
+                alignment: true,
+                lifetimes: false,
+                safety: true,
+                validity: false,
+            }
+        }>
+    {}
+}
+
+fn main() {
+    #[repr(C)] struct A(&'static B);
+    #[repr(C)] struct B(&'static A);
+    assert::is_maybe_transmutable::<&'static A, &'static B>(); //~ overflow evaluating the requirement
+    assert::is_maybe_transmutable::<&'static B, &'static A>();
+}
diff --git a/tests/ui/transmutability/references.next.stderr b/tests/ui/transmutability/references/recursive-wrapper-types.stderr
index 819c9b92bc8..35a60c22643 100644
--- a/tests/ui/transmutability/references.next.stderr
+++ b/tests/ui/transmutability/references/recursive-wrapper-types.stderr
@@ -1,11 +1,11 @@
-error[E0277]: `&Unit` cannot be safely transmuted into `&Unit` in the defining scope of `assert::Context`
-  --> $DIR/references.rs:29:52
+error[E0275]: overflow evaluating the requirement `A: BikeshedIntrinsicFrom<B, assert::Context, Assume { alignment: true, lifetimes: false, safety: true, validity: false }>`
+  --> $DIR/recursive-wrapper-types.rs:25:5
    |
-LL |     assert::is_maybe_transmutable::<&'static Unit, &'static Unit>();
-   |                                                    ^^^^^^^^^^^^^ `&Unit` does not have a well-specified layout
+LL |     assert::is_maybe_transmutable::<&'static A, &'static B>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/references.rs:16:14
+  --> $DIR/recursive-wrapper-types.rs:11:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
@@ -14,7 +14,7 @@ LL |           Dst: BikeshedIntrinsicFrom<Src, Context, {
    |  ______________^
 LL | |             Assume {
 LL | |                 alignment: true,
-LL | |                 lifetimes: true,
+LL | |                 lifetimes: false,
 ...  |
 LL | |             }
 LL | |         }>
@@ -22,4 +22,4 @@ LL | |         }>
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/transmutability/references/u8-to-unit.rs b/tests/ui/transmutability/references/u8-to-unit.rs
new file mode 100644
index 00000000000..8b37492bd6b
--- /dev/null
+++ b/tests/ui/transmutability/references/u8-to-unit.rs
@@ -0,0 +1,24 @@
+// check-pass
+#![feature(transmutability)]
+
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    pub struct Context;
+
+    pub fn is_maybe_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, Context, {
+            Assume {
+                alignment: false,
+                lifetimes: true,
+                safety: true,
+                validity: false,
+            }
+        }>
+    {}
+}
+
+fn main() {
+    #[repr(C)] struct Unit;
+    assert::is_maybe_transmutable::<&'static u8, &'static Unit>();
+}
diff --git a/tests/ui/transmutability/references.rs b/tests/ui/transmutability/references/unit-to-itself.rs
index 8c2b25ebba1..04a7e16d7cc 100644
--- a/tests/ui/transmutability/references.rs
+++ b/tests/ui/transmutability/references/unit-to-itself.rs
@@ -1,11 +1,5 @@
-// revisions: current next
-//[next] compile-flags: -Ztrait-solver=next
-
-//! Transmutations involving references are not yet supported.
-
-#![crate_type = "lib"]
+// check-pass
 #![feature(transmutability)]
-#![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
     use std::mem::{Assume, BikeshedIntrinsicFrom};
@@ -16,15 +10,15 @@ mod assert {
         Dst: BikeshedIntrinsicFrom<Src, Context, {
             Assume {
                 alignment: true,
-                lifetimes: true,
+                lifetimes: false,
                 safety: true,
-                validity: true,
+                validity: false,
             }
         }>
     {}
 }
 
-fn not_yet_implemented() {
+fn main() {
     #[repr(C)] struct Unit;
-    assert::is_maybe_transmutable::<&'static Unit, &'static Unit>(); //~ ERROR cannot be safely transmuted
+    assert::is_maybe_transmutable::<&'static Unit, &'static Unit>();
 }
diff --git a/tests/ui/transmutability/references/unit-to-u8.rs b/tests/ui/transmutability/references/unit-to-u8.rs
new file mode 100644
index 00000000000..eff516e9a96
--- /dev/null
+++ b/tests/ui/transmutability/references/unit-to-u8.rs
@@ -0,0 +1,24 @@
+// check-fail
+#![feature(transmutability)]
+
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+    pub struct Context;
+
+    pub fn is_maybe_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, Context, {
+            Assume {
+                alignment: true,
+                lifetimes: true,
+                safety: true,
+                validity: false,
+            }
+        }>
+    {}
+}
+
+fn main() {
+    #[repr(C)] struct Unit;
+    assert::is_maybe_transmutable::<&'static Unit, &'static u8>(); //~ ERROR cannot be safely transmuted
+}
diff --git a/tests/ui/transmutability/references.current.stderr b/tests/ui/transmutability/references/unit-to-u8.stderr
index 819c9b92bc8..f2b72357f79 100644
--- a/tests/ui/transmutability/references.current.stderr
+++ b/tests/ui/transmutability/references/unit-to-u8.stderr
@@ -1,11 +1,11 @@
-error[E0277]: `&Unit` cannot be safely transmuted into `&Unit` in the defining scope of `assert::Context`
-  --> $DIR/references.rs:29:52
+error[E0277]: `Unit` cannot be safely transmuted into `u8` in the defining scope of `assert::Context`
+  --> $DIR/unit-to-u8.rs:23:52
    |
-LL |     assert::is_maybe_transmutable::<&'static Unit, &'static Unit>();
-   |                                                    ^^^^^^^^^^^^^ `&Unit` does not have a well-specified layout
+LL |     assert::is_maybe_transmutable::<&'static Unit, &'static u8>();
+   |                                                    ^^^^^^^^^^^ The size of `Unit` is smaller than the size of `u8`
    |
 note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/references.rs:16:14
+  --> $DIR/unit-to-u8.rs:10:14
    |
 LL |       pub fn is_maybe_transmutable<Src, Dst>()
    |              --------------------- required by a bound in this function
diff --git a/tests/ui/transmutability/region-infer.stderr b/tests/ui/transmutability/region-infer.stderr
index d6b65e9e4a0..307d0dfe50d 100644
--- a/tests/ui/transmutability/region-infer.stderr
+++ b/tests/ui/transmutability/region-infer.stderr
@@ -2,7 +2,7 @@ error[E0277]: `()` cannot be safely transmuted into `W<'_>` in the defining scop
   --> $DIR/region-infer.rs:20:5
    |
 LL |     test();
-   |     ^^^^ `W<'_>` does not have a well-specified layout
+   |     ^^^^ The size of `()` is smaller than the size of `W<'_>`
    |
 note: required by a bound in `test`
   --> $DIR/region-infer.rs:11:12