about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/codegen/powerpc64le-struct-align-128.rs93
-rw-r--r--tests/codegen/step_by-overflow-checks.rs26
-rw-r--r--tests/ui/async-await/async-closures/mut-ref-reborrow.rs27
-rw-r--r--tests/ui/async-await/async-closures/overlapping-projs.rs27
-rw-r--r--tests/ui/async-await/async-closures/overlapping-projs.run.stdout1
-rw-r--r--tests/ui/async-await/async-closures/precise-captures.call.run.stdout29
-rw-r--r--tests/ui/async-await/async-closures/precise-captures.call_once.run.stdout29
-rw-r--r--tests/ui/async-await/async-closures/precise-captures.force_once.run.stdout29
-rw-r--r--tests/ui/async-await/async-closures/precise-captures.rs157
-rw-r--r--tests/ui/sanitizer/cfi-fn-ptr.rs (renamed from tests/ui/sanitizer/cfi-method-fn-ptr-cast.rs)8
-rw-r--r--tests/ui/traits/pred-known-to-hold-modulo-regions-unsized-tail.rs244
-rw-r--r--tests/ui/transmutability/arrays/huge-len.stderr4
-rw-r--r--tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr12
-rw-r--r--tests/ui/transmutability/enums/niche_optimization.rs156
-rw-r--r--tests/ui/transmutability/enums/repr/padding_differences.rs80
-rw-r--r--tests/ui/transmutability/enums/repr/should_handle_all.rs (renamed from tests/ui/transmutability/enums/repr/should_require_well_defined_layout.rs)21
-rw-r--r--tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr135
-rw-r--r--tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr2
-rw-r--r--tests/ui/transmutability/maybeuninit.rs43
-rw-r--r--tests/ui/transmutability/maybeuninit.stderr18
-rw-r--r--tests/ui/transmutability/references/unsafecell.rs47
-rw-r--r--tests/ui/transmutability/references/unsafecell.stderr33
-rw-r--r--tests/ui/transmutability/structs/repr/should_handle_all.rs (renamed from tests/ui/transmutability/structs/repr/should_require_well_defined_layout.rs)29
-rw-r--r--tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr267
-rw-r--r--tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.rs1
-rw-r--r--tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr19
-rw-r--r--tests/ui/transmutability/transmute-padding-ice.rs9
-rw-r--r--tests/ui/transmutability/transmute-padding-ice.stderr22
-rw-r--r--tests/ui/transmutability/uninhabited.rs71
-rw-r--r--tests/ui/transmutability/uninhabited.stderr86
-rw-r--r--tests/ui/transmutability/unions/repr/should_handle_align.rs4
-rw-r--r--tests/ui/transmutability/unions/repr/should_handle_all.rs (renamed from tests/ui/transmutability/unions/repr/should_require_well_defined_layout.rs)24
-rw-r--r--tests/ui/transmutability/unions/repr/should_handle_packed.rs1
-rw-r--r--tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr47
34 files changed, 1279 insertions, 522 deletions
diff --git a/tests/codegen/powerpc64le-struct-align-128.rs b/tests/codegen/powerpc64le-struct-align-128.rs
new file mode 100644
index 00000000000..0096c6d3138
--- /dev/null
+++ b/tests/codegen/powerpc64le-struct-align-128.rs
@@ -0,0 +1,93 @@
+// Test that structs aligned to 128 bits are passed with the correct ABI on powerpc64le.
+// This is similar to aarch64-struct-align-128.rs, but for ppc.
+
+//@ compile-flags: --target powerpc64le-unknown-linux-gnu
+//@ needs-llvm-components: powerpc
+
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_core]
+
+#[lang="sized"]
+trait Sized { }
+#[lang="freeze"]
+trait Freeze { }
+#[lang="copy"]
+trait Copy { }
+
+#[repr(C)]
+pub struct Align8 {
+    pub a: u64,
+    pub b: u64,
+}
+
+#[repr(transparent)]
+pub struct Transparent8 {
+    a: Align8
+}
+
+#[repr(C)]
+pub struct Wrapped8 {
+    a: Align8,
+}
+
+extern "C" {
+    // CHECK: declare void @test_8([2 x i64], [2 x i64], [2 x i64])
+    fn test_8(a: Align8, b: Transparent8, c: Wrapped8);
+}
+
+#[repr(C)]
+#[repr(align(16))]
+pub struct Align16 {
+    pub a: u64,
+    pub b: u64,
+}
+
+#[repr(transparent)]
+pub struct Transparent16 {
+    a: Align16
+}
+
+#[repr(C)]
+pub struct Wrapped16 {
+    pub a: Align16,
+}
+
+extern "C" {
+    // It's important that this produces [1 x i128]  rather than just i128!
+    // CHECK: declare void @test_16([1 x i128], [1 x i128], [1 x i128])
+    fn test_16(a: Align16, b: Transparent16, c: Wrapped16);
+}
+
+#[repr(C)]
+#[repr(align(32))]
+pub struct Align32 {
+    pub a: u64,
+    pub b: u64,
+    pub c: u64,
+}
+
+#[repr(transparent)]
+pub struct Transparent32 {
+    a: Align32
+}
+
+#[repr(C)]
+pub struct Wrapped32 {
+    pub a: Align32,
+}
+
+extern "C" {
+    // CHECK: declare void @test_32([2 x i128], [2 x i128], [2 x i128])
+    fn test_32(a: Align32, b: Transparent32, c: Wrapped32);
+}
+
+pub unsafe fn main(
+    a1: Align8, a2: Transparent8, a3: Wrapped8,
+    b1: Align16, b2: Transparent16, b3: Wrapped16,
+    c1: Align32, c2: Transparent32, c3: Wrapped32,
+) {
+    test_8(a1, a2, a3);
+    test_16(b1, b2, b3);
+    test_32(c1, c2, c3);
+}
diff --git a/tests/codegen/step_by-overflow-checks.rs b/tests/codegen/step_by-overflow-checks.rs
new file mode 100644
index 00000000000..43e8514a8b7
--- /dev/null
+++ b/tests/codegen/step_by-overflow-checks.rs
@@ -0,0 +1,26 @@
+//@ compile-flags: -O
+
+#![crate_type = "lib"]
+
+use std::iter::StepBy;
+use std::slice::Iter;
+
+// The constructor for `StepBy` ensures we can never end up needing to do zero
+// checks on denominators, so check that the code isn't emitting panic paths.
+
+// CHECK-LABEL: @step_by_len_std
+#[no_mangle]
+pub fn step_by_len_std(x: &StepBy<Iter<i32>>) -> usize {
+    // CHECK-NOT: div_by_zero
+    // CHECK: udiv
+    // CHECK-NOT: div_by_zero
+    x.len()
+}
+
+// CHECK-LABEL: @step_by_len_naive
+#[no_mangle]
+pub fn step_by_len_naive(x: Iter<i32>, step_minus_one: usize) -> usize {
+    // CHECK: udiv
+    // CHECK: call{{.+}}div_by_zero
+    x.len() / (step_minus_one + 1)
+}
diff --git a/tests/ui/async-await/async-closures/mut-ref-reborrow.rs b/tests/ui/async-await/async-closures/mut-ref-reborrow.rs
new file mode 100644
index 00000000000..9f2cbd7ce1c
--- /dev/null
+++ b/tests/ui/async-await/async-closures/mut-ref-reborrow.rs
@@ -0,0 +1,27 @@
+//@ aux-build:block-on.rs
+//@ run-pass
+//@ check-run-results
+//@ revisions: e2021 e2018
+//@[e2018] edition:2018
+//@[e2021] edition:2021
+
+#![feature(async_closure)]
+
+extern crate block_on;
+
+async fn call_once(f: impl async FnOnce()) { f().await; }
+
+pub async fn async_closure(x: &mut i32) {
+    let c = async move || {
+        *x += 1;
+    };
+    call_once(c).await;
+}
+
+fn main() {
+    block_on::block_on(async {
+        let mut x = 0;
+        async_closure(&mut x).await;
+        assert_eq!(x, 1);
+    });
+}
diff --git a/tests/ui/async-await/async-closures/overlapping-projs.rs b/tests/ui/async-await/async-closures/overlapping-projs.rs
new file mode 100644
index 00000000000..6dd00b16103
--- /dev/null
+++ b/tests/ui/async-await/async-closures/overlapping-projs.rs
@@ -0,0 +1,27 @@
+//@ aux-build:block-on.rs
+//@ edition:2021
+//@ run-pass
+//@ check-run-results
+
+#![feature(async_closure)]
+
+extern crate block_on;
+
+async fn call_once(f: impl async FnOnce()) {
+    f().await;
+}
+
+async fn async_main() {
+    let x = &mut 0;
+    let y = &mut 0;
+    let c = async || {
+        *x = 1;
+        *y = 2;
+    };
+    call_once(c).await;
+    println!("{x} {y}");
+}
+
+fn main() {
+    block_on::block_on(async_main());
+}
diff --git a/tests/ui/async-await/async-closures/overlapping-projs.run.stdout b/tests/ui/async-await/async-closures/overlapping-projs.run.stdout
new file mode 100644
index 00000000000..8d04f961a03
--- /dev/null
+++ b/tests/ui/async-await/async-closures/overlapping-projs.run.stdout
@@ -0,0 +1 @@
+1 2
diff --git a/tests/ui/async-await/async-closures/precise-captures.call.run.stdout b/tests/ui/async-await/async-closures/precise-captures.call.run.stdout
new file mode 100644
index 00000000000..6062556837c
--- /dev/null
+++ b/tests/ui/async-await/async-closures/precise-captures.call.run.stdout
@@ -0,0 +1,29 @@
+after call
+after await
+fixed
+uncaptured
+
+after call
+after await
+fixed
+uncaptured
+
+after call
+after await
+fixed
+uncaptured
+
+after call
+after await
+fixed
+untouched
+
+after call
+drop first
+after await
+uncaptured
+
+after call
+drop first
+after await
+uncaptured
diff --git a/tests/ui/async-await/async-closures/precise-captures.call_once.run.stdout b/tests/ui/async-await/async-closures/precise-captures.call_once.run.stdout
new file mode 100644
index 00000000000..ddb02d47600
--- /dev/null
+++ b/tests/ui/async-await/async-closures/precise-captures.call_once.run.stdout
@@ -0,0 +1,29 @@
+after call
+after await
+fixed
+uncaptured
+
+after call
+after await
+fixed
+uncaptured
+
+after call
+fixed
+after await
+uncaptured
+
+after call
+after await
+fixed
+untouched
+
+after call
+drop first
+after await
+uncaptured
+
+after call
+drop first
+after await
+uncaptured
diff --git a/tests/ui/async-await/async-closures/precise-captures.force_once.run.stdout b/tests/ui/async-await/async-closures/precise-captures.force_once.run.stdout
new file mode 100644
index 00000000000..ddb02d47600
--- /dev/null
+++ b/tests/ui/async-await/async-closures/precise-captures.force_once.run.stdout
@@ -0,0 +1,29 @@
+after call
+after await
+fixed
+uncaptured
+
+after call
+after await
+fixed
+uncaptured
+
+after call
+fixed
+after await
+uncaptured
+
+after call
+after await
+fixed
+untouched
+
+after call
+drop first
+after await
+uncaptured
+
+after call
+drop first
+after await
+uncaptured
diff --git a/tests/ui/async-await/async-closures/precise-captures.rs b/tests/ui/async-await/async-closures/precise-captures.rs
new file mode 100644
index 00000000000..e82dd1dbaf0
--- /dev/null
+++ b/tests/ui/async-await/async-closures/precise-captures.rs
@@ -0,0 +1,157 @@
+//@ aux-build:block-on.rs
+//@ edition:2021
+//@ run-pass
+//@ check-run-results
+//@ revisions: call call_once force_once
+
+// call - Call the closure regularly.
+// call_once - Call the closure w/ `async FnOnce`, so exercising the by_move shim.
+// force_once - Force the closure mode to `FnOnce`, so exercising what was fixed
+//   in <https://github.com/rust-lang/rust/pull/123350>.
+
+#![feature(async_closure)]
+#![allow(unused_mut)]
+
+extern crate block_on;
+
+#[cfg(any(call, force_once))]
+macro_rules! call {
+    ($c:expr) => { ($c)() }
+}
+
+#[cfg(call_once)]
+async fn call_once(f: impl async FnOnce()) {
+    f().await
+}
+
+#[cfg(call_once)]
+macro_rules! call {
+    ($c:expr) => { call_once($c) }
+}
+
+#[cfg(not(force_once))]
+macro_rules! guidance {
+    ($c:expr) => { $c }
+}
+
+#[cfg(force_once)]
+fn infer_fnonce(c: impl async FnOnce()) -> impl async FnOnce() { c }
+
+#[cfg(force_once)]
+macro_rules! guidance {
+    ($c:expr) => { infer_fnonce($c) }
+}
+
+#[derive(Debug)]
+struct Drop(&'static str);
+
+impl std::ops::Drop for Drop {
+    fn drop(&mut self) {
+        println!("{}", self.0);
+    }
+}
+
+struct S {
+    a: i32,
+    b: Drop,
+    c: Drop,
+}
+
+async fn async_main() {
+    // Precise capture struct
+    {
+        let mut s = S { a: 1, b: Drop("fix me up"), c: Drop("untouched") };
+        let mut c = guidance!(async || {
+            s.a = 2;
+            let w = &mut s.b;
+            w.0 = "fixed";
+        });
+        s.c.0 = "uncaptured";
+        let fut = call!(c);
+        println!("after call");
+        fut.await;
+        println!("after await");
+    }
+    println!();
+
+    // Precise capture &mut struct
+    {
+        let s = &mut S { a: 1, b: Drop("fix me up"), c: Drop("untouched") };
+        let mut c = guidance!(async || {
+            s.a = 2;
+            let w = &mut s.b;
+            w.0 = "fixed";
+        });
+        s.c.0 = "uncaptured";
+        let fut = call!(c);
+        println!("after call");
+        fut.await;
+        println!("after await");
+    }
+    println!();
+
+    // Precise capture struct by move
+    {
+        let mut s = S { a: 1, b: Drop("fix me up"), c: Drop("untouched") };
+        let mut c = guidance!(async move || {
+            s.a = 2;
+            let w = &mut s.b;
+            w.0 = "fixed";
+        });
+        s.c.0 = "uncaptured";
+        let fut = call!(c);
+        println!("after call");
+        fut.await;
+        println!("after await");
+    }
+    println!();
+
+    // Precise capture &mut struct by move
+    {
+        let s = &mut S { a: 1, b: Drop("fix me up"), c: Drop("untouched") };
+        let mut c = guidance!(async move || {
+            s.a = 2;
+            let w = &mut s.b;
+            w.0 = "fixed";
+        });
+        // `s` is still captured fully as `&mut S`.
+        let fut = call!(c);
+        println!("after call");
+        fut.await;
+        println!("after await");
+    }
+    println!();
+
+    // Precise capture struct, consume field
+    {
+        let mut s = S { a: 1, b: Drop("drop first"), c: Drop("untouched") };
+        let c = guidance!(async move || {
+            // s.a = 2; // FIXME(async_closures): Figure out why this fails
+            drop(s.b);
+        });
+        s.c.0 = "uncaptured";
+        let fut = call!(c);
+        println!("after call");
+        fut.await;
+        println!("after await");
+    }
+    println!();
+
+    // Precise capture struct by move, consume field
+    {
+        let mut s = S { a: 1, b: Drop("drop first"), c: Drop("untouched") };
+        let c = guidance!(async move || {
+            // s.a = 2; // FIXME(async_closures): Figure out why this fails
+            drop(s.b);
+        });
+        s.c.0 = "uncaptured";
+        let fut = call!(c);
+        println!("after call");
+        fut.await;
+        println!("after await");
+    }
+}
+
+fn main() {
+    block_on::block_on(async_main());
+}
diff --git a/tests/ui/sanitizer/cfi-method-fn-ptr-cast.rs b/tests/ui/sanitizer/cfi-fn-ptr.rs
index 8f79de11748..505b4b8e7f0 100644
--- a/tests/ui/sanitizer/cfi-method-fn-ptr-cast.rs
+++ b/tests/ui/sanitizer/cfi-fn-ptr.rs
@@ -1,4 +1,4 @@
-// Verifies that casting a method to a function pointer works.
+// Verifies that casting to a function pointer works.
 
 //@ revisions: cfi kcfi
 // FIXME(#122848) Remove only-linux once OSX CFI binaries work
@@ -46,6 +46,8 @@ impl Trait1 for Type1 {
     fn foo(&self) {}
 }
 
+fn foo<T>(_: &T) {}
+
 fn main() {
     let type1 = Type1 {};
     let f = <Type1 as Trait1>::foo;
@@ -53,5 +55,7 @@ fn main() {
     // Check again with different optimization barriers
     S2 { f: <S as Foo>::foo }.foo(&S);
     // Check mismatched #[track_caller]
-    S2 { f: <S as Foo>::bar }.foo(&S)
+    S2 { f: <S as Foo>::bar }.foo(&S);
+    // Check non-method functions
+    S2 { f: foo }.foo(&S)
 }
diff --git a/tests/ui/traits/pred-known-to-hold-modulo-regions-unsized-tail.rs b/tests/ui/traits/pred-known-to-hold-modulo-regions-unsized-tail.rs
new file mode 100644
index 00000000000..4e8c19d600d
--- /dev/null
+++ b/tests/ui/traits/pred-known-to-hold-modulo-regions-unsized-tail.rs
@@ -0,0 +1,244 @@
+// This is a non-regression test for issues #108721 and its duplicate #123275 (hopefully, because
+// the test is still convoluted and the ICE is fiddly).
+//
+// `pred_known_to_hold_modulo_regions` prevented "unexpected unsized tail" ICEs with warp/hyper but
+// was unknowingly removed in #120463.
+
+//@ build-pass: the ICE happened in codegen
+
+use std::future::Future;
+trait TryFuture: Future {
+    type Ok;
+}
+impl<F, T> TryFuture for F
+where
+    F: ?Sized + Future<Output = Option<T>>,
+{
+    type Ok = T;
+}
+trait Executor {}
+struct Exec {}
+trait HttpBody {
+    type Data;
+}
+trait ConnStreamExec<F> {}
+impl<F> ConnStreamExec<F> for Exec where H2Stream<F>: Send {}
+impl<E, F> ConnStreamExec<F> for E where E: Executor {}
+struct H2Stream<F> {
+    _fut: F,
+}
+trait NewSvcExec<S, E, W: Watcher<S, E>> {
+    fn execute_new_svc(&mut self, _fut: NewSvcTask<S, E, W>) {
+        unimplemented!()
+    }
+}
+impl<S, E, W> NewSvcExec<S, E, W> for Exec where W: Watcher<S, E> {}
+trait Watcher<S, E> {
+    type Future;
+}
+struct NoopWatcher;
+impl<S, E> Watcher<S, E> for NoopWatcher
+where
+    S: HttpService,
+    E: ConnStreamExec<S::Future>,
+{
+    type Future = Option<<<S as HttpService>::ResBody as HttpBody>::Data>;
+}
+trait Service<Request> {
+    type Response;
+    type Future;
+}
+trait HttpService {
+    type ResBody: HttpBody;
+    type Future;
+}
+struct Body {}
+impl HttpBody for Body {
+    type Data = String;
+}
+impl<S> HttpService for S
+where
+    S: Service<(), Response = ()>,
+{
+    type ResBody = Body;
+    type Future = S::Future;
+}
+trait MakeServiceRef<Target> {
+    type ResBody;
+    type Service: HttpService<ResBody = Self::ResBody>;
+}
+impl<T, Target, S, F> MakeServiceRef<Target> for T
+where
+    T: for<'a> Service<&'a Target, Response = S, Future = F>,
+    S: HttpService,
+{
+    type Service = S;
+    type ResBody = S::ResBody;
+}
+fn make_service_fn<F, Target, Ret>(_f: F) -> MakeServiceFn<F>
+where
+    F: FnMut(&Target) -> Ret,
+    Ret: Future,
+{
+    unimplemented!()
+}
+struct MakeServiceFn<F> {
+    _func: F,
+}
+impl<'t, F, Ret, Target, Svc> Service<&'t Target> for MakeServiceFn<F>
+where
+    F: FnMut(&Target) -> Ret,
+    Ret: Future<Output = Option<Svc>>,
+{
+    type Response = Svc;
+    type Future = Option<()>;
+}
+struct AddrIncoming {}
+struct Server<I, S, E> {
+    _incoming: I,
+    _make_service: S,
+    _protocol: E,
+}
+impl<I, S, E, B> Server<I, S, E>
+where
+    S: MakeServiceRef<(), ResBody = B>,
+    B: HttpBody,
+    E: ConnStreamExec<<S::Service as HttpService>::Future>,
+    E: NewSvcExec<S::Service, E, NoopWatcher>,
+{
+    fn serve(&mut self) {
+        let fut = NewSvcTask::new();
+        self._protocol.execute_new_svc(fut);
+    }
+}
+fn serve<S>(_make_service: S) -> Server<AddrIncoming, S, Exec> {
+    unimplemented!()
+}
+struct NewSvcTask<S, E, W: Watcher<S, E>> {
+    _state: State<S, E, W>,
+}
+struct State<S, E, W: Watcher<S, E>> {
+    _fut: W::Future,
+}
+impl<S, E, W: Watcher<S, E>> NewSvcTask<S, E, W> {
+    fn new() -> Self {
+        unimplemented!()
+    }
+}
+trait Filter {
+    type Extract;
+    type Future;
+    fn map<F>(self, _fun: F) -> MapFilter<Self, F>
+    where
+        Self: Sized,
+    {
+        unimplemented!()
+    }
+    fn wrap_with<W>(self, _wrapper: W) -> W::Wrapped
+    where
+        Self: Sized,
+        W: Wrap<Self>,
+    {
+        unimplemented!()
+    }
+}
+fn service<F>(_filter: F) -> FilteredService<F>
+where
+    F: Filter,
+{
+    unimplemented!()
+}
+struct FilteredService<F> {
+    _filter: F,
+}
+impl<F> Service<()> for FilteredService<F>
+where
+    F: Filter,
+{
+    type Response = ();
+    type Future = FilteredFuture<F::Future>;
+}
+struct FilteredFuture<F> {
+    _fut: F,
+}
+struct MapFilter<T, F> {
+    _filter: T,
+    _func: F,
+}
+impl<T, F> Filter for MapFilter<T, F>
+where
+    T: Filter,
+    F: Func<T::Extract>,
+{
+    type Extract = F::Output;
+    type Future = MapFilterFuture<T, F>;
+}
+struct MapFilterFuture<T: Filter, F> {
+    _extract: T::Future,
+    _func: F,
+}
+trait Wrap<F> {
+    type Wrapped;
+}
+fn make_filter_fn<F, U>(_func: F) -> FilterFn<F>
+where
+    F: Fn() -> U,
+{
+    unimplemented!()
+}
+struct FilterFn<F> {
+    _func: F,
+}
+impl<F, U> Filter for FilterFn<F>
+where
+    F: Fn() -> U,
+    U: TryFuture,
+    U::Ok: Send,
+{
+    type Extract = U::Ok;
+    type Future = Option<U>;
+}
+fn trace<F>(_func: F) -> Trace<F>
+where
+    F: Fn(),
+{
+    unimplemented!()
+}
+struct Trace<F> {
+    _func: F,
+}
+impl<FN, F> Wrap<F> for Trace<FN> {
+    type Wrapped = WithTrace<FN, F>;
+}
+struct WithTrace<FN, F> {
+    _filter: F,
+    _trace: FN,
+}
+impl<FN, F> Filter for WithTrace<FN, F>
+where
+    F: Filter,
+{
+    type Extract = ();
+    type Future = (F::Future, fn(F::Extract));
+}
+trait Func<Args> {
+    type Output;
+}
+impl<F, R> Func<()> for F
+where
+    F: Fn() -> R,
+{
+    type Output = R;
+}
+fn main() {
+    let make_service = make_service_fn(|_| {
+        let tracer = trace(|| unimplemented!());
+        let filter = make_filter_fn(|| std::future::ready(Some(())))
+            .map(|| "Hello, world")
+            .wrap_with(tracer);
+        let svc = service(filter);
+        std::future::ready(Some(svc))
+    });
+    let mut server = serve(make_service);
+    server.serve();
+}
diff --git a/tests/ui/transmutability/arrays/huge-len.stderr b/tests/ui/transmutability/arrays/huge-len.stderr
index 37160c5c959..3fc652f47c1 100644
--- a/tests/ui/transmutability/arrays/huge-len.stderr
+++ b/tests/ui/transmutability/arrays/huge-len.stderr
@@ -2,7 +2,7 @@ error[E0277]: `()` cannot be safely transmuted into `ExplicitlyPadded`
   --> $DIR/huge-len.rs:21:41
    |
 LL |     assert::is_maybe_transmutable::<(), ExplicitlyPadded>();
-   |                                         ^^^^^^^^^^^^^^^^ values of the type `ExplicitlyPadded` are too big for the current architecture
+   |                                         ^^^^^^^^^^^^^^^^ analyzing the transmutability of `ExplicitlyPadded` is not yet supported
    |
 note: required by a bound in `is_maybe_transmutable`
   --> $DIR/huge-len.rs:8:14
@@ -17,7 +17,7 @@ error[E0277]: `ExplicitlyPadded` cannot be safely transmuted into `()`
   --> $DIR/huge-len.rs:24:55
    |
 LL |     assert::is_maybe_transmutable::<ExplicitlyPadded, ()>();
-   |                                                       ^^ values of the type `ExplicitlyPadded` are too big for the current architecture
+   |                                                       ^^ analyzing the transmutability of `ExplicitlyPadded` is not yet supported
    |
 note: required by a bound in `is_maybe_transmutable`
   --> $DIR/huge-len.rs:8:14
diff --git a/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr
index e486928a445..b4cd70142c4 100644
--- a/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr
+++ b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr
@@ -2,7 +2,7 @@ error[E0277]: `[String; 0]` cannot be safely transmuted into `()`
   --> $DIR/should_require_well_defined_layout.rs:25:52
    |
 LL |         assert::is_maybe_transmutable::<repr_rust, ()>();
-   |                                                    ^^ analyzing the transmutability of `[String; 0]` is not yet supported.
+   |                                                    ^^ analyzing the transmutability of `[String; 0]` is not yet supported
    |
 note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:12:14
@@ -23,7 +23,7 @@ error[E0277]: `u128` cannot be safely transmuted into `[String; 0]`
   --> $DIR/should_require_well_defined_layout.rs:26:47
    |
 LL |         assert::is_maybe_transmutable::<u128, repr_rust>();
-   |                                               ^^^^^^^^^ analyzing the transmutability of `[String; 0]` is not yet supported.
+   |                                               ^^^^^^^^^ analyzing the transmutability of `[String; 0]` is not yet supported
    |
 note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:12:14
@@ -44,7 +44,7 @@ error[E0277]: `[String; 1]` cannot be safely transmuted into `()`
   --> $DIR/should_require_well_defined_layout.rs:31:52
    |
 LL |         assert::is_maybe_transmutable::<repr_rust, ()>();
-   |                                                    ^^ analyzing the transmutability of `[String; 1]` is not yet supported.
+   |                                                    ^^ analyzing the transmutability of `[String; 1]` is not yet supported
    |
 note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:12:14
@@ -65,7 +65,7 @@ error[E0277]: `u128` cannot be safely transmuted into `[String; 1]`
   --> $DIR/should_require_well_defined_layout.rs:32:47
    |
 LL |         assert::is_maybe_transmutable::<u128, repr_rust>();
-   |                                               ^^^^^^^^^ analyzing the transmutability of `[String; 1]` is not yet supported.
+   |                                               ^^^^^^^^^ analyzing the transmutability of `[String; 1]` is not yet supported
    |
 note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:12:14
@@ -86,7 +86,7 @@ error[E0277]: `[String; 2]` cannot be safely transmuted into `()`
   --> $DIR/should_require_well_defined_layout.rs:37:52
    |
 LL |         assert::is_maybe_transmutable::<repr_rust, ()>();
-   |                                                    ^^ analyzing the transmutability of `[String; 2]` is not yet supported.
+   |                                                    ^^ analyzing the transmutability of `[String; 2]` is not yet supported
    |
 note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:12:14
@@ -107,7 +107,7 @@ error[E0277]: `u128` cannot be safely transmuted into `[String; 2]`
   --> $DIR/should_require_well_defined_layout.rs:38:47
    |
 LL |         assert::is_maybe_transmutable::<u128, repr_rust>();
-   |                                               ^^^^^^^^^ analyzing the transmutability of `[String; 2]` is not yet supported.
+   |                                               ^^^^^^^^^ analyzing the transmutability of `[String; 2]` is not yet supported
    |
 note: required by a bound in `is_maybe_transmutable`
   --> $DIR/should_require_well_defined_layout.rs:12:14
diff --git a/tests/ui/transmutability/enums/niche_optimization.rs b/tests/ui/transmutability/enums/niche_optimization.rs
new file mode 100644
index 00000000000..23f57ecad75
--- /dev/null
+++ b/tests/ui/transmutability/enums/niche_optimization.rs
@@ -0,0 +1,156 @@
+//@ check-pass
+//! Checks that niche optimizations are encoded correctly.
+#![crate_type = "lib"]
+#![feature(transmutability)]
+#![allow(dead_code, incomplete_features, non_camel_case_types)]
+
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+
+    pub fn is_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, {
+            Assume {
+                alignment: false,
+                lifetimes: false,
+                safety: true,
+                validity: false,
+            }
+        }>
+    {}
+
+    pub fn is_maybe_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, {
+            Assume {
+                alignment: false,
+                lifetimes: false,
+                safety: true,
+                validity: true,
+            }
+        }>
+    {}
+}
+
+#[repr(u8)] enum V0 { V = 0 }
+#[repr(u8)] enum V1 { V = 1 }
+#[repr(u8)] enum V2 { V = 2 }
+#[repr(u8)] enum V253 { V = 253 }
+#[repr(u8)] enum V254 { V = 254 }
+#[repr(u8)] enum V255 { V = 255 }
+
+fn bool() {
+    enum OptionLike {
+        A(bool),
+        B,
+    }
+
+    const _: () = {
+        assert!(std::mem::size_of::<OptionLike>() == 1);
+    };
+
+    assert::is_transmutable::<OptionLike, u8>();
+
+    assert::is_transmutable::<bool, OptionLike>();
+    assert::is_transmutable::<V0, OptionLike>();
+    assert::is_transmutable::<V1, OptionLike>();
+    assert::is_transmutable::<V2, OptionLike>();
+}
+
+fn one_niche() {
+    #[repr(u8)]
+    enum N1 {
+        S = 0,
+        E = 255 - 1,
+    }
+
+    enum OptionLike {
+        A(N1),
+        B,
+    }
+
+    const _: () = {
+        assert!(std::mem::size_of::<OptionLike>() == 1);
+    };
+
+    assert::is_transmutable::<OptionLike, u8>();
+    assert::is_transmutable::<V0, OptionLike>();
+    assert::is_transmutable::<V254, OptionLike>();
+    assert::is_transmutable::<V255, OptionLike>();
+}
+
+fn one_niche_alt() {
+    #[repr(u8)]
+    enum N1 {
+        S = 1,
+        E = 255 - 1,
+    }
+
+    enum OptionLike {
+        A(N1),
+        B,
+        C,
+    }
+
+    const _: () = {
+        assert!(std::mem::size_of::<OptionLike>() == 1);
+    };
+
+    assert::is_transmutable::<OptionLike, u8>();
+    assert::is_transmutable::<V0, OptionLike>();
+    assert::is_transmutable::<V254, OptionLike>();
+    assert::is_transmutable::<V255, OptionLike>();
+}
+
+fn two_niche() {
+    #[repr(u8)]
+    enum Niche {
+        S = 0,
+        E = 255 - 2,
+    }
+
+    enum OptionLike {
+        A(Niche),
+        B,
+        C,
+    }
+
+    const _: () = {
+        assert!(std::mem::size_of::<OptionLike>() == 1);
+    };
+
+    assert::is_transmutable::<OptionLike, u8>();
+    assert::is_transmutable::<V0, OptionLike>();
+    assert::is_transmutable::<V253, OptionLike>();
+    assert::is_transmutable::<V254, OptionLike>();
+    assert::is_transmutable::<V255, OptionLike>();
+}
+
+fn no_niche() {
+    use std::mem::MaybeUninit;
+
+    #[repr(u8)]
+    enum Niche {
+        S = 0,
+        E = 255 - 1,
+    }
+
+    enum OptionLike {
+        A(Niche),
+        B,
+        C,
+    }
+
+    const _: () = {
+        assert!(std::mem::size_of::<OptionLike>() == 2);
+    };
+
+    #[repr(C)]
+    struct Pair<T, U>(T, U);
+
+    assert::is_transmutable::<V0, Niche>();
+    assert::is_transmutable::<V254, Niche>();
+    assert::is_transmutable::<Pair<V0, Niche>, OptionLike>();
+    assert::is_transmutable::<Pair<V1, MaybeUninit<u8>>, OptionLike>();
+    assert::is_transmutable::<Pair<V2, MaybeUninit<u8>>, OptionLike>();
+}
diff --git a/tests/ui/transmutability/enums/repr/padding_differences.rs b/tests/ui/transmutability/enums/repr/padding_differences.rs
new file mode 100644
index 00000000000..d0e1502b5e2
--- /dev/null
+++ b/tests/ui/transmutability/enums/repr/padding_differences.rs
@@ -0,0 +1,80 @@
+//@ check-pass
+//! Adapted from https://rust-lang.github.io/unsafe-code-guidelines/layout/enums.html#explicit-repr-annotation-without-c-compatibility
+#![crate_type = "lib"]
+#![feature(transmutability)]
+#![allow(dead_code, incomplete_features, non_camel_case_types)]
+
+use std::mem::MaybeUninit;
+
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+
+    pub fn is_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, {
+            Assume {
+                alignment: false,
+                lifetimes: false,
+                safety: true,
+                validity: false,
+            }
+        }>
+    {}
+
+    pub fn is_maybe_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, {
+            Assume {
+                alignment: false,
+                lifetimes: false,
+                safety: true,
+                validity: true,
+            }
+        }>
+    {}
+}
+
+#[repr(u8)] enum V0 { V = 0 }
+#[repr(u8)] enum V1 { V = 1 }
+
+fn repr_u8() {
+    #[repr(u8)]
+    enum TwoCases {
+        A(u8, u16),     // 0x00 INIT INIT INIT
+        B(u16),         // 0x01 PADD INIT INIT
+    }
+
+    const _: () = {
+        assert!(std::mem::size_of::<TwoCases>() == 4);
+    };
+
+    #[repr(C)] struct TwoCasesA(V0, u8, u8, u8);
+    #[repr(C)] struct TwoCasesB(V1, MaybeUninit<u8>, u8, u8);
+
+    assert::is_transmutable::<TwoCasesA, TwoCases>();
+    assert::is_transmutable::<TwoCasesB, TwoCases>();
+
+    assert::is_maybe_transmutable::<TwoCases, TwoCasesA>();
+    assert::is_maybe_transmutable::<TwoCases, TwoCasesB>();
+}
+
+fn repr_c_u8() {
+    #[repr(C, u8)]
+    enum TwoCases {
+        A(u8, u16),     // 0x00 PADD INIT PADD INIT INIT
+        B(u16),         // 0x01 PADD INIT INIT PADD PADD
+    }
+
+    const _: () = {
+        assert!(std::mem::size_of::<TwoCases>() == 6);
+    };
+
+    #[repr(C)] struct TwoCasesA(V0, MaybeUninit<u8>, u8, MaybeUninit<u8>, u8, u8);
+    #[repr(C)] struct TwoCasesB(V1, MaybeUninit<u8>, u8, u8, MaybeUninit<u8>, MaybeUninit<u8>);
+
+    assert::is_transmutable::<TwoCasesA, TwoCases>();
+    assert::is_transmutable::<TwoCasesB, TwoCases>();
+
+    assert::is_maybe_transmutable::<TwoCases, TwoCasesA>();
+    assert::is_maybe_transmutable::<TwoCases, TwoCasesB>();
+}
diff --git a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.rs b/tests/ui/transmutability/enums/repr/should_handle_all.rs
index 630e662b926..a8ec86fa40d 100644
--- a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.rs
+++ b/tests/ui/transmutability/enums/repr/should_handle_all.rs
@@ -1,5 +1,4 @@
-//! An enum must have a well-defined layout to participate in a transmutation.
-
+//@ check-pass
 #![crate_type = "lib"]
 #![feature(repr128)]
 #![feature(transmutability)]
