about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-06-11 11:06:38 +0000
committerbors <bors@rust-lang.org>2019-06-11 11:06:38 +0000
commit8e948df707ea8a3c88c65bf2ffdcb2f1cf5491be (patch)
treecaf2cb5f0b7881b6056c37c37c2e73e46b520aab /src/test
parent912d22e36965d3c9f6d7f14ca18657182aa1fe54 (diff)
parentdac1c6a731713ec9e90a1e05b3e2c789faf3f2ba (diff)
downloadrust-8e948df707ea8a3c88c65bf2ffdcb2f1cf5491be.tar.gz
rust-8e948df707ea8a3c88c65bf2ffdcb2f1cf5491be.zip
Auto merge of #60463 - mjbshaw:transparent, r=varkor,rkruppe
Implement RFC 2645 (transparent enums and unions)

Tracking issue: #60405
Diffstat (limited to 'src/test')
-rw-r--r--src/test/codegen/repr-transparent-aggregates-1.rs59
-rw-r--r--src/test/codegen/repr-transparent-aggregates-2.rs58
-rw-r--r--src/test/codegen/repr-transparent-aggregates-3.rs58
-rw-r--r--src/test/codegen/repr-transparent.rs43
-rw-r--r--src/test/run-pass/structs-enums/enum-null-pointer-opt.rs12
-rw-r--r--src/test/ui/attr-usage-repr.rs2
-rw-r--r--src/test/ui/attr-usage-repr.stderr4
-rw-r--r--src/test/ui/error-codes/E0517.stderr8
-rw-r--r--src/test/ui/feature-gates/feature-gate-transparent_enums.rs6
-rw-r--r--src/test/ui/feature-gates/feature-gate-transparent_enums.stderr14
-rw-r--r--src/test/ui/feature-gates/feature-gate-transparent_unions.rs7
-rw-r--r--src/test/ui/feature-gates/feature-gate-transparent_unions.stderr15
-rw-r--r--src/test/ui/issues/issue-14309.stderr10
-rw-r--r--src/test/ui/issues/issue-16250.stderr2
-rw-r--r--src/test/ui/issues/issue-31769.rs2
-rw-r--r--src/test/ui/issues/issue-31769.stderr4
-rw-r--r--src/test/ui/issues/issue-43988.stderr8
-rw-r--r--src/test/ui/lint/lint-ctypes-enum.rs18
-rw-r--r--src/test/ui/lint/lint-ctypes-enum.stderr42
-rw-r--r--src/test/ui/lint/lint-ctypes.stderr10
-rw-r--r--src/test/ui/repr/repr-transparent-other-items.rs21
-rw-r--r--src/test/ui/repr/repr-transparent-other-items.stderr64
-rw-r--r--src/test/ui/repr/repr-transparent.rs34
-rw-r--r--src/test/ui/repr/repr-transparent.stderr96
-rw-r--r--src/test/ui/union/union-repr-c.stderr2
25 files changed, 433 insertions, 166 deletions
diff --git a/src/test/codegen/repr-transparent-aggregates-1.rs b/src/test/codegen/repr-transparent-aggregates-1.rs
index fb88f2a69ca..e7c4b6193bc 100644
--- a/src/test/codegen/repr-transparent-aggregates-1.rs
+++ b/src/test/codegen/repr-transparent-aggregates-1.rs
@@ -1,4 +1,5 @@
 // compile-flags: -C no-prepopulate-passes
+// ignore-tidy-linelength
 
 // ignore-arm
 // ignore-mips
@@ -7,36 +8,76 @@
 // ignore-powerpc64
 // See repr-transparent.rs
 
+#![feature(transparent_enums, transparent_unions)]
+
 #![crate_type="lib"]
 
 
+#[derive(Clone, Copy)]
 #[repr(C)]
-pub struct Big([u32; 16]);
+pub struct BigS([u32; 16]);
+
+#[repr(transparent)]
+pub struct TsBigS(BigS);
+
+#[repr(transparent)]
+pub union TuBigS {
+    field: BigS,
+}
 
 #[repr(transparent)]
-pub struct BigW(Big);
+pub enum TeBigS {
+    Variant(BigS),
+}
+
+// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS:.*]], %BigS* [[BIGS_ARG_ATTRS:.*]])
+#[no_mangle]
+pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
+
+// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS]], %TsBigS* [[BIGS_ARG_ATTRS]])
+#[no_mangle]
+pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
 
-// CHECK: define void @test_Big(%Big* [[BIG_RET_ATTRS:.*]], %Big* [[BIG_ARG_ATTRS:.*]])
+// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS]], %TuBigS* [[BIGS_ARG_ATTRS]])
 #[no_mangle]
-pub extern fn test_Big(_: Big) -> Big { loop {} }
+pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
 
-// CHECK: define void @test_BigW(%BigW* [[BIG_RET_ATTRS]], %BigW* [[BIG_ARG_ATTRS]])
+// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS]], %"TeBigS::Variant"* [[BIGS_ARG_ATTRS]])
 #[no_mangle]
-pub extern fn test_BigW(_: BigW) -> BigW { loop {} }
+pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
 
 
+#[derive(Clone, Copy)]
 #[repr(C)]
 pub union BigU {
     foo: [u32; 16],
 }
 
 #[repr(transparent)]
-pub struct BigUw(BigU);
+pub struct TsBigU(BigU);
+
+#[repr(transparent)]
+pub union TuBigU {
+    field: BigU,
+}
+
+#[repr(transparent)]
+pub enum TeBigU {
+    Variant(BigU),
+}
 
 // CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], %BigU* [[BIGU_ARG_ATTRS:.*]])
 #[no_mangle]
 pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
 
-// CHECK: define void @test_BigUw(%BigUw* [[BIGU_RET_ATTRS]], %BigUw* [[BIGU_ARG_ATTRS]])
+// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS:.*]], %TsBigU* [[BIGU_ARG_ATTRS]])
+#[no_mangle]
+pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
+
+// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS]], %TuBigU* [[BIGU_ARG_ATTRS]])
+#[no_mangle]
+pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
+
+// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS]], %"TeBigU::Variant"* [[BIGU_ARG_ATTRS]])
 #[no_mangle]
-pub extern fn test_BigUw(_: BigUw) -> BigUw { loop {} }
+pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
diff --git a/src/test/codegen/repr-transparent-aggregates-2.rs b/src/test/codegen/repr-transparent-aggregates-2.rs
index 6c628ac035f..5521c3c849f 100644
--- a/src/test/codegen/repr-transparent-aggregates-2.rs
+++ b/src/test/codegen/repr-transparent-aggregates-2.rs
@@ -14,36 +14,76 @@
 // ignore-x86_64
 // See repr-transparent.rs
 
+#![feature(transparent_enums, transparent_unions)]
+
 #![crate_type="lib"]
 
 
+#[derive(Clone, Copy)]
 #[repr(C)]
-pub struct Big([u32; 16]);
+pub struct BigS([u32; 16]);
+
+#[repr(transparent)]
+pub struct TsBigS(BigS);
+
+#[repr(transparent)]
+pub union TuBigS {
+    field: BigS,
+}
 
 #[repr(transparent)]
-pub struct BigW(Big);
+pub enum TeBigS {
+    Variant(BigS),
+}
+
+// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS:.*]], [16 x i32]
+#[no_mangle]
+pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
+
+// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS]], [16 x i32]
+#[no_mangle]
+pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
 
-// CHECK: define void @test_Big(%Big* [[BIG_RET_ATTRS:.*]], [16 x i32]
+// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS]], [16 x i32]
 #[no_mangle]
-pub extern fn test_Big(_: Big) -> Big { loop {} }
+pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
 
-// CHECK: define void @test_BigW(%BigW* [[BIG_RET_ATTRS]], [16 x i32]
+// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS]], [16 x i32]
 #[no_mangle]
-pub extern fn test_BigW(_: BigW) -> BigW { loop {} }
+pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
 
 
+#[derive(Clone, Copy)]
 #[repr(C)]
 pub union BigU {
     foo: [u32; 16],
 }
 
 #[repr(transparent)]
-pub struct BigUw(BigU);
+pub struct TsBigU(BigU);
+
+#[repr(transparent)]
+pub union TuBigU {
+    field: BigU,
+}
+
+#[repr(transparent)]
+pub enum TeBigU {
+    Variant(BigU),
+}
 
 // CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], [16 x i32]
 #[no_mangle]
 pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
 
-// CHECK: define void @test_BigUw(%BigUw* [[BIGU_RET_ATTRS]], [16 x i32]
+// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS:.*]], [16 x i32]
+#[no_mangle]
+pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
+
+// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS]], [16 x i32]
+#[no_mangle]
+pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
+
+// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS]], [16 x i32]
 #[no_mangle]
-pub extern fn test_BigUw(_: BigUw) -> BigUw { loop {} }
+pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
diff --git a/src/test/codegen/repr-transparent-aggregates-3.rs b/src/test/codegen/repr-transparent-aggregates-3.rs
index cd740dc9b82..1a59c9b48b9 100644
--- a/src/test/codegen/repr-transparent-aggregates-3.rs
+++ b/src/test/codegen/repr-transparent-aggregates-3.rs
@@ -3,36 +3,76 @@
 // only-mips64
 // See repr-transparent.rs
 
+#![feature(transparent_enums, transparent_unions)]
+
 #![crate_type="lib"]
 
 
+#[derive(Clone, Copy)]
 #[repr(C)]
-pub struct Big([u32; 16]);
+pub struct BigS([u32; 16]);
+
+#[repr(transparent)]
+pub struct TsBigS(BigS);
+
+#[repr(transparent)]
+pub union TuBigS {
+    field: BigS,
+}
 
 #[repr(transparent)]
-pub struct BigW(Big);
+pub enum TeBigS {
+    Variant(BigS),
+}
+
+// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS:.*]], [8 x i64]
+#[no_mangle]
+pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
+
+// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS]], [8 x i64]
+#[no_mangle]
+pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
 
-// CHECK: define void @test_Big(%Big* [[BIG_RET_ATTRS:.*]], [8 x i64]
+// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS]], [8 x i64]
 #[no_mangle]
-pub extern fn test_Big(_: Big) -> Big { loop {} }
+pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
 
-// CHECK: define void @test_BigW(%BigW* [[BIG_RET_ATTRS]], [8 x i64]
+// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS]], [8 x i64]
 #[no_mangle]
-pub extern fn test_BigW(_: BigW) -> BigW { loop {} }
+pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
 
 
+#[derive(Clone, Copy)]
 #[repr(C)]
 pub union BigU {
     foo: [u32; 16],
 }
 
 #[repr(transparent)]
-pub struct BigUw(BigU);
+pub struct TsBigU(BigU);
+
+#[repr(transparent)]
+pub union TuBigU {
+    field: BigU,
+}
+
+#[repr(transparent)]
+pub enum TeBigU {
+    Variant(BigU),
+}
 
 // CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS:.*]], [8 x i64]
 #[no_mangle]
 pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
 
-// CHECK: define void @test_BigUw(%BigUw* [[BIGU_RET_ATTRS]], [8 x i64]
+// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS:.*]], [8 x i64]
+#[no_mangle]
+pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
+
+// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS]], [8 x i64]
+#[no_mangle]
+pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
+
+// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS]], [8 x i64]
 #[no_mangle]
-pub extern fn test_BigUw(_: BigUw) -> BigUw { loop {} }
+pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
diff --git a/src/test/codegen/repr-transparent.rs b/src/test/codegen/repr-transparent.rs
index fd655261ab8..c9f38375658 100644
--- a/src/test/codegen/repr-transparent.rs
+++ b/src/test/codegen/repr-transparent.rs
@@ -1,13 +1,16 @@
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type="lib"]
-#![feature(repr_simd)]
+#![feature(repr_simd, transparent_enums, transparent_unions)]
 
 use std::marker::PhantomData;
 
+#[derive(Copy, Clone)]
 pub struct Zst1;
+#[derive(Copy, Clone)]
 pub struct Zst2(());
 
+#[derive(Copy, Clone)]
 #[repr(transparent)]
 pub struct F32(f32);
 
@@ -112,6 +115,44 @@ pub struct StructWithProjection(<f32 as Mirror>::It);
 #[no_mangle]
 pub extern fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} }
 
+#[repr(transparent)]
+pub enum EnumF32 {
+    Variant(F32)
+}
+
+// CHECK: define float @test_EnumF32(float %arg0)
+#[no_mangle]
+pub extern fn test_EnumF32(_: EnumF32) -> EnumF32 { loop {} }
+
+#[repr(transparent)]
+pub enum EnumF32WithZsts {
+    Variant(Zst1, F32, Zst2)
+}
+
+// CHECK: define float @test_EnumF32WithZsts(float %arg0)
+#[no_mangle]
+pub extern fn test_EnumF32WithZsts(_: EnumF32WithZsts) -> EnumF32WithZsts { loop {} }
+
+#[repr(transparent)]
+pub union UnionF32 {
+    field: F32,
+}
+
+// CHECK: define float @test_UnionF32(float %arg0)
+#[no_mangle]
+pub extern fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} }
+
+#[repr(transparent)]
+pub union UnionF32WithZsts {
+    zst1: Zst1,
+    field: F32,
+    zst2: Zst2,
+}
+
+// CHECK: define float @test_UnionF32WithZsts(float %arg0)
+#[no_mangle]
+pub extern fn test_UnionF32WithZsts(_: UnionF32WithZsts) -> UnionF32WithZsts { loop {} }
+
 
 // All that remains to be tested are aggregates. They are tested in separate files called repr-
 // transparent-*.rs  with `only-*` or `ignore-*` directives, because the expected LLVM IR
diff --git a/src/test/run-pass/structs-enums/enum-null-pointer-opt.rs b/src/test/run-pass/structs-enums/enum-null-pointer-opt.rs
index 87629665bc2..f871c218558 100644
--- a/src/test/run-pass/structs-enums/enum-null-pointer-opt.rs
+++ b/src/test/run-pass/structs-enums/enum-null-pointer-opt.rs
@@ -1,4 +1,6 @@
 // run-pass
+#![feature(transparent_unions)]
+
 use std::mem::size_of;
 use std::num::NonZeroUsize;
 use std::ptr::NonNull;
@@ -10,6 +12,11 @@ trait Mirror { type Image; }
 impl<T> Mirror for T { type Image = T; }
 struct ParamTypeStruct<T>(T);
 struct AssocTypeStruct<T>(<T as Mirror>::Image);
+#[repr(transparent)]
+union MaybeUninitUnion<T: Copy> {
+    _value: T,
+    _uninit: (),
+}
 
 fn main() {
     // Functions
@@ -29,9 +36,12 @@ fn main() {
     // Pointers - Box<T>
     assert_eq!(size_of::<Box<isize>>(), size_of::<Option<Box<isize>>>());
 
-    // The optimization can't apply to raw pointers
+    // The optimization can't apply to raw pointers or unions with a ZST field.
     assert!(size_of::<Option<*const isize>>() != size_of::<*const isize>());
     assert!(Some(0 as *const isize).is_some()); // Can't collapse None to null
+    assert_ne!(size_of::<fn(isize)>(), size_of::<Option<MaybeUninitUnion<fn(isize)>>>());
+    assert_ne!(size_of::<&str>(), size_of::<Option<MaybeUninitUnion<&str>>>());
+    assert_ne!(size_of::<NonNull<isize>>(), size_of::<Option<MaybeUninitUnion<NonNull<isize>>>>());
 
     struct Foo {
         _a: Box<isize>
diff --git a/src/test/ui/attr-usage-repr.rs b/src/test/ui/attr-usage-repr.rs
index ef64dfe20bc..a0b82375e77 100644
--- a/src/test/ui/attr-usage-repr.rs
+++ b/src/test/ui/attr-usage-repr.rs
@@ -1,6 +1,6 @@
 #![feature(repr_simd)]
 
-#[repr(C)] //~ ERROR: attribute should be applied to struct, enum or union
+#[repr(C)] //~ ERROR: attribute should be applied to struct, enum, or union
 fn f() {}
 
 #[repr(C)]
diff --git a/src/test/ui/attr-usage-repr.stderr b/src/test/ui/attr-usage-repr.stderr
index d1f4f3bfeb2..82d80d8d0b1 100644
--- a/src/test/ui/attr-usage-repr.stderr
+++ b/src/test/ui/attr-usage-repr.stderr
@@ -1,10 +1,10 @@
-error[E0517]: attribute should be applied to struct, enum or union
+error[E0517]: attribute should be applied to struct, enum, or union
   --> $DIR/attr-usage-repr.rs:3:8
    |
 LL | #[repr(C)]
    |        ^
 LL | fn f() {}
-   | --------- not a struct, enum or union
+   | --------- not a struct, enum, or union
 
 error[E0517]: attribute should be applied to enum
   --> $DIR/attr-usage-repr.rs:15:8
diff --git a/src/test/ui/error-codes/E0517.stderr b/src/test/ui/error-codes/E0517.stderr
index e256c07de26..2cfca1724c8 100644
--- a/src/test/ui/error-codes/E0517.stderr
+++ b/src/test/ui/error-codes/E0517.stderr
@@ -1,10 +1,10 @@
-error[E0517]: attribute should be applied to struct, enum or union
+error[E0517]: attribute should be applied to struct, enum, or union
   --> $DIR/E0517.rs:1:8
    |
 LL | #[repr(C)]
    |        ^
 LL | type Foo = u8;
-   | -------------- not a struct, enum or union
+   | -------------- not a struct, enum, or union
 
 error[E0517]: attribute should be applied to struct or union
   --> $DIR/E0517.rs:4:8
@@ -22,14 +22,14 @@ LL | #[repr(u8)]
 LL | struct Foo3 {bar: bool, baz: bool}
    | ---------------------------------- not an enum
 
-error[E0517]: attribute should be applied to struct, enum or union
+error[E0517]: attribute should be applied to struct, enum, or union
   --> $DIR/E0517.rs:10:8
    |
 LL |   #[repr(C)]
    |          ^
 LL | / impl Foo3 {
 LL | | }
-   | |_- not a struct, enum or union
+   | |_- not a struct, enum, or union
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/feature-gates/feature-gate-transparent_enums.rs b/src/test/ui/feature-gates/feature-gate-transparent_enums.rs
new file mode 100644
index 00000000000..0a7a73a168e
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-transparent_enums.rs
@@ -0,0 +1,6 @@
+#[repr(transparent)]
+enum OkButUnstableEnum { //~ ERROR transparent enums are unstable
+    Foo((), String, ()),
+}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr b/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr
new file mode 100644
index 00000000000..4b22654e9e4
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr
@@ -0,0 +1,14 @@
+error[E0658]: transparent enums are unstable
+  --> $DIR/feature-gate-transparent_enums.rs:2:1
+   |
+LL | / enum OkButUnstableEnum {
+LL | |     Foo((), String, ()),
+LL | | }
+   | |_^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/60405
+   = help: add #![feature(transparent_enums)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-transparent_unions.rs b/src/test/ui/feature-gates/feature-gate-transparent_unions.rs
new file mode 100644
index 00000000000..73cac0a4914
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-transparent_unions.rs
@@ -0,0 +1,7 @@
+#[repr(transparent)]
+union OkButUnstableUnion { //~ ERROR transparent unions are unstable
+    field: u8,
+    zst: (),
+}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-transparent_unions.stderr b/src/test/ui/feature-gates/feature-gate-transparent_unions.stderr
new file mode 100644
index 00000000000..933b227de63
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-transparent_unions.stderr
@@ -0,0 +1,15 @@
+error[E0658]: transparent unions are unstable
+  --> $DIR/feature-gate-transparent_unions.rs:2:1
+   |
+LL | / union OkButUnstableUnion {
+LL | |     field: u8,
+LL | |     zst: (),
+LL | | }
+   | |_^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/60405
+   = help: add #![feature(transparent_unions)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/issues/issue-14309.stderr b/src/test/ui/issues/issue-14309.stderr
index 4376876ecd6..e0491093a72 100644
--- a/src/test/ui/issues/issue-14309.stderr
+++ b/src/test/ui/issues/issue-14309.stderr
@@ -9,7 +9,7 @@ note: lint level defined here
    |
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
-   = help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
 note: type defined here
   --> $DIR/issue-14309.rs:4:1
    |
@@ -24,7 +24,7 @@ error: `extern` block uses type `A` which is not FFI-safe: this struct has unspe
 LL |     fn bar(x: B);
    |               ^
    |
-   = help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
 note: type defined here
   --> $DIR/issue-14309.rs:4:1
    |
@@ -39,7 +39,7 @@ error: `extern` block uses type `A` which is not FFI-safe: this struct has unspe
 LL |     fn qux(x: A2);
    |               ^^
    |
-   = help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
 note: type defined here
   --> $DIR/issue-14309.rs:4:1
    |
@@ -54,7 +54,7 @@ error: `extern` block uses type `A` which is not FFI-safe: this struct has unspe
 LL |     fn quux(x: B2);
    |                ^^
    |
-   = help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
 note: type defined here
   --> $DIR/issue-14309.rs:4:1
    |
@@ -69,7 +69,7 @@ error: `extern` block uses type `A` which is not FFI-safe: this struct has unspe
 LL |     fn fred(x: D);
    |                ^
    |
-   = help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
 note: type defined here
   --> $DIR/issue-14309.rs:4:1
    |
diff --git a/src/test/ui/issues/issue-16250.stderr b/src/test/ui/issues/issue-16250.stderr
index a8ff2548b73..142d8e21532 100644
--- a/src/test/ui/issues/issue-16250.stderr
+++ b/src/test/ui/issues/issue-16250.stderr
@@ -10,7 +10,7 @@ note: lint level defined here
 LL | #![deny(warnings)]
    |         ^^^^^^^^
    = note: #[deny(improper_ctypes)] implied by #[deny(warnings)]
-   = help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
 note: type defined here
   --> $DIR/issue-16250.rs:3:1
    |
diff --git a/src/test/ui/issues/issue-31769.rs b/src/test/ui/issues/issue-31769.rs
index 794c1d19893..45eb5e40080 100644
--- a/src/test/ui/issues/issue-31769.rs
+++ b/src/test/ui/issues/issue-31769.rs
@@ -1,4 +1,4 @@
 fn main() {
     #[inline] struct Foo;  //~ ERROR attribute should be applied to function or closure
-    #[repr(C)] fn foo() {} //~ ERROR attribute should be applied to struct, enum or union
+    #[repr(C)] fn foo() {} //~ ERROR attribute should be applied to struct, enum, or union
 }
diff --git a/src/test/ui/issues/issue-31769.stderr b/src/test/ui/issues/issue-31769.stderr
index 51d1f51d1c9..20534e1ae82 100644
--- a/src/test/ui/issues/issue-31769.stderr
+++ b/src/test/ui/issues/issue-31769.stderr
@@ -4,11 +4,11 @@ error[E0518]: attribute should be applied to function or closure
 LL |     #[inline] struct Foo;
    |     ^^^^^^^^^ ----------- not a function or closure
 
-error[E0517]: attribute should be applied to struct, enum or union
+error[E0517]: attribute should be applied to struct, enum, or union
   --> $DIR/issue-31769.rs:3:12
    |
 LL |     #[repr(C)] fn foo() {}
-   |            ^   ----------- not a struct, enum or union
+   |            ^   ----------- not a struct, enum, or union
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-43988.stderr b/src/test/ui/issues/issue-43988.stderr
index c2f0cc6f0ff..339c1a3b8f6 100644
--- a/src/test/ui/issues/issue-43988.stderr
+++ b/src/test/ui/issues/issue-43988.stderr
@@ -32,7 +32,7 @@ error[E0517]: attribute should not be applied to a statement
 LL |     #[repr(nothing)]
    |     ^^^^^^^^^^^^^^^^
 LL |     let _x = 0;
-   |     ----------- not a struct, enum or union
+   |     ----------- not a struct, enum, or union
 
 error[E0517]: attribute should not be applied to an expression
   --> $DIR/issue-43988.rs:18:5
@@ -42,7 +42,7 @@ LL |       #[repr(something_not_real)]
 LL | /     loop {
 LL | |         ()
 LL | |     };
-   | |_____- not defining a struct, enum or union
+   | |_____- not defining a struct, enum, or union
 
 error[E0517]: attribute should not be applied to a statement
   --> $DIR/issue-43988.rs:24:5
@@ -50,7 +50,7 @@ error[E0517]: attribute should not be applied to a statement
 LL |     #[repr]
    |     ^^^^^^^
 LL |     let _y = "123";
-   |     --------------- not a struct, enum or union
+   |     --------------- not a struct, enum, or union
 
 error[E0518]: attribute should be applied to function or closure
   --> $DIR/issue-43988.rs:31:5
@@ -64,7 +64,7 @@ error[E0517]: attribute should not be applied to an expression
   --> $DIR/issue-43988.rs:35:14
    |
 LL |     let _z = #[repr] 1;
-   |              ^^^^^^^ - not defining a struct, enum or union
+   |              ^^^^^^^ - not defining a struct, enum, or union
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/lint/lint-ctypes-enum.rs b/src/test/ui/lint/lint-ctypes-enum.rs
index d3e11d2f7ed..45eeffff7a6 100644
--- a/src/test/ui/lint/lint-ctypes-enum.rs
+++ b/src/test/ui/lint/lint-ctypes-enum.rs
@@ -1,3 +1,4 @@
+#![feature(transparent_enums, transparent_unions)]
 #![deny(improper_ctypes)]
 #![allow(dead_code)]
 
@@ -18,7 +19,17 @@ enum U8 { A, B, C }
 enum Isize { A, B, C }
 
 #[repr(transparent)]
-struct Transparent<T>(T, std::marker::PhantomData<Z>);
+struct TransparentStruct<T>(T, std::marker::PhantomData<Z>);
+
+#[repr(transparent)]
+enum TransparentEnum<T> {
+   Variant(T, std::marker::PhantomData<Z>),
+}
+
+#[repr(transparent)]
+union TransparentUnion<T: Copy> {
+   field: T,
+}
 
 struct Rust<T>(T);
 
@@ -47,7 +58,10 @@ extern {
    fn nonzero_i128(x: Option<num::NonZeroI128>);
    //~^ ERROR 128-bit integers don't currently have a known stable ABI
    fn nonzero_isize(x: Option<num::NonZeroIsize>);
-   fn repr_transparent(x: Option<Transparent<num::NonZeroU8>>);
+   fn transparent_struct(x: Option<TransparentStruct<num::NonZeroU8>>);
+   fn transparent_enum(x: Option<TransparentEnum<num::NonZeroU8>>);
+   fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
+   //~^ ERROR enum has no representation hint
    fn repr_rust(x: Option<Rust<num::NonZeroU8>>); //~ ERROR enum has no representation hint
    fn no_result(x: Result<(), num::NonZeroI32>); //~ ERROR enum has no representation hint
 }
diff --git a/src/test/ui/lint/lint-ctypes-enum.stderr b/src/test/ui/lint/lint-ctypes-enum.stderr
index 6b807f48aaa..2a60cd12d99 100644
--- a/src/test/ui/lint/lint-ctypes-enum.stderr
+++ b/src/test/ui/lint/lint-ctypes-enum.stderr
@@ -1,74 +1,82 @@
 error: `extern` block uses type `U` which is not FFI-safe: enum has no representation hint
-  --> $DIR/lint-ctypes-enum.rs:27:13
+  --> $DIR/lint-ctypes-enum.rs:38:13
    |
 LL |    fn uf(x: U);
    |             ^
    |
 note: lint level defined here
-  --> $DIR/lint-ctypes-enum.rs:1:9
+  --> $DIR/lint-ctypes-enum.rs:2:9
    |
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
-   = help: consider adding a #[repr(...)] attribute to this enum
+   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
 note: type defined here
-  --> $DIR/lint-ctypes-enum.rs:7:1
+  --> $DIR/lint-ctypes-enum.rs:8:1
    |
 LL | enum U { A }
    | ^^^^^^^^^^^^
 
 error: `extern` block uses type `B` which is not FFI-safe: enum has no representation hint
-  --> $DIR/lint-ctypes-enum.rs:28:13
+  --> $DIR/lint-ctypes-enum.rs:39:13
    |
 LL |    fn bf(x: B);
    |             ^
    |
-   = help: consider adding a #[repr(...)] attribute to this enum
+   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
 note: type defined here
-  --> $DIR/lint-ctypes-enum.rs:8:1
+  --> $DIR/lint-ctypes-enum.rs:9:1
    |
 LL | enum B { C, D }
    | ^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `T` which is not FFI-safe: enum has no representation hint
-  --> $DIR/lint-ctypes-enum.rs:29:13
+  --> $DIR/lint-ctypes-enum.rs:40:13
    |
 LL |    fn tf(x: T);
    |             ^
    |
-   = help: consider adding a #[repr(...)] attribute to this enum
+   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
 note: type defined here
-  --> $DIR/lint-ctypes-enum.rs:9:1
+  --> $DIR/lint-ctypes-enum.rs:10:1
    |
 LL | enum T { E, F, G }
    | ^^^^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `u128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
-  --> $DIR/lint-ctypes-enum.rs:40:23
+  --> $DIR/lint-ctypes-enum.rs:51:23
    |
 LL |    fn nonzero_u128(x: Option<num::NonZeroU128>);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `i128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
-  --> $DIR/lint-ctypes-enum.rs:47:23
+  --> $DIR/lint-ctypes-enum.rs:58:23
    |
 LL |    fn nonzero_i128(x: Option<num::NonZeroI128>);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^
 
+error: `extern` block uses type `std::option::Option<TransparentUnion<std::num::NonZeroU8>>` which is not FFI-safe: enum has no representation hint
+  --> $DIR/lint-ctypes-enum.rs:63:28
+   |
+LL |    fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+
 error: `extern` block uses type `std::option::Option<Rust<std::num::NonZeroU8>>` which is not FFI-safe: enum has no representation hint
-  --> $DIR/lint-ctypes-enum.rs:51:20
+  --> $DIR/lint-ctypes-enum.rs:65:20
    |
 LL |    fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: consider adding a #[repr(...)] attribute to this enum
+   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
 
 error: `extern` block uses type `std::result::Result<(), std::num::NonZeroI32>` which is not FFI-safe: enum has no representation hint
-  --> $DIR/lint-ctypes-enum.rs:52:20
+  --> $DIR/lint-ctypes-enum.rs:66:20
    |
 LL |    fn no_result(x: Result<(), num::NonZeroI32>);
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: consider adding a #[repr(...)] attribute to this enum
+   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
 
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/lint/lint-ctypes.stderr b/src/test/ui/lint/lint-ctypes.stderr
index 03c18e4530b..c78463beb65 100644
--- a/src/test/ui/lint/lint-ctypes.stderr
+++ b/src/test/ui/lint/lint-ctypes.stderr
@@ -9,7 +9,7 @@ note: lint level defined here
    |
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
-   = help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
 note: type defined here
   --> $DIR/lint-ctypes.rs:24:1
    |
@@ -22,7 +22,7 @@ error: `extern` block uses type `Foo` which is not FFI-safe: this struct has uns
 LL |     pub fn ptr_type2(size: *const Foo);
    |                            ^^^^^^^^^^
    |
-   = help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
 note: type defined here
   --> $DIR/lint-ctypes.rs:24:1
    |
@@ -51,7 +51,7 @@ error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: th
 LL |     pub fn box_type(p: Box<u32>);
    |                        ^^^^^^^^
    |
-   = help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
 
 error: `extern` block uses type `char` which is not FFI-safe: the `char` type has no C equivalent
   --> $DIR/lint-ctypes.rs:51:25
@@ -142,7 +142,7 @@ error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: th
 LL |     pub fn fn_contained(p: RustBadRet);
    |                            ^^^^^^^^^^
    |
-   = help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
 
 error: `extern` block uses type `i128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
   --> $DIR/lint-ctypes.rs:64:32
@@ -164,7 +164,7 @@ error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: th
 LL |     pub fn transparent_fn(p: TransparentBadFn);
    |                              ^^^^^^^^^^^^^^^^
    |
-   = help: consider adding a #[repr(C)] or #[repr(transparent)] attribute to this struct
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
 
 error: aborting due to 20 previous errors
 
diff --git a/src/test/ui/repr/repr-transparent-other-items.rs b/src/test/ui/repr/repr-transparent-other-items.rs
index 392e7c9de4d..c3d772f6266 100644
--- a/src/test/ui/repr/repr-transparent-other-items.rs
+++ b/src/test/ui/repr/repr-transparent-other-items.rs
@@ -1,26 +1,5 @@
 // See also repr-transparent.rs
 
-#[repr(transparent)] //~ ERROR unsupported representation for zero-variant enum
-enum Void {}         //~| ERROR should be applied to struct
-
-#[repr(transparent)] //~ ERROR should be applied to struct
-enum FieldlessEnum {
-    Foo,
-    Bar,
-}
-
-#[repr(transparent)] //~ ERROR should be applied to struct
-enum Enum {
-    Foo(String),
-    Bar(u32),
-}
-
-#[repr(transparent)] //~ ERROR should be applied to struct
-union Foo {
-    u: u32,
-    s: i32
-}
-
 #[repr(transparent)] //~ ERROR should be applied to struct
 fn cant_repr_this() {}
 
diff --git a/src/test/ui/repr/repr-transparent-other-items.stderr b/src/test/ui/repr/repr-transparent-other-items.stderr
index 24fa309a2fb..03df3569b42 100644
--- a/src/test/ui/repr/repr-transparent-other-items.stderr
+++ b/src/test/ui/repr/repr-transparent-other-items.stderr
@@ -1,69 +1,19 @@
-error[E0517]: attribute should be applied to struct
+error[E0517]: attribute should be applied to struct, enum, or union
   --> $DIR/repr-transparent-other-items.rs:3:8
    |
 LL | #[repr(transparent)]
    |        ^^^^^^^^^^^
-LL | enum Void {}
-   | ------------ not a struct
-
-error[E0517]: attribute should be applied to struct
-  --> $DIR/repr-transparent-other-items.rs:6:8
-   |
-LL |   #[repr(transparent)]
-   |          ^^^^^^^^^^^
-LL | / enum FieldlessEnum {
-LL | |     Foo,
-LL | |     Bar,
-LL | | }
-   | |_- not a struct
-
-error[E0517]: attribute should be applied to struct
-  --> $DIR/repr-transparent-other-items.rs:12:8
-   |
-LL |   #[repr(transparent)]
-   |          ^^^^^^^^^^^
-LL | / enum Enum {
-LL | |     Foo(String),
-LL | |     Bar(u32),
-LL | | }
-   | |_- not a struct
-
-error[E0517]: attribute should be applied to struct
-  --> $DIR/repr-transparent-other-items.rs:18:8
-   |
-LL |   #[repr(transparent)]
-   |          ^^^^^^^^^^^
-LL | / union Foo {
-LL | |     u: u32,
-LL | |     s: i32
-LL | | }
-   | |_- not a struct
-
-error[E0517]: attribute should be applied to struct
-  --> $DIR/repr-transparent-other-items.rs:24:8
-   |
-LL | #[repr(transparent)]
-   |        ^^^^^^^^^^^
 LL | fn cant_repr_this() {}
-   | ---------------------- not a struct
+   | ---------------------- not a struct, enum, or union
 
-error[E0517]: attribute should be applied to struct
-  --> $DIR/repr-transparent-other-items.rs:27:8
+error[E0517]: attribute should be applied to struct, enum, or union
+  --> $DIR/repr-transparent-other-items.rs:6:8
    |
 LL | #[repr(transparent)]
    |        ^^^^^^^^^^^
 LL | static CANT_REPR_THIS: u32 = 0;
-   | ------------------------------- not a struct
-
-error[E0084]: unsupported representation for zero-variant enum
-  --> $DIR/repr-transparent-other-items.rs:3:1
-   |
-LL | #[repr(transparent)]
-   | ^^^^^^^^^^^^^^^^^^^^
-LL | enum Void {}
-   | ------------ zero-variant enum
+   | ------------------------------- not a struct, enum, or union
 
-error: aborting due to 7 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0084, E0517.
-For more information about an error, try `rustc --explain E0084`.
+For more information about this error, try `rustc --explain E0517`.
diff --git a/src/test/ui/repr/repr-transparent.rs b/src/test/ui/repr/repr-transparent.rs
index 66d39ff9bb5..730d428ff50 100644
--- a/src/test/ui/repr/repr-transparent.rs
+++ b/src/test/ui/repr/repr-transparent.rs
@@ -3,7 +3,7 @@
 // - repr-transparent-other-reprs.rs
 // - repr-transparent-other-items.rs
 
-#![feature(repr_align)]
+#![feature(repr_align, transparent_enums, transparent_unions)]
 
 use std::marker::PhantomData;
 
@@ -39,4 +39,36 @@ struct ZstAlign32<T>(PhantomData<T>);
 #[repr(transparent)]
 struct GenericAlign<T>(ZstAlign32<T>, u32); //~ ERROR alignment larger than 1
 
+#[repr(transparent)] //~ ERROR unsupported representation for zero-variant enum
+enum Void {}
+//~^ ERROR transparent enum needs exactly one variant, but has 0
+
+#[repr(transparent)]
+enum FieldlessEnum { //~ ERROR transparent enum needs exactly one non-zero-sized field, but has 0
+    Foo,
+}
+
+#[repr(transparent)]
+enum TooManyFieldsEnum {
+    Foo(u32, String),
+}
+//~^^^ ERROR transparent enum needs exactly one non-zero-sized field, but has 2
+
+#[repr(transparent)]
+enum TooManyVariants { //~ ERROR transparent enum needs exactly one variant, but has 2
+    Foo(String),
+    Bar,
+}
+
+#[repr(transparent)]
+union UnitUnion { //~ ERROR transparent union needs exactly one non-zero-sized field, but has 0
+    u: (),
+}
+
+#[repr(transparent)]
+union TooManyFields { //~ ERROR transparent union needs exactly one non-zero-sized field, but has 2
+    u: u32,
+    s: i32
+}
+
 fn main() {}
diff --git a/src/test/ui/repr/repr-transparent.stderr b/src/test/ui/repr/repr-transparent.stderr
index 2542a842fe8..ea16bdf5378 100644
--- a/src/test/ui/repr/repr-transparent.stderr
+++ b/src/test/ui/repr/repr-transparent.stderr
@@ -3,32 +3,24 @@ error[E0690]: transparent struct needs exactly one non-zero-sized field, but has
    |
 LL | struct NoFields;
    | ^^^^^^^^^^^^^^^^
-   |
-   = note: non-zero-sized field
 
 error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0
   --> $DIR/repr-transparent.rs:14:1
    |
 LL | struct ContainsOnlyZst(());
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: non-zero-sized field
 
 error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0
   --> $DIR/repr-transparent.rs:17:1
    |
 LL | struct ContainsOnlyZstArray([bool; 0]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: non-zero-sized field
 
 error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0
   --> $DIR/repr-transparent.rs:20:1
    |
 LL | struct ContainsMultipleZst(PhantomData<*const i32>, NoFields);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: non-zero-sized field
 
 error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 2
   --> $DIR/repr-transparent.rs:24:1
@@ -36,7 +28,7 @@ error[E0690]: transparent struct needs exactly one non-zero-sized field, but has
 LL | struct MultipleNonZst(u8, u8);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: non-zero-sized field
+note: the following non-zero-sized fields exist on `MultipleNonZst`:
   --> $DIR/repr-transparent.rs:24:23
    |
 LL | struct MultipleNonZst(u8, u8);
@@ -48,7 +40,7 @@ error[E0690]: transparent struct needs exactly one non-zero-sized field, but has
 LL | pub struct StructWithProjection(f32, <f32 as Mirror>::It);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-note: non-zero-sized field
+note: the following non-zero-sized fields exist on `StructWithProjection`:
   --> $DIR/repr-transparent.rs:30:33
    |
 LL | pub struct StructWithProjection(f32, <f32 as Mirror>::It);
@@ -66,7 +58,85 @@ error[E0691]: zero-sized field in transparent struct has alignment larger than 1
 LL | struct GenericAlign<T>(ZstAlign32<T>, u32);
    |                        ^^^^^^^^^^^^^
 
-error: aborting due to 8 previous errors
+error[E0084]: unsupported representation for zero-variant enum
+  --> $DIR/repr-transparent.rs:42:1
+   |
+LL | #[repr(transparent)]
+   | ^^^^^^^^^^^^^^^^^^^^
+LL | enum Void {}
+   | ------------ zero-variant enum
+
+error[E0731]: transparent enum needs exactly one variant, but has 0
+  --> $DIR/repr-transparent.rs:43:1
+   |
+LL | enum Void {}
+   | ^^^^^^^^^^^^
+
+error[E0690]: the variant of a transparent enum needs exactly one non-zero-sized field, but has 0
+  --> $DIR/repr-transparent.rs:47:1
+   |
+LL | / enum FieldlessEnum {
+LL | |     Foo,
+LL | | }
+   | |_^
+
+error[E0690]: the variant of a transparent enum needs exactly one non-zero-sized field, but has 2
+  --> $DIR/repr-transparent.rs:52:1
+   |
+LL | / enum TooManyFieldsEnum {
+LL | |     Foo(u32, String),
+LL | | }
+   | |_^
+   |
+note: the following non-zero-sized fields exist on `TooManyFieldsEnum`:
+  --> $DIR/repr-transparent.rs:53:9
+   |
+LL |     Foo(u32, String),
+   |         ^^^  ^^^^^^
+
+error[E0731]: transparent enum needs exactly one variant, but has 2
+  --> $DIR/repr-transparent.rs:58:1
+   |
+LL | / enum TooManyVariants {
+LL | |     Foo(String),
+LL | |     Bar,
+LL | | }
+   | |_^
+   |
+note: the following variants exist on `TooManyVariants`
+  --> $DIR/repr-transparent.rs:59:5
+   |
+LL |     Foo(String),
+   |     ^^^^^^^^^^^
+LL |     Bar,
+   |     ^^^
+
+error[E0690]: transparent union needs exactly one non-zero-sized field, but has 0
+  --> $DIR/repr-transparent.rs:64:1
+   |
+LL | / union UnitUnion {
+LL | |     u: (),
+LL | | }
+   | |_^
+
+error[E0690]: transparent union needs exactly one non-zero-sized field, but has 2
+  --> $DIR/repr-transparent.rs:69:1
+   |
+LL | / union TooManyFields {
+LL | |     u: u32,
+LL | |     s: i32
+LL | | }
+   | |_^
+   |
+note: the following non-zero-sized fields exist on `TooManyFields`:
+  --> $DIR/repr-transparent.rs:70:5
+   |
+LL |     u: u32,
+   |     ^^^^^^
+LL |     s: i32
+   |     ^^^^^^
+
+error: aborting due to 15 previous errors
 
-Some errors have detailed explanations: E0690, E0691.
-For more information about an error, try `rustc --explain E0690`.
+Some errors have detailed explanations: E0084, E0690, E0691, E0731.
+For more information about an error, try `rustc --explain E0084`.
diff --git a/src/test/ui/union/union-repr-c.stderr b/src/test/ui/union/union-repr-c.stderr
index 40d9a50f1fa..c60817a849a 100644
--- a/src/test/ui/union/union-repr-c.stderr
+++ b/src/test/ui/union/union-repr-c.stderr
@@ -9,7 +9,7 @@ note: lint level defined here
    |
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
-   = help: consider adding a #[repr(C)] attribute to this union
+   = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
 note: type defined here
   --> $DIR/union-repr-c.rs:9:1
    |