diff options
| author | bors <bors@rust-lang.org> | 2019-06-11 11:06:38 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-06-11 11:06:38 +0000 |
| commit | 8e948df707ea8a3c88c65bf2ffdcb2f1cf5491be (patch) | |
| tree | caf2cb5f0b7881b6056c37c37c2e73e46b520aab /src/test | |
| parent | 912d22e36965d3c9f6d7f14ca18657182aa1fe54 (diff) | |
| parent | dac1c6a731713ec9e90a1e05b3e2c789faf3f2ba (diff) | |
| download | rust-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')
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 | |