@@ -21,23 +20,17 @@ mod assert {
     {}
 }
 
-fn should_reject_repr_rust() {
-    fn void() {
-        enum repr_rust {}
-        assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted
-        assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted
-    }
-
+fn should_accept_repr_rust() {
     fn singleton() {
         enum repr_rust { V }
-        assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted
-        assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted
+        assert::is_maybe_transmutable::<repr_rust, ()>();
+        assert::is_maybe_transmutable::<u128, repr_rust>();
     }
 
     fn duplex() {
         enum repr_rust { A, B }
-        assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted
-        assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted
+        assert::is_maybe_transmutable::<repr_rust, ()>();
+        assert::is_maybe_transmutable::<u128, repr_rust>();
     }
 }
 
@@ -116,7 +109,7 @@ fn should_accept_primitive_reprs()
     }
 }
 
-fn should_accept_repr_C() {
+fn should_accept_repr_c() {
     #[repr(C)] enum repr_c { V }
     assert::is_maybe_transmutable::<repr_c, ()>();
     assert::is_maybe_transmutable::<i128, repr_c>();
diff --git a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr
deleted file mode 100644
index 2a683de6a65..00000000000
--- a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr
+++ /dev/null
@@ -1,135 +0,0 @@
-error[E0277]: `void::repr_rust` cannot be safely transmuted into `()`
-  --> $DIR/should_require_well_defined_layout.rs:27:52
-   |
-LL |         assert::is_maybe_transmutable::<repr_rust, ()>();
-   |                                                    ^^ analyzing the transmutability of `void::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:13:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `u128` cannot be safely transmuted into `void::repr_rust`
-  --> $DIR/should_require_well_defined_layout.rs:28:47
-   |
-LL |         assert::is_maybe_transmutable::<u128, repr_rust>();
-   |                                               ^^^^^^^^^ analyzing the transmutability of `void::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:13:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `singleton::repr_rust` cannot be safely transmuted into `()`
-  --> $DIR/should_require_well_defined_layout.rs:33:52
-   |
-LL |         assert::is_maybe_transmutable::<repr_rust, ()>();
-   |                                                    ^^ analyzing the transmutability of `singleton::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:13:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `u128` cannot be safely transmuted into `singleton::repr_rust`
-  --> $DIR/should_require_well_defined_layout.rs:34:47
-   |
-LL |         assert::is_maybe_transmutable::<u128, repr_rust>();
-   |                                               ^^^^^^^^^ analyzing the transmutability of `singleton::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:13:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `duplex::repr_rust` cannot be safely transmuted into `()`
-  --> $DIR/should_require_well_defined_layout.rs:39:52
-   |
-LL |         assert::is_maybe_transmutable::<repr_rust, ()>();
-   |                                                    ^^ analyzing the transmutability of `duplex::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:13:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `u128` cannot be safely transmuted into `duplex::repr_rust`
-  --> $DIR/should_require_well_defined_layout.rs:40:47
-   |
-LL |         assert::is_maybe_transmutable::<u128, repr_rust>();
-   |                                               ^^^^^^^^^ analyzing the transmutability of `duplex::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:13:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error: aborting due to 6 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr
index eeed8a62a2a..cabc7bcfef7 100644
--- a/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr
+++ b/tests/ui/transmutability/malformed-program-gracefulness/unknown_src_field.stderr
@@ -8,7 +8,7 @@ error[E0277]: `Src` cannot be safely transmuted into `Dst`
   --> $DIR/unknown_src_field.rs:19:36
    |
 LL |     assert::is_transmutable::<Src, Dst>();
-   |                                    ^^^ `Dst` has an unknown layout
+   |                                    ^^^ analyzing the transmutability of `Dst` is not yet supported
    |
 note: required by a bound in `is_transmutable`
   --> $DIR/unknown_src_field.rs:12:14
diff --git a/tests/ui/transmutability/maybeuninit.rs b/tests/ui/transmutability/maybeuninit.rs
new file mode 100644
index 00000000000..77c3381c774
--- /dev/null
+++ b/tests/ui/transmutability/maybeuninit.rs
@@ -0,0 +1,43 @@
+#![crate_type = "lib"]
+#![feature(transmutability)]
+#![allow(dead_code, incomplete_features, non_camel_case_types)]
+
+use std::mem::MaybeUninit;
+
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+
+    pub fn is_maybe_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
+    {}
+}
+
+fn validity() {
+    // An initialized byte is a valid uninitialized byte.
+    assert::is_maybe_transmutable::<u8, MaybeUninit<u8>>();
+
+    // An uninitialized byte is never a valid initialized byte.
+    assert::is_maybe_transmutable::<MaybeUninit<u8>, u8>(); //~ ERROR: cannot be safely transmuted
+}
+
+fn padding() {
+    #[repr(align(8))]
+    struct Align8;
+
+    #[repr(u8)]
+    enum ImplicitlyPadded {
+        A(Align8),
+    }
+
+    #[repr(u8)]
+    enum V0 {
+        V0 = 0,
+    }
+
+    #[repr(C)]
+    struct ExplicitlyPadded(V0, MaybeUninit<[u8; 7]>);
+
+    assert::is_maybe_transmutable::<ExplicitlyPadded, ImplicitlyPadded>();
+    assert::is_maybe_transmutable::<ImplicitlyPadded, ExplicitlyPadded>();
+}
diff --git a/tests/ui/transmutability/maybeuninit.stderr b/tests/ui/transmutability/maybeuninit.stderr
new file mode 100644
index 00000000000..be7dcaf35ea
--- /dev/null
+++ b/tests/ui/transmutability/maybeuninit.stderr
@@ -0,0 +1,18 @@
+error[E0277]: `MaybeUninit<u8>` cannot be safely transmuted into `u8`
+  --> $DIR/maybeuninit.rs:21:54
+   |
+LL |     assert::is_maybe_transmutable::<MaybeUninit<u8>, u8>();
+   |                                                      ^^ at least one value of `MaybeUninit<u8>` isn't a bit-valid value of `u8`
+   |
+note: required by a bound in `is_maybe_transmutable`
+  --> $DIR/maybeuninit.rs:12:14
+   |
+LL |     pub fn is_maybe_transmutable<Src, Dst>()
+   |            --------------------- required by a bound in this function
+LL |     where
+LL |         Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/transmutability/references/unsafecell.rs b/tests/ui/transmutability/references/unsafecell.rs
new file mode 100644
index 00000000000..a8a1f969fb4
--- /dev/null
+++ b/tests/ui/transmutability/references/unsafecell.rs
@@ -0,0 +1,47 @@
+#![crate_type = "lib"]
+#![feature(transmutability)]
+#![allow(dead_code, incomplete_features, non_camel_case_types)]
+
+use std::cell::UnsafeCell;
+
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+
+    pub fn is_maybe_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
+    {}
+}
+
+fn value_to_value() {
+    // We accept value-to-value transmutations of `UnsafeCell`-containing types,
+    // because owning a value implies exclusive access.
+    assert::is_maybe_transmutable::<UnsafeCell<u8>, u8>();
+    assert::is_maybe_transmutable::<u8, UnsafeCell<u8>>();
+    assert::is_maybe_transmutable::<UnsafeCell<u8>, UnsafeCell<u8>>();
+}
+
+fn ref_to_ref() {
+    // We forbid `UnsafeCell`-containing ref-to-ref transmutations, because the
+    // two types may use different, incompatible synchronization strategies.
+    assert::is_maybe_transmutable::<&'static u8, &'static UnsafeCell<u8>>(); //~ ERROR: cannot be safely transmuted
+
+    assert::is_maybe_transmutable::<&'static UnsafeCell<u8>, &'static UnsafeCell<u8>>(); //~ ERROR: cannot be safely transmuted
+}
+
+fn mut_to_mut() {
+    // `UnsafeCell` does't matter for `&mut T` to `&mut U`, since exclusive
+    // borrows can't be used for shared access.
+    assert::is_maybe_transmutable::<&'static mut u8, &'static mut UnsafeCell<u8>>();
+    assert::is_maybe_transmutable::<&'static mut UnsafeCell<u8>, &'static mut u8>();
+    assert::is_maybe_transmutable::<&'static mut UnsafeCell<u8>, &'static mut UnsafeCell<u8>>();
+}
+
+fn mut_to_ref() {
+    // We don't care about `UnsafeCell` for transmutations in the form `&mut T
+    // -> &U`, because downgrading a `&mut T` to a `&U` deactivates `&mut T` for
+    // the lifetime of `&U`.
+    assert::is_maybe_transmutable::<&'static mut u8, &'static UnsafeCell<u8>>();
+    assert::is_maybe_transmutable::<&'static mut UnsafeCell<u8>, &'static u8>();
+    assert::is_maybe_transmutable::<&'static mut UnsafeCell<u8>, &'static UnsafeCell<u8>>();
+}
diff --git a/tests/ui/transmutability/references/unsafecell.stderr b/tests/ui/transmutability/references/unsafecell.stderr
new file mode 100644
index 00000000000..651eb8ceb26
--- /dev/null
+++ b/tests/ui/transmutability/references/unsafecell.stderr
@@ -0,0 +1,33 @@
+error[E0277]: `&u8` cannot be safely transmuted into `&UnsafeCell<u8>`
+  --> $DIR/unsafecell.rs:27:50
+   |
+LL |     assert::is_maybe_transmutable::<&'static u8, &'static UnsafeCell<u8>>();
+   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `&'static UnsafeCell<u8>`
+   |
+note: required by a bound in `is_maybe_transmutable`
+  --> $DIR/unsafecell.rs:12:14
+   |
+LL |     pub fn is_maybe_transmutable<Src, Dst>()
+   |            --------------------- required by a bound in this function
+LL |     where
+LL |         Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+
+error[E0277]: `&UnsafeCell<u8>` cannot be safely transmuted into `&UnsafeCell<u8>`
+  --> $DIR/unsafecell.rs:29:62
+   |
+LL |     assert::is_maybe_transmutable::<&'static UnsafeCell<u8>, &'static UnsafeCell<u8>>();
+   |                                                              ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `&'static UnsafeCell<u8>`
+   |
+note: required by a bound in `is_maybe_transmutable`
+  --> $DIR/unsafecell.rs:12:14
+   |
+LL |     pub fn is_maybe_transmutable<Src, Dst>()
+   |            --------------------- required by a bound in this function
+LL |     where
+LL |         Dst: BikeshedIntrinsicFrom<Src, { Assume::SAFETY }>
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.rs b/tests/ui/transmutability/structs/repr/should_handle_all.rs
index 2e673601baf..52c24eecf12 100644
--- a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.rs
+++ b/tests/ui/transmutability/structs/repr/should_handle_all.rs
@@ -1,3 +1,4 @@
+//@ check-pass
 //! A struct must have a well-defined layout to participate in a transmutation.
 
 #![crate_type = "lib"]
@@ -20,47 +21,47 @@ mod assert {
     {}
 }
 
-fn should_reject_repr_rust()
+fn should_accept_repr_rust()
 {
     fn unit() {
         struct repr_rust;
-        assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted
-        assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted
+        assert::is_maybe_transmutable::<repr_rust, ()>();
+        assert::is_maybe_transmutable::<u128, repr_rust>();
     }
 
     fn tuple() {
         struct repr_rust();
-        assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted
-        assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted
+        assert::is_maybe_transmutable::<repr_rust, ()>();
+        assert::is_maybe_transmutable::<u128, repr_rust>();
     }
 
     fn braces() {
         struct repr_rust{}
-        assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted
-        assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted
+        assert::is_maybe_transmutable::<repr_rust, ()>();
+        assert::is_maybe_transmutable::<u128, repr_rust>();
     }
 
     fn aligned() {
         #[repr(align(1))] struct repr_rust{}
-        assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted
-        assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted
+        assert::is_maybe_transmutable::<repr_rust, ()>();
+        assert::is_maybe_transmutable::<u128, repr_rust>();
     }
 
     fn packed() {
         #[repr(packed)] struct repr_rust{}
-        assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted
-        assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted
+        assert::is_maybe_transmutable::<repr_rust, ()>();
+        assert::is_maybe_transmutable::<u128, repr_rust>();
     }
 
     fn nested() {
         struct repr_rust;
         #[repr(C)] struct repr_c(repr_rust);
-        assert::is_maybe_transmutable::<repr_c, ()>(); //~ ERROR cannot be safely transmuted
-        assert::is_maybe_transmutable::<u128, repr_c>(); //~ ERROR cannot be safely transmuted
+        assert::is_maybe_transmutable::<repr_c, ()>();
+        assert::is_maybe_transmutable::<u128, repr_c>();
     }
 }
 
-fn should_accept_repr_C()
+fn should_accept_repr_c()
 {
     fn unit() {
         #[repr(C)] struct repr_c;
diff --git a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr
deleted file mode 100644
index 77788f72c21..00000000000
--- a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr
+++ /dev/null
@@ -1,267 +0,0 @@
-error[E0277]: `should_reject_repr_rust::unit::repr_rust` cannot be safely transmuted into `()`
-  --> $DIR/should_require_well_defined_layout.rs:27:52
-   |
-LL |         assert::is_maybe_transmutable::<repr_rust, ()>();
-   |                                                    ^^ analyzing the transmutability of `should_reject_repr_rust::unit::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:12:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::unit::repr_rust`
-  --> $DIR/should_require_well_defined_layout.rs:28:47
-   |
-LL |         assert::is_maybe_transmutable::<u128, repr_rust>();
-   |                                               ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::unit::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:12:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `should_reject_repr_rust::tuple::repr_rust` cannot be safely transmuted into `()`
-  --> $DIR/should_require_well_defined_layout.rs:33:52
-   |
-LL |         assert::is_maybe_transmutable::<repr_rust, ()>();
-   |                                                    ^^ analyzing the transmutability of `should_reject_repr_rust::tuple::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:12:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::tuple::repr_rust`
-  --> $DIR/should_require_well_defined_layout.rs:34:47
-   |
-LL |         assert::is_maybe_transmutable::<u128, repr_rust>();
-   |                                               ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::tuple::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:12:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `should_reject_repr_rust::braces::repr_rust` cannot be safely transmuted into `()`
-  --> $DIR/should_require_well_defined_layout.rs:39:52
-   |
-LL |         assert::is_maybe_transmutable::<repr_rust, ()>();
-   |                                                    ^^ analyzing the transmutability of `should_reject_repr_rust::braces::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:12:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::braces::repr_rust`
-  --> $DIR/should_require_well_defined_layout.rs:40:47
-   |
-LL |         assert::is_maybe_transmutable::<u128, repr_rust>();
-   |                                               ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::braces::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:12:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `aligned::repr_rust` cannot be safely transmuted into `()`
-  --> $DIR/should_require_well_defined_layout.rs:45:52
-   |
-LL |         assert::is_maybe_transmutable::<repr_rust, ()>();
-   |                                                    ^^ analyzing the transmutability of `aligned::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:12:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `u128` cannot be safely transmuted into `aligned::repr_rust`
-  --> $DIR/should_require_well_defined_layout.rs:46:47
-   |
-LL |         assert::is_maybe_transmutable::<u128, repr_rust>();
-   |                                               ^^^^^^^^^ analyzing the transmutability of `aligned::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:12:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `packed::repr_rust` cannot be safely transmuted into `()`
-  --> $DIR/should_require_well_defined_layout.rs:51:52
-   |
-LL |         assert::is_maybe_transmutable::<repr_rust, ()>();
-   |                                                    ^^ analyzing the transmutability of `packed::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:12:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `u128` cannot be safely transmuted into `packed::repr_rust`
-  --> $DIR/should_require_well_defined_layout.rs:52:47
-   |
-LL |         assert::is_maybe_transmutable::<u128, repr_rust>();
-   |                                               ^^^^^^^^^ analyzing the transmutability of `packed::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:12:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `nested::repr_c` cannot be safely transmuted into `()`
-  --> $DIR/should_require_well_defined_layout.rs:58:49
-   |
-LL |         assert::is_maybe_transmutable::<repr_c, ()>();
-   |                                                 ^^ analyzing the transmutability of `nested::repr_c` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:12:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `u128` cannot be safely transmuted into `nested::repr_c`
-  --> $DIR/should_require_well_defined_layout.rs:59:47
-   |
-LL |         assert::is_maybe_transmutable::<u128, repr_c>();
-   |                                               ^^^^^^ analyzing the transmutability of `nested::repr_c` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:12:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error: aborting due to 12 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.rs b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.rs
index 4c285a616b3..64110753832 100644
--- a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.rs
+++ b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.rs
@@ -22,4 +22,5 @@ fn should_pad_explicitly_packed_field() {
     //~^ ERROR: recursive type
 
     assert::is_maybe_transmutable::<ExplicitlyPadded, ()>();
+    //~^ ERROR: cannot be safely transmuted
 }
diff --git a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr
index 7fb051f6625..ebfb5361143 100644
--- a/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr
+++ b/tests/ui/transmutability/structs/repr/transmute_infinitely_recursive_type.stderr
@@ -15,7 +15,22 @@ error[E0391]: cycle detected when computing layout of `should_pad_explicitly_pac
    = note: cycle used when evaluating trait selection obligation `(): core::mem::transmutability::BikeshedIntrinsicFrom<should_pad_explicitly_packed_field::ExplicitlyPadded, core::mem::transmutability::Assume { alignment: false, lifetimes: false, safety: false, validity: false }>`
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error: aborting due to 2 previous errors
+error[E0277]: `ExplicitlyPadded` cannot be safely transmuted into `()`
+  --> $DIR/transmute_infinitely_recursive_type.rs:24:55
+   |
+LL |     assert::is_maybe_transmutable::<ExplicitlyPadded, ()>();
+   |                                                       ^^ analyzing the transmutability of `ExplicitlyPadded` is not yet supported
+   |
+note: required by a bound in `is_maybe_transmutable`
+  --> $DIR/transmute_infinitely_recursive_type.rs:14:14
+   |
+LL |     pub fn is_maybe_transmutable<Src, Dst>()
+   |            --------------------- required by a bound in this function
+LL |     where
+LL |         Dst: BikeshedIntrinsicFrom<Src>,
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable`
+
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0072, E0391.
+Some errors have detailed explanations: E0072, E0277, E0391.
 For more information about an error, try `rustc --explain E0072`.
diff --git a/tests/ui/transmutability/transmute-padding-ice.rs b/tests/ui/transmutability/transmute-padding-ice.rs
index 3f3f75bc086..f5935a0009e 100644
--- a/tests/ui/transmutability/transmute-padding-ice.rs
+++ b/tests/ui/transmutability/transmute-padding-ice.rs
@@ -1,7 +1,13 @@
+//@ check-pass
+//! This UI test was introduced as check-fail by a buggy bug-fix for an ICE. In
+//! fact, this transmutation should be valid.
+
 #![crate_type = "lib"]
 #![feature(transmutability)]
 #![allow(dead_code)]
 
+use std::mem::size_of;
+
 mod assert {
     use std::mem::{Assume, BikeshedIntrinsicFrom};
 
@@ -22,6 +28,7 @@ fn test() {
     #[repr(C)]
     struct B(u8, u8);
 
+    assert_eq!(size_of::<A>(), size_of::<B>());
+
     assert::is_maybe_transmutable::<B, A>();
-    //~^ ERROR cannot be safely transmuted
 }
diff --git a/tests/ui/transmutability/transmute-padding-ice.stderr b/tests/ui/transmutability/transmute-padding-ice.stderr
deleted file mode 100644
index 4c121d463c6..00000000000
--- a/tests/ui/transmutability/transmute-padding-ice.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-error[E0277]: `B` cannot be safely transmuted into `A`
-  --> $DIR/transmute-padding-ice.rs:25:40
-   |
-LL |     assert::is_maybe_transmutable::<B, A>();
-   |                                        ^ the size of `B` is smaller than the size of `A`
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/transmute-padding-ice.rs:10:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<
-   |  ______________^
-LL | |             Src,
-LL | |             { Assume { alignment: true, lifetimes: true, safety: true, validity: true } },
-LL | |         >,
-   | |_________^ required by this bound in `is_maybe_transmutable`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/transmutability/uninhabited.rs b/tests/ui/transmutability/uninhabited.rs
new file mode 100644
index 00000000000..b61b110f6a1
--- /dev/null
+++ b/tests/ui/transmutability/uninhabited.rs
@@ -0,0 +1,71 @@
+#![crate_type = "lib"]
+#![feature(transmutability)]
+#![allow(dead_code, incomplete_features, non_camel_case_types)]
+
+mod assert {
+    use std::mem::{Assume, BikeshedIntrinsicFrom};
+
+    pub fn is_maybe_transmutable<Src, Dst>()
+    where
+        Dst: BikeshedIntrinsicFrom<Src, {
+            Assume {
+                alignment: true,
+                lifetimes: true,
+                safety: true,
+                validity: true,
+            }
+        }>
+    {}
+}
+
+fn void() {
+    enum Void {}
+
+    // This transmutation is vacuously acceptable; since one cannot construct a
+    // `Void`, unsoundness cannot directly arise from transmuting a void into
+    // anything else.
+    assert::is_maybe_transmutable::<Void, u128>();
+
+    assert::is_maybe_transmutable::<(), Void>(); //~ ERROR: cannot be safely transmuted
+}
+
+// Non-ZST uninhabited types are, nonetheless, uninhabited.
+fn yawning_void() {
+    enum Void {}
+
+    struct YawningVoid(Void, u128);
+
+    const _: () = {
+        assert!(std::mem::size_of::<YawningVoid>() == std::mem::size_of::<u128>());
+        // Just to be sure the above constant actually evaluated:
+        assert!(false); //~ ERROR: evaluation of constant value failed
+    };
+
+    // This transmutation is vacuously acceptable; since one cannot construct a
+    // `Void`, unsoundness cannot directly arise from transmuting a void into
+    // anything else.
+    assert::is_maybe_transmutable::<YawningVoid, u128>();
+
+    assert::is_maybe_transmutable::<(), Void>(); //~ ERROR: cannot be safely transmuted
+}
+
+// References to uninhabited types are, logically, uninhabited, but for layout
+// purposes are not ZSTs, and aren't treated as uninhabited when they appear in
+// enum variants.
+fn distant_void() {
+    enum Void {}
+
+    enum DistantVoid {
+        A(&'static Void)
+    }
+
+    const _: () = {
+        assert!(std::mem::size_of::<DistantVoid>() == std::mem::size_of::<usize>());
+        // Just to be sure the above constant actually evaluated:
+        assert!(false); //~ ERROR: evaluation of constant value failed
+    };
+
+    assert::is_maybe_transmutable::<DistantVoid, ()>();
+    assert::is_maybe_transmutable::<DistantVoid, &'static Void>();
+    assert::is_maybe_transmutable::<u128, DistantVoid>(); //~ ERROR: cannot be safely transmuted
+}
diff --git a/tests/ui/transmutability/uninhabited.stderr b/tests/ui/transmutability/uninhabited.stderr
new file mode 100644
index 00000000000..60219b0f263
--- /dev/null
+++ b/tests/ui/transmutability/uninhabited.stderr
@@ -0,0 +1,86 @@
+error[E0080]: evaluation of constant value failed
+  --> $DIR/uninhabited.rs:41:9
+   |
+LL |         assert!(false);
+   |         ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/uninhabited.rs:41:9
+   |
+   = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+  --> $DIR/uninhabited.rs:65:9
+   |
+LL |         assert!(false);
+   |         ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/uninhabited.rs:65:9
+   |
+   = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0277]: `()` cannot be safely transmuted into `void::Void`
+  --> $DIR/uninhabited.rs:29:41
+   |
+LL |     assert::is_maybe_transmutable::<(), Void>();
+   |                                         ^^^^ `void::Void` is uninhabited
+   |
+note: required by a bound in `is_maybe_transmutable`
+  --> $DIR/uninhabited.rs:10:14
+   |
+LL |       pub fn is_maybe_transmutable<Src, Dst>()
+   |              --------------------- required by a bound in this function
+LL |       where
+LL |           Dst: BikeshedIntrinsicFrom<Src, {
+   |  ______________^
+LL | |             Assume {
+LL | |                 alignment: true,
+LL | |                 lifetimes: true,
+...  |
+LL | |             }
+LL | |         }>
+   | |__________^ required by this bound in `is_maybe_transmutable`
+
+error[E0277]: `()` cannot be safely transmuted into `yawning_void::Void`
+  --> $DIR/uninhabited.rs:49:41
+   |
+LL |     assert::is_maybe_transmutable::<(), Void>();
+   |                                         ^^^^ `yawning_void::Void` is uninhabited
+   |
+note: required by a bound in `is_maybe_transmutable`
+  --> $DIR/uninhabited.rs:10:14
+   |
+LL |       pub fn is_maybe_transmutable<Src, Dst>()
+   |              --------------------- required by a bound in this function
+LL |       where
+LL |           Dst: BikeshedIntrinsicFrom<Src, {
+   |  ______________^
+LL | |             Assume {
+LL | |                 alignment: true,
+LL | |                 lifetimes: true,
+...  |
+LL | |             }
+LL | |         }>
+   | |__________^ required by this bound in `is_maybe_transmutable`
+
+error[E0277]: `u128` cannot be safely transmuted into `DistantVoid`
+  --> $DIR/uninhabited.rs:70:43
+   |
+LL |     assert::is_maybe_transmutable::<u128, DistantVoid>();
+   |                                           ^^^^^^^^^^^ at least one value of `u128` isn't a bit-valid value of `DistantVoid`
+   |
+note: required by a bound in `is_maybe_transmutable`
+  --> $DIR/uninhabited.rs:10:14
+   |
+LL |       pub fn is_maybe_transmutable<Src, Dst>()
+   |              --------------------- required by a bound in this function
+LL |       where
+LL |           Dst: BikeshedIntrinsicFrom<Src, {
+   |  ______________^
+LL | |             Assume {
+LL | |                 alignment: true,
+LL | |                 lifetimes: true,
+...  |
+LL | |             }
+LL | |         }>
+   | |__________^ required by this bound in `is_maybe_transmutable`
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0080, E0277.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/tests/ui/transmutability/unions/repr/should_handle_align.rs b/tests/ui/transmutability/unions/repr/should_handle_align.rs
index 8668cca3cb5..ba4e904e161 100644
--- a/tests/ui/transmutability/unions/repr/should_handle_align.rs
+++ b/tests/ui/transmutability/unions/repr/should_handle_align.rs
@@ -25,13 +25,13 @@ fn should_pad_explicitly_aligned_field() {
     #[derive(Clone, Copy)] #[repr(u8)] enum V0u8 { V = 0 }
     #[derive(Clone, Copy)] #[repr(u8)] enum V1u8 { V = 1 }
 
-    #[repr(C)]
+    #[repr(align(1))]
     pub union Uninit {
         a: (),
         b: V1u8,
     }
 
-    #[repr(C, align(2))]
+    #[repr(align(2))]
     pub union align_2 {
         a: V0u8,
     }
diff --git a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.rs b/tests/ui/transmutability/unions/repr/should_handle_all.rs
index 8495b0ea88f..85d48dd9b7f 100644
--- a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.rs
+++ b/tests/ui/transmutability/unions/repr/should_handle_all.rs
@@ -1,7 +1,7 @@
-//! A struct must have a well-defined layout to participate in a transmutation.
+//@ check-pass
 
 #![crate_type = "lib"]
-#![feature(transmutability)]
+#![feature(transmutability, transparent_unions)]
 #![allow(dead_code, incomplete_features, non_camel_case_types)]
 
 mod assert {
@@ -20,17 +20,17 @@ mod assert {
     {}
 }
 
-fn should_reject_repr_rust()
+fn should_accept_repr_rust()
 {
     union repr_rust {
         a: u8
     }
 
-    assert::is_maybe_transmutable::<repr_rust, ()>(); //~ ERROR cannot be safely transmuted
-    assert::is_maybe_transmutable::<u128, repr_rust>(); //~ ERROR cannot be safely transmuted
+    assert::is_maybe_transmutable::<repr_rust, ()>();
+    assert::is_maybe_transmutable::<u128, repr_rust>();
 }
 
-fn should_accept_repr_C()
+fn should_accept_repr_c()
 {
     #[repr(C)]
     union repr_c {
@@ -41,3 +41,15 @@ fn should_accept_repr_C()
     assert::is_maybe_transmutable::<repr_c, ()>();
     assert::is_maybe_transmutable::<u128, repr_c>();
 }
+
+
+fn should_accept_transparent()
+{
+    #[repr(transparent)]
+    union repr_transparent {
+        a: u8
+    }
+
+    assert::is_maybe_transmutable::<repr_transparent, ()>();
+    assert::is_maybe_transmutable::<u128, repr_transparent>();
+}
diff --git a/tests/ui/transmutability/unions/repr/should_handle_packed.rs b/tests/ui/transmutability/unions/repr/should_handle_packed.rs
index 4af6c1d3a61..fc06eba4353 100644
--- a/tests/ui/transmutability/unions/repr/should_handle_packed.rs
+++ b/tests/ui/transmutability/unions/repr/should_handle_packed.rs
@@ -27,7 +27,6 @@ fn should_pad_explicitly_packed_field() {
     #[derive(Clone, Copy)] #[repr(u8)] enum V2u8 { V = 2 }
     #[derive(Clone, Copy)] #[repr(u32)] enum V3u32 { V = 3 }
 
-    #[repr(C)]
     pub union Uninit {
         a: (),
         b: V1u8,
diff --git a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr
deleted file mode 100644
index bec07f13103..00000000000
--- a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr
+++ /dev/null
@@ -1,47 +0,0 @@
-error[E0277]: `should_reject_repr_rust::repr_rust` cannot be safely transmuted into `()`
-  --> $DIR/should_require_well_defined_layout.rs:29:48
-   |
-LL |     assert::is_maybe_transmutable::<repr_rust, ()>();
-   |                                                ^^ analyzing the transmutability of `should_reject_repr_rust::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:12:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error[E0277]: `u128` cannot be safely transmuted into `should_reject_repr_rust::repr_rust`
-  --> $DIR/should_require_well_defined_layout.rs:30:43
-   |
-LL |     assert::is_maybe_transmutable::<u128, repr_rust>();
-   |                                           ^^^^^^^^^ analyzing the transmutability of `should_reject_repr_rust::repr_rust` is not yet supported.
-   |
-note: required by a bound in `is_maybe_transmutable`
-  --> $DIR/should_require_well_defined_layout.rs:12:14
-   |
-LL |       pub fn is_maybe_transmutable<Src, Dst>()
-   |              --------------------- required by a bound in this function
-LL |       where
-LL |           Dst: BikeshedIntrinsicFrom<Src, {
-   |  ______________^
-LL | |             Assume {
-LL | |                 alignment: true,
-LL | |                 lifetimes: true,
-...  |
-LL | |             }
-LL | |         }>
-   | |__________^ required by this bound in `is_maybe_transmutable`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0277`.