From 64d98f8ee037282c35007b64c2649055c56af1db Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:03 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- tests/ui/repr/align-with-extern-c-fn.rs | 18 +++ tests/ui/repr/aligned_enum_cast.rs | 25 ++++ tests/ui/repr/attr-usage-repr.rs | 33 +++++ tests/ui/repr/attr-usage-repr.stderr | 35 ++++++ .../auxiliary/repr-transparent-non-exhaustive.rs | 18 +++ tests/ui/repr/invalid_repr_list_help.rs | 17 +++ tests/ui/repr/invalid_repr_list_help.stderr | 35 ++++++ tests/ui/repr/issue-83505-repr-simd.rs | 10 ++ tests/ui/repr/issue-83505-repr-simd.stderr | 30 +++++ tests/ui/repr/issue-83921-ice.rs | 34 +++++ tests/ui/repr/issue-83921-ice.stderr | 46 +++++++ tests/ui/repr/repr-align-assign.fixed | 13 ++ tests/ui/repr/repr-align-assign.rs | 13 ++ tests/ui/repr/repr-align-assign.stderr | 27 ++++ tests/ui/repr/repr-align.rs | 33 +++++ tests/ui/repr/repr-align.stderr | 75 +++++++++++ tests/ui/repr/repr-disallow-on-variant.rs | 9 ++ tests/ui/repr/repr-disallow-on-variant.stderr | 12 ++ tests/ui/repr/repr-packed-contains-align.rs | 53 ++++++++ tests/ui/repr/repr-packed-contains-align.stderr | 139 +++++++++++++++++++++ tests/ui/repr/repr-transparent-issue-87496.rs | 12 ++ tests/ui/repr/repr-transparent-issue-87496.stderr | 16 +++ tests/ui/repr/repr-transparent-non-exhaustive.rs | 96 ++++++++++++++ .../ui/repr/repr-transparent-non-exhaustive.stderr | 127 +++++++++++++++++++ tests/ui/repr/repr-transparent-other-items.rs | 9 ++ tests/ui/repr/repr-transparent-other-items.stderr | 19 +++ tests/ui/repr/repr-transparent-other-reprs.rs | 18 +++ tests/ui/repr/repr-transparent-other-reprs.stderr | 29 +++++ tests/ui/repr/repr-transparent.rs | 90 +++++++++++++ tests/ui/repr/repr-transparent.stderr | 90 +++++++++++++ tests/ui/repr/repr.rs | 13 ++ tests/ui/repr/repr.stderr | 20 +++ tests/ui/repr/repr_c_int_align.rs | 46 +++++++ .../ui/repr/transparent-enum-too-many-variants.rs | 10 ++ .../repr/transparent-enum-too-many-variants.stderr | 11 ++ 35 files changed, 1281 insertions(+) create mode 100644 tests/ui/repr/align-with-extern-c-fn.rs create mode 100644 tests/ui/repr/aligned_enum_cast.rs create mode 100644 tests/ui/repr/attr-usage-repr.rs create mode 100644 tests/ui/repr/attr-usage-repr.stderr create mode 100644 tests/ui/repr/auxiliary/repr-transparent-non-exhaustive.rs create mode 100644 tests/ui/repr/invalid_repr_list_help.rs create mode 100644 tests/ui/repr/invalid_repr_list_help.stderr create mode 100644 tests/ui/repr/issue-83505-repr-simd.rs create mode 100644 tests/ui/repr/issue-83505-repr-simd.stderr create mode 100644 tests/ui/repr/issue-83921-ice.rs create mode 100644 tests/ui/repr/issue-83921-ice.stderr create mode 100644 tests/ui/repr/repr-align-assign.fixed create mode 100644 tests/ui/repr/repr-align-assign.rs create mode 100644 tests/ui/repr/repr-align-assign.stderr create mode 100644 tests/ui/repr/repr-align.rs create mode 100644 tests/ui/repr/repr-align.stderr create mode 100644 tests/ui/repr/repr-disallow-on-variant.rs create mode 100644 tests/ui/repr/repr-disallow-on-variant.stderr create mode 100644 tests/ui/repr/repr-packed-contains-align.rs create mode 100644 tests/ui/repr/repr-packed-contains-align.stderr create mode 100644 tests/ui/repr/repr-transparent-issue-87496.rs create mode 100644 tests/ui/repr/repr-transparent-issue-87496.stderr create mode 100644 tests/ui/repr/repr-transparent-non-exhaustive.rs create mode 100644 tests/ui/repr/repr-transparent-non-exhaustive.stderr create mode 100644 tests/ui/repr/repr-transparent-other-items.rs create mode 100644 tests/ui/repr/repr-transparent-other-items.stderr create mode 100644 tests/ui/repr/repr-transparent-other-reprs.rs create mode 100644 tests/ui/repr/repr-transparent-other-reprs.stderr create mode 100644 tests/ui/repr/repr-transparent.rs create mode 100644 tests/ui/repr/repr-transparent.stderr create mode 100644 tests/ui/repr/repr.rs create mode 100644 tests/ui/repr/repr.stderr create mode 100644 tests/ui/repr/repr_c_int_align.rs create mode 100644 tests/ui/repr/transparent-enum-too-many-variants.rs create mode 100644 tests/ui/repr/transparent-enum-too-many-variants.stderr (limited to 'tests/ui/repr') diff --git a/tests/ui/repr/align-with-extern-c-fn.rs b/tests/ui/repr/align-with-extern-c-fn.rs new file mode 100644 index 000000000..9e490e27a --- /dev/null +++ b/tests/ui/repr/align-with-extern-c-fn.rs @@ -0,0 +1,18 @@ +// run-pass + +#![allow(stable_features)] +#![allow(unused_variables)] + +// #45662 + +#![feature(repr_align)] + +#[repr(align(16))] +pub struct A(#[allow(unused_tuple_struct_fields)] i64); + +#[allow(improper_ctypes_definitions)] +pub extern "C" fn foo(x: A) {} + +fn main() { + foo(A(0)); +} diff --git a/tests/ui/repr/aligned_enum_cast.rs b/tests/ui/repr/aligned_enum_cast.rs new file mode 100644 index 000000000..1ddf12717 --- /dev/null +++ b/tests/ui/repr/aligned_enum_cast.rs @@ -0,0 +1,25 @@ +// run-pass +// allows aligned custom discriminant enums to cast into other types +// See the issue #92464 for more info +#[allow(dead_code)] +#[repr(align(8))] +enum Aligned { + Zero = 0, + One = 1, +} + +fn main() { + let aligned = Aligned::Zero; + let fo = aligned as u8; + println!("foo {}", fo); + assert_eq!(fo, 0); + println!("{}", tou8(Aligned::Zero)); + assert_eq!(tou8(Aligned::Zero), 0); +} + +#[inline(never)] +fn tou8(al: Aligned) -> u8 { + // Cast behind a function call so ConstProp does not see it + // (so that we can test codegen). + al as u8 +} diff --git a/tests/ui/repr/attr-usage-repr.rs b/tests/ui/repr/attr-usage-repr.rs new file mode 100644 index 000000000..8965decc3 --- /dev/null +++ b/tests/ui/repr/attr-usage-repr.rs @@ -0,0 +1,33 @@ +#![feature(repr_simd)] + +#[repr(C)] //~ ERROR: attribute should be applied to a struct, enum, or union +fn f() {} + +#[repr(C)] +struct SExtern(f64, f64); + +#[repr(packed)] +struct SPacked(f64, f64); + +#[repr(simd)] +struct SSimd(f64, f64); + +#[repr(i8)] //~ ERROR: attribute should be applied to an enum +struct SInt(f64, f64); + +#[repr(C)] +enum EExtern { A, B } + +#[repr(align(8))] +enum EAlign { A, B } + +#[repr(packed)] //~ ERROR: attribute should be applied to a struct +enum EPacked { A, B } + +#[repr(simd)] //~ ERROR: attribute should be applied to a struct +enum ESimd { A, B } + +#[repr(i8)] +enum EInt { A, B } + +fn main() {} diff --git a/tests/ui/repr/attr-usage-repr.stderr b/tests/ui/repr/attr-usage-repr.stderr new file mode 100644 index 000000000..42f65625a --- /dev/null +++ b/tests/ui/repr/attr-usage-repr.stderr @@ -0,0 +1,35 @@ +error[E0517]: attribute should be applied to a struct, enum, or union + --> $DIR/attr-usage-repr.rs:3:8 + | +LL | #[repr(C)] + | ^ +LL | fn f() {} + | --------- not a struct, enum, or union + +error[E0517]: attribute should be applied to an enum + --> $DIR/attr-usage-repr.rs:15:8 + | +LL | #[repr(i8)] + | ^^ +LL | struct SInt(f64, f64); + | ---------------------- not an enum + +error[E0517]: attribute should be applied to a struct or union + --> $DIR/attr-usage-repr.rs:24:8 + | +LL | #[repr(packed)] + | ^^^^^^ +LL | enum EPacked { A, B } + | --------------------- not a struct or union + +error[E0517]: attribute should be applied to a struct + --> $DIR/attr-usage-repr.rs:27:8 + | +LL | #[repr(simd)] + | ^^^^ +LL | enum ESimd { A, B } + | ------------------- not a struct + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0517`. diff --git a/tests/ui/repr/auxiliary/repr-transparent-non-exhaustive.rs b/tests/ui/repr/auxiliary/repr-transparent-non-exhaustive.rs new file mode 100644 index 000000000..4bf6b54fe --- /dev/null +++ b/tests/ui/repr/auxiliary/repr-transparent-non-exhaustive.rs @@ -0,0 +1,18 @@ +#![crate_type = "lib"] + +pub struct Private { _priv: () } + +#[non_exhaustive] +pub struct NonExhaustive {} + +#[non_exhaustive] +pub enum NonExhaustiveEnum {} + +pub enum NonExhaustiveVariant { + #[non_exhaustive] + A, +} + +pub struct ExternalIndirection { + pub x: T, +} diff --git a/tests/ui/repr/invalid_repr_list_help.rs b/tests/ui/repr/invalid_repr_list_help.rs new file mode 100644 index 000000000..c32098453 --- /dev/null +++ b/tests/ui/repr/invalid_repr_list_help.rs @@ -0,0 +1,17 @@ +#![crate_type = "lib"] + +#[repr(uwu)] //~ERROR: unrecognized representation hint +pub struct OwO; + +#[repr(uwu = "a")] //~ERROR: unrecognized representation hint +pub struct OwO2(i32); + +#[repr(uwu(4))] //~ERROR: unrecognized representation hint +pub struct OwO3 { + x: i32, +} + +#[repr(uwu, u8)] //~ERROR: unrecognized representation hint +pub enum OwO4 { + UwU = 1, +} diff --git a/tests/ui/repr/invalid_repr_list_help.stderr b/tests/ui/repr/invalid_repr_list_help.stderr new file mode 100644 index 000000000..2acd56d9a --- /dev/null +++ b/tests/ui/repr/invalid_repr_list_help.stderr @@ -0,0 +1,35 @@ +error[E0552]: unrecognized representation hint + --> $DIR/invalid_repr_list_help.rs:3:8 + | +LL | #[repr(uwu)] + | ^^^ + | + = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize` + +error[E0552]: unrecognized representation hint + --> $DIR/invalid_repr_list_help.rs:6:8 + | +LL | #[repr(uwu = "a")] + | ^^^^^^^^^ + | + = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize` + +error[E0552]: unrecognized representation hint + --> $DIR/invalid_repr_list_help.rs:9:8 + | +LL | #[repr(uwu(4))] + | ^^^^^^ + | + = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize` + +error[E0552]: unrecognized representation hint + --> $DIR/invalid_repr_list_help.rs:14:8 + | +LL | #[repr(uwu, u8)] + | ^^^ + | + = help: valid reprs are `C`, `align`, `packed`, `transparent`, `simd`, `i8`, `u8`, `i16`, `u16`, `i32`, `u32`, `i64`, `u64`, `i128`, `u128`, `isize`, `usize` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0552`. diff --git a/tests/ui/repr/issue-83505-repr-simd.rs b/tests/ui/repr/issue-83505-repr-simd.rs new file mode 100644 index 000000000..280b771d0 --- /dev/null +++ b/tests/ui/repr/issue-83505-repr-simd.rs @@ -0,0 +1,10 @@ +// Regression test for the ICE described in #83505. + +#![crate_type="lib"] + +#[repr(simd)] +//~^ ERROR: attribute should be applied to a struct [E0517] +//~| ERROR: unsupported representation for zero-variant enum [E0084] +enum Es {} +static CLs: Es; +//~^ ERROR: free static item without body diff --git a/tests/ui/repr/issue-83505-repr-simd.stderr b/tests/ui/repr/issue-83505-repr-simd.stderr new file mode 100644 index 000000000..df99baaf5 --- /dev/null +++ b/tests/ui/repr/issue-83505-repr-simd.stderr @@ -0,0 +1,30 @@ +error: free static item without body + --> $DIR/issue-83505-repr-simd.rs:9:1 + | +LL | static CLs: Es; + | ^^^^^^^^^^^^^^- + | | + | help: provide a definition for the static: `= ;` + +error[E0517]: attribute should be applied to a struct + --> $DIR/issue-83505-repr-simd.rs:5:8 + | +LL | #[repr(simd)] + | ^^^^ +... +LL | enum Es {} + | ---------- not a struct + +error[E0084]: unsupported representation for zero-variant enum + --> $DIR/issue-83505-repr-simd.rs:5:1 + | +LL | #[repr(simd)] + | ^^^^^^^^^^^^^ +... +LL | enum Es {} + | ------- zero-variant enum + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0084, E0517. +For more information about an error, try `rustc --explain E0084`. diff --git a/tests/ui/repr/issue-83921-ice.rs b/tests/ui/repr/issue-83921-ice.rs new file mode 100644 index 000000000..70583eb9b --- /dev/null +++ b/tests/ui/repr/issue-83921-ice.rs @@ -0,0 +1,34 @@ +// Regression test for various ICEs inspired by +// https://github.com/rust-lang/rust/issues/83921#issuecomment-814640734 + +// compile-flags: -Zdeduplicate-diagnostics=yes + +#[repr(packed())] +//~^ ERROR: incorrect `repr(packed)` attribute format +struct S1; + +#[repr(align)] +//~^ ERROR: invalid `repr(align)` attribute +struct S2; + +#[repr(align(2, 4))] +//~^ ERROR: incorrect `repr(align)` attribute format +struct S3; + +#[repr(align())] +//~^ ERROR: incorrect `repr(align)` attribute format +struct S4; + +#[repr(i8())] +//~^ ERROR: invalid representation hint +enum E1 { A, B } + +#[repr(u32(42))] +//~^ ERROR: invalid representation hint +enum E2 { A, B } + +#[repr(i64 = 2)] +//~^ ERROR: invalid representation hint +enum E3 { A, B } + +fn main() {} diff --git a/tests/ui/repr/issue-83921-ice.stderr b/tests/ui/repr/issue-83921-ice.stderr new file mode 100644 index 000000000..32c450410 --- /dev/null +++ b/tests/ui/repr/issue-83921-ice.stderr @@ -0,0 +1,46 @@ +error[E0552]: incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all + --> $DIR/issue-83921-ice.rs:6:8 + | +LL | #[repr(packed())] + | ^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: `align` needs an argument + --> $DIR/issue-83921-ice.rs:10:8 + | +LL | #[repr(align)] + | ^^^^^ help: supply an argument here: `align(...)` + +error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses + --> $DIR/issue-83921-ice.rs:14:8 + | +LL | #[repr(align(2, 4))] + | ^^^^^^^^^^^ + +error[E0693]: incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses + --> $DIR/issue-83921-ice.rs:18:8 + | +LL | #[repr(align())] + | ^^^^^^^ + +error[E0552]: invalid representation hint: `i8` does not take a parenthesized argument list + --> $DIR/issue-83921-ice.rs:22:8 + | +LL | #[repr(i8())] + | ^^^^ + +error[E0552]: invalid representation hint: `u32` does not take a parenthesized argument list + --> $DIR/issue-83921-ice.rs:26:8 + | +LL | #[repr(u32(42))] + | ^^^^^^^ + +error[E0552]: invalid representation hint: `i64` does not take a value + --> $DIR/issue-83921-ice.rs:30:8 + | +LL | #[repr(i64 = 2)] + | ^^^^^^^ + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0552, E0589, E0693. +For more information about an error, try `rustc --explain E0552`. diff --git a/tests/ui/repr/repr-align-assign.fixed b/tests/ui/repr/repr-align-assign.fixed new file mode 100644 index 000000000..59ca22e97 --- /dev/null +++ b/tests/ui/repr/repr-align-assign.fixed @@ -0,0 +1,13 @@ +// run-rustfix + +#![allow(dead_code)] + +#[repr(align(8))] //~ ERROR incorrect `repr(align)` attribute format + //~| ERROR incorrect `repr(align)` attribute format +struct A(u64); + +#[repr(align(8))] //~ ERROR incorrect `repr(align)` attribute format + //~| ERROR incorrect `repr(align)` attribute format +struct B(u64); + +fn main() {} diff --git a/tests/ui/repr/repr-align-assign.rs b/tests/ui/repr/repr-align-assign.rs new file mode 100644 index 000000000..6b7799297 --- /dev/null +++ b/tests/ui/repr/repr-align-assign.rs @@ -0,0 +1,13 @@ +// run-rustfix + +#![allow(dead_code)] + +#[repr(align=8)] //~ ERROR incorrect `repr(align)` attribute format + //~| ERROR incorrect `repr(align)` attribute format +struct A(u64); + +#[repr(align="8")] //~ ERROR incorrect `repr(align)` attribute format + //~| ERROR incorrect `repr(align)` attribute format +struct B(u64); + +fn main() {} diff --git a/tests/ui/repr/repr-align-assign.stderr b/tests/ui/repr/repr-align-assign.stderr new file mode 100644 index 000000000..b878ae0d1 --- /dev/null +++ b/tests/ui/repr/repr-align-assign.stderr @@ -0,0 +1,27 @@ +error[E0693]: incorrect `repr(align)` attribute format + --> $DIR/repr-align-assign.rs:5:8 + | +LL | #[repr(align=8)] + | ^^^^^^^ help: use parentheses instead: `align(8)` + +error[E0693]: incorrect `repr(align)` attribute format + --> $DIR/repr-align-assign.rs:9:8 + | +LL | #[repr(align="8")] + | ^^^^^^^^^ help: use parentheses instead: `align(8)` + +error[E0693]: incorrect `repr(align)` attribute format + --> $DIR/repr-align-assign.rs:5:8 + | +LL | #[repr(align=8)] + | ^^^^^^^ help: use parentheses instead: `align(8)` + +error[E0693]: incorrect `repr(align)` attribute format + --> $DIR/repr-align-assign.rs:9:8 + | +LL | #[repr(align="8")] + | ^^^^^^^^^ help: use parentheses instead: `align(8)` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0693`. diff --git a/tests/ui/repr/repr-align.rs b/tests/ui/repr/repr-align.rs new file mode 100644 index 000000000..58ecf9a51 --- /dev/null +++ b/tests/ui/repr/repr-align.rs @@ -0,0 +1,33 @@ +#![allow(dead_code)] + +#[repr(align(16.0))] //~ ERROR: invalid `repr(align)` attribute: not an unsuffixed integer + //~| ERROR: invalid `repr(align)` attribute: not an unsuffixed integer +struct S0(i32); + +#[repr(align(15))] //~ ERROR: invalid `repr(align)` attribute: not a power of two + //~| ERROR: invalid `repr(align)` attribute: not a power of two +struct S1(i32); + +#[repr(align(4294967296))] //~ ERROR: invalid `repr(align)` attribute: larger than 2^29 + //~| ERROR: invalid `repr(align)` attribute: larger than 2^29 +struct S2(i32); + +#[repr(align(536870912))] // ok: this is the largest accepted alignment +struct S3(i32); + +#[repr(align(16.0))] //~ ERROR: invalid `repr(align)` attribute: not an unsuffixed integer + //~| ERROR: invalid `repr(align)` attribute: not an unsuffixed integer +enum E0 { A, B } + +#[repr(align(15))] //~ ERROR: invalid `repr(align)` attribute: not a power of two + //~| ERROR: invalid `repr(align)` attribute: not a power of two +enum E1 { A, B } + +#[repr(align(4294967296))] //~ ERROR: invalid `repr(align)` attribute: larger than 2^29 + //~| ERROR: invalid `repr(align)` attribute: larger than 2^29 +enum E2 { A, B } + +#[repr(align(536870912))] // ok: this is the largest accepted alignment +enum E3 { A, B } + +fn main() {} diff --git a/tests/ui/repr/repr-align.stderr b/tests/ui/repr/repr-align.stderr new file mode 100644 index 000000000..900a811bb --- /dev/null +++ b/tests/ui/repr/repr-align.stderr @@ -0,0 +1,75 @@ +error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer + --> $DIR/repr-align.rs:3:8 + | +LL | #[repr(align(16.0))] + | ^^^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: not a power of two + --> $DIR/repr-align.rs:7:8 + | +LL | #[repr(align(15))] + | ^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: larger than 2^29 + --> $DIR/repr-align.rs:11:8 + | +LL | #[repr(align(4294967296))] + | ^^^^^^^^^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer + --> $DIR/repr-align.rs:18:8 + | +LL | #[repr(align(16.0))] + | ^^^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: not a power of two + --> $DIR/repr-align.rs:22:8 + | +LL | #[repr(align(15))] + | ^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: larger than 2^29 + --> $DIR/repr-align.rs:26:8 + | +LL | #[repr(align(4294967296))] + | ^^^^^^^^^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer + --> $DIR/repr-align.rs:3:8 + | +LL | #[repr(align(16.0))] + | ^^^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: not a power of two + --> $DIR/repr-align.rs:7:8 + | +LL | #[repr(align(15))] + | ^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: larger than 2^29 + --> $DIR/repr-align.rs:11:8 + | +LL | #[repr(align(4294967296))] + | ^^^^^^^^^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: not an unsuffixed integer + --> $DIR/repr-align.rs:18:8 + | +LL | #[repr(align(16.0))] + | ^^^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: not a power of two + --> $DIR/repr-align.rs:22:8 + | +LL | #[repr(align(15))] + | ^^^^^^^^^ + +error[E0589]: invalid `repr(align)` attribute: larger than 2^29 + --> $DIR/repr-align.rs:26:8 + | +LL | #[repr(align(4294967296))] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0589`. diff --git a/tests/ui/repr/repr-disallow-on-variant.rs b/tests/ui/repr/repr-disallow-on-variant.rs new file mode 100644 index 000000000..d9bd0b0e3 --- /dev/null +++ b/tests/ui/repr/repr-disallow-on-variant.rs @@ -0,0 +1,9 @@ +struct Test; + +enum Foo { + #[repr(u8)] + //~^ ERROR attribute should be applied to an enum + Variant, +} + +fn main() {} diff --git a/tests/ui/repr/repr-disallow-on-variant.stderr b/tests/ui/repr/repr-disallow-on-variant.stderr new file mode 100644 index 000000000..f7e4dcc9d --- /dev/null +++ b/tests/ui/repr/repr-disallow-on-variant.stderr @@ -0,0 +1,12 @@ +error[E0517]: attribute should be applied to an enum + --> $DIR/repr-disallow-on-variant.rs:4:12 + | +LL | #[repr(u8)] + | ^^ +LL | +LL | Variant, + | ------- not an enum + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0517`. diff --git a/tests/ui/repr/repr-packed-contains-align.rs b/tests/ui/repr/repr-packed-contains-align.rs new file mode 100644 index 000000000..bef5c7d8c --- /dev/null +++ b/tests/ui/repr/repr-packed-contains-align.rs @@ -0,0 +1,53 @@ +#![allow(dead_code)] + +#[repr(align(16))] +#[derive(Clone, Copy)] +struct SA(i32); + +#[derive(Clone, Copy)] +struct SB(SA); + +#[repr(align(16))] +#[derive(Clone, Copy)] +union UA { + i: i32 +} + +#[derive(Clone, Copy)] +union UB { + a: UA +} + +#[repr(packed)] +struct SC(SA); //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type + +#[repr(packed)] +struct SD(SB); //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type + +#[repr(packed)] +struct SE(UA); //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type + +#[repr(packed)] +struct SF(UB); //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type + +#[repr(packed)] +union UC { //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type + a: UA +} + +#[repr(packed)] +union UD { //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type + n: UB +} + +#[repr(packed)] +union UE { //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type + a: SA +} + +#[repr(packed)] +union UF { //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type + n: SB +} + +fn main() {} diff --git a/tests/ui/repr/repr-packed-contains-align.stderr b/tests/ui/repr/repr-packed-contains-align.stderr new file mode 100644 index 000000000..4c3a960ca --- /dev/null +++ b/tests/ui/repr/repr-packed-contains-align.stderr @@ -0,0 +1,139 @@ +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type + --> $DIR/repr-packed-contains-align.rs:22:1 + | +LL | struct SC(SA); + | ^^^^^^^^^ + | +note: `SA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:5:1 + | +LL | struct SA(i32); + | ^^^^^^^^^ + +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type + --> $DIR/repr-packed-contains-align.rs:25:1 + | +LL | struct SD(SB); + | ^^^^^^^^^ + | +note: `SA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:5:1 + | +LL | struct SA(i32); + | ^^^^^^^^^ +note: `SD` contains a field of type `SB` + --> $DIR/repr-packed-contains-align.rs:25:11 + | +LL | struct SD(SB); + | ^^ +note: ...which contains a field of type `SA` + --> $DIR/repr-packed-contains-align.rs:8:11 + | +LL | struct SB(SA); + | ^^ + +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type + --> $DIR/repr-packed-contains-align.rs:28:1 + | +LL | struct SE(UA); + | ^^^^^^^^^ + | +note: `UA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:12:1 + | +LL | union UA { + | ^^^^^^^^ + +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type + --> $DIR/repr-packed-contains-align.rs:31:1 + | +LL | struct SF(UB); + | ^^^^^^^^^ + | +note: `UA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:12:1 + | +LL | union UA { + | ^^^^^^^^ +note: `SF` contains a field of type `UB` + --> $DIR/repr-packed-contains-align.rs:31:11 + | +LL | struct SF(UB); + | ^^ +note: ...which contains a field of type `UA` + --> $DIR/repr-packed-contains-align.rs:18:5 + | +LL | a: UA + | ^ + +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type + --> $DIR/repr-packed-contains-align.rs:34:1 + | +LL | union UC { + | ^^^^^^^^ + | +note: `UA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:12:1 + | +LL | union UA { + | ^^^^^^^^ + +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type + --> $DIR/repr-packed-contains-align.rs:39:1 + | +LL | union UD { + | ^^^^^^^^ + | +note: `UA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:12:1 + | +LL | union UA { + | ^^^^^^^^ +note: `UD` contains a field of type `UB` + --> $DIR/repr-packed-contains-align.rs:40:5 + | +LL | n: UB + | ^ +note: ...which contains a field of type `UA` + --> $DIR/repr-packed-contains-align.rs:18:5 + | +LL | a: UA + | ^ + +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type + --> $DIR/repr-packed-contains-align.rs:44:1 + | +LL | union UE { + | ^^^^^^^^ + | +note: `SA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:5:1 + | +LL | struct SA(i32); + | ^^^^^^^^^ + +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type + --> $DIR/repr-packed-contains-align.rs:49:1 + | +LL | union UF { + | ^^^^^^^^ + | +note: `SA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:5:1 + | +LL | struct SA(i32); + | ^^^^^^^^^ +note: `UF` contains a field of type `SB` + --> $DIR/repr-packed-contains-align.rs:50:5 + | +LL | n: SB + | ^ +note: ...which contains a field of type `SA` + --> $DIR/repr-packed-contains-align.rs:8:11 + | +LL | struct SB(SA); + | ^^ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0588`. diff --git a/tests/ui/repr/repr-transparent-issue-87496.rs b/tests/ui/repr/repr-transparent-issue-87496.rs new file mode 100644 index 000000000..a4dd45c63 --- /dev/null +++ b/tests/ui/repr/repr-transparent-issue-87496.rs @@ -0,0 +1,12 @@ +// Regression test for the ICE described in #87496. + +// check-pass + +#[repr(transparent)] +struct TransparentCustomZst(()); +extern "C" { + fn good17(p: TransparentCustomZst); + //~^ WARNING: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe +} + +fn main() {} diff --git a/tests/ui/repr/repr-transparent-issue-87496.stderr b/tests/ui/repr/repr-transparent-issue-87496.stderr new file mode 100644 index 000000000..aee31212b --- /dev/null +++ b/tests/ui/repr/repr-transparent-issue-87496.stderr @@ -0,0 +1,16 @@ +warning: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe + --> $DIR/repr-transparent-issue-87496.rs:8:18 + | +LL | fn good17(p: TransparentCustomZst); + | ^^^^^^^^^^^^^^^^^^^^ not FFI-safe + | + = note: this struct contains only zero-sized fields +note: the type is defined here + --> $DIR/repr-transparent-issue-87496.rs:6:1 + | +LL | struct TransparentCustomZst(()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(improper_ctypes)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/repr/repr-transparent-non-exhaustive.rs b/tests/ui/repr/repr-transparent-non-exhaustive.rs new file mode 100644 index 000000000..506f1dcf3 --- /dev/null +++ b/tests/ui/repr/repr-transparent-non-exhaustive.rs @@ -0,0 +1,96 @@ +#![deny(repr_transparent_external_private_fields)] + +// aux-build: repr-transparent-non-exhaustive.rs +extern crate repr_transparent_non_exhaustive; + +use repr_transparent_non_exhaustive::{ + Private, + NonExhaustive, + NonExhaustiveEnum, + NonExhaustiveVariant, + ExternalIndirection, +}; + +pub struct InternalPrivate { + _priv: (), +} + +#[non_exhaustive] +pub struct InternalNonExhaustive; + +pub struct InternalIndirection { + x: T, +} + +pub type Sized = i32; + +#[repr(transparent)] +pub struct T1(Sized, InternalPrivate); +#[repr(transparent)] +pub struct T2(Sized, InternalNonExhaustive); +#[repr(transparent)] +pub struct T3(Sized, InternalIndirection<(InternalPrivate, InternalNonExhaustive)>); +#[repr(transparent)] +pub struct T4(Sized, ExternalIndirection<(InternalPrivate, InternalNonExhaustive)>); + +#[repr(transparent)] +pub struct T5(Sized, Private); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +#[repr(transparent)] +pub struct T6(Sized, NonExhaustive); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +#[repr(transparent)] +pub struct T7(Sized, NonExhaustiveEnum); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +#[repr(transparent)] +pub struct T8(Sized, NonExhaustiveVariant); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +#[repr(transparent)] +pub struct T9(Sized, InternalIndirection); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +#[repr(transparent)] +pub struct T10(Sized, InternalIndirection); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +#[repr(transparent)] +pub struct T11(Sized, InternalIndirection); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +#[repr(transparent)] +pub struct T12(Sized, InternalIndirection); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +#[repr(transparent)] +pub struct T13(Sized, ExternalIndirection); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +#[repr(transparent)] +pub struct T14(Sized, ExternalIndirection); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +#[repr(transparent)] +pub struct T15(Sized, ExternalIndirection); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +#[repr(transparent)] +pub struct T16(Sized, ExternalIndirection); +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types +//~| WARN this was previously accepted by the compiler + +fn main() {} diff --git a/tests/ui/repr/repr-transparent-non-exhaustive.stderr b/tests/ui/repr/repr-transparent-non-exhaustive.stderr new file mode 100644 index 000000000..16edf59c7 --- /dev/null +++ b/tests/ui/repr/repr-transparent-non-exhaustive.stderr @@ -0,0 +1,127 @@ +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:37:22 + | +LL | pub struct T5(Sized, Private); + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #78586 + = note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future. +note: the lint level is defined here + --> $DIR/repr-transparent-non-exhaustive.rs:1:9 + | +LL | #![deny(repr_transparent_external_private_fields)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:42:22 + | +LL | pub struct T6(Sized, NonExhaustive); + | ^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #78586 + = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. + +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:47:22 + | +LL | pub struct T7(Sized, NonExhaustiveEnum); + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #78586 + = note: this enum contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. + +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:52:22 + | +LL | pub struct T8(Sized, NonExhaustiveVariant); + | ^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #78586 + = note: this enum contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. + +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:57:22 + | +LL | pub struct T9(Sized, InternalIndirection); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #78586 + = note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future. + +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:62:23 + | +LL | pub struct T10(Sized, InternalIndirection); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #78586 + = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. + +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:67:23 + | +LL | pub struct T11(Sized, InternalIndirection); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #78586 + = note: this enum contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. + +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:72:23 + | +LL | pub struct T12(Sized, InternalIndirection); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #78586 + = note: this enum contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. + +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:77:23 + | +LL | pub struct T13(Sized, ExternalIndirection); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #78586 + = note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future. + +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:82:23 + | +LL | pub struct T14(Sized, ExternalIndirection); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #78586 + = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. + +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:87:23 + | +LL | pub struct T15(Sized, ExternalIndirection); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #78586 + = note: this enum contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. + +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types + --> $DIR/repr-transparent-non-exhaustive.rs:92:23 + | +LL | pub struct T16(Sized, ExternalIndirection); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #78586 + = note: this enum contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. + +error: aborting due to 12 previous errors + diff --git a/tests/ui/repr/repr-transparent-other-items.rs b/tests/ui/repr/repr-transparent-other-items.rs new file mode 100644 index 000000000..e537e3e1a --- /dev/null +++ b/tests/ui/repr/repr-transparent-other-items.rs @@ -0,0 +1,9 @@ +// See also repr-transparent.rs + +#[repr(transparent)] //~ ERROR should be applied to a struct +fn cant_repr_this() {} + +#[repr(transparent)] //~ ERROR should be applied to a struct +static CANT_REPR_THIS: u32 = 0; + +fn main() {} diff --git a/tests/ui/repr/repr-transparent-other-items.stderr b/tests/ui/repr/repr-transparent-other-items.stderr new file mode 100644 index 000000000..14e6f13e1 --- /dev/null +++ b/tests/ui/repr/repr-transparent-other-items.stderr @@ -0,0 +1,19 @@ +error[E0517]: attribute should be applied to a struct, enum, or union + --> $DIR/repr-transparent-other-items.rs:3:8 + | +LL | #[repr(transparent)] + | ^^^^^^^^^^^ +LL | fn cant_repr_this() {} + | ---------------------- not a struct, enum, or union + +error[E0517]: attribute should be applied to a 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, enum, or union + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0517`. diff --git a/tests/ui/repr/repr-transparent-other-reprs.rs b/tests/ui/repr/repr-transparent-other-reprs.rs new file mode 100644 index 000000000..0cd0edf32 --- /dev/null +++ b/tests/ui/repr/repr-transparent-other-reprs.rs @@ -0,0 +1,18 @@ +// See also repr-transparent.rs + +#[repr(transparent, C)] //~ ERROR cannot have other repr +struct TransparentPlusC { + ptr: *const u8 +} + +#[repr(transparent, packed)] //~ ERROR cannot have other repr +struct TransparentPlusPacked(*const u8); + +#[repr(transparent, align(2))] //~ ERROR cannot have other repr +struct TransparentPlusAlign(u8); + +#[repr(transparent)] //~ ERROR cannot have other repr +#[repr(C)] +struct SeparateAttributes(*mut u8); + +fn main() {} diff --git a/tests/ui/repr/repr-transparent-other-reprs.stderr b/tests/ui/repr/repr-transparent-other-reprs.stderr new file mode 100644 index 000000000..d92c35811 --- /dev/null +++ b/tests/ui/repr/repr-transparent-other-reprs.stderr @@ -0,0 +1,29 @@ +error[E0692]: transparent struct cannot have other repr hints + --> $DIR/repr-transparent-other-reprs.rs:3:8 + | +LL | #[repr(transparent, C)] + | ^^^^^^^^^^^ ^ + +error[E0692]: transparent struct cannot have other repr hints + --> $DIR/repr-transparent-other-reprs.rs:8:8 + | +LL | #[repr(transparent, packed)] + | ^^^^^^^^^^^ ^^^^^^ + +error[E0692]: transparent struct cannot have other repr hints + --> $DIR/repr-transparent-other-reprs.rs:11:8 + | +LL | #[repr(transparent, align(2))] + | ^^^^^^^^^^^ ^^^^^^^^ + +error[E0692]: transparent struct cannot have other repr hints + --> $DIR/repr-transparent-other-reprs.rs:14:8 + | +LL | #[repr(transparent)] + | ^^^^^^^^^^^ +LL | #[repr(C)] + | ^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0692`. diff --git a/tests/ui/repr/repr-transparent.rs b/tests/ui/repr/repr-transparent.rs new file mode 100644 index 000000000..8c9d1639c --- /dev/null +++ b/tests/ui/repr/repr-transparent.rs @@ -0,0 +1,90 @@ +// This file tests repr(transparent)-related errors reported during typeck. Other errors +// that are reported earlier and therefore preempt these are tested in: +// - repr-transparent-other-reprs.rs +// - repr-transparent-other-items.rs + +#![feature(transparent_unions)] + +use std::marker::PhantomData; + +#[repr(transparent)] +struct NoFields; + +#[repr(transparent)] +struct ContainsOnlyZst(()); + +#[repr(transparent)] +struct ContainsOnlyZstArray([bool; 0]); + +#[repr(transparent)] +struct ContainsMultipleZst(PhantomData<*const i32>, NoFields); + +#[repr(transparent)] +struct ContainsZstAndNonZst((), [i32; 2]); + +#[repr(transparent)] +struct MultipleNonZst(u8, u8); //~ ERROR needs at most one non-zero-sized field + +trait Mirror { type It: ?Sized; } +impl Mirror for T { type It = Self; } + +#[repr(transparent)] +pub struct StructWithProjection(f32, ::It); +//~^ ERROR needs at most one non-zero-sized field + +#[repr(transparent)] +struct NontrivialAlignZst(u32, [u16; 0]); //~ ERROR alignment larger than 1 + +#[repr(align(32))] +struct ZstAlign32(PhantomData); + +#[repr(transparent)] +struct GenericAlign(ZstAlign32, 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 { + Foo, +} + +#[repr(transparent)] +enum UnitFieldEnum { + Foo(()), +} + +#[repr(transparent)] +enum TooManyFieldsEnum { + Foo(u32, String), +} +//~^^^ ERROR transparent enum needs at most one non-zero-sized field, but has 2 + +#[repr(transparent)] +enum MultipleVariants { //~ ERROR transparent enum needs exactly one variant, but has 2 + Foo(String), + Bar, +} + +#[repr(transparent)] +enum NontrivialAlignZstEnum { + Foo(u32, [u16; 0]), //~ ERROR alignment larger than 1 +} + +#[repr(transparent)] +enum GenericAlignEnum { + Foo { bar: ZstAlign32, baz: u32 } //~ ERROR alignment larger than 1 +} + +#[repr(transparent)] +union UnitUnion { + u: (), +} + +#[repr(transparent)] +union TooManyFields { //~ ERROR transparent union needs at most one non-zero-sized field, but has 2 + u: u32, + s: i32 +} + +fn main() {} diff --git a/tests/ui/repr/repr-transparent.stderr b/tests/ui/repr/repr-transparent.stderr new file mode 100644 index 000000000..f1c570b95 --- /dev/null +++ b/tests/ui/repr/repr-transparent.stderr @@ -0,0 +1,90 @@ +error[E0690]: transparent struct needs at most one non-zero-sized field, but has 2 + --> $DIR/repr-transparent.rs:26:1 + | +LL | struct MultipleNonZst(u8, u8); + | ^^^^^^^^^^^^^^^^^^^^^ -- -- this field is non-zero-sized + | | | + | | this field is non-zero-sized + | needs at most one non-zero-sized field, but has 2 + +error[E0690]: transparent struct needs at most one non-zero-sized field, but has 2 + --> $DIR/repr-transparent.rs:32:1 + | +LL | pub struct StructWithProjection(f32, ::It); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --- ------------------- this field is non-zero-sized + | | | + | | this field is non-zero-sized + | needs at most one non-zero-sized field, but has 2 + +error[E0691]: zero-sized field in transparent struct has alignment larger than 1 + --> $DIR/repr-transparent.rs:36:32 + | +LL | struct NontrivialAlignZst(u32, [u16; 0]); + | ^^^^^^^^ has alignment larger than 1 + +error[E0691]: zero-sized field in transparent struct has alignment larger than 1 + --> $DIR/repr-transparent.rs:42:24 + | +LL | struct GenericAlign(ZstAlign32, u32); + | ^^^^^^^^^^^^^ has alignment larger than 1 + +error[E0084]: unsupported representation for zero-variant enum + --> $DIR/repr-transparent.rs:44: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:45:1 + | +LL | enum Void {} + | ^^^^^^^^^ needs exactly one variant, but has 0 + +error[E0690]: the variant of a transparent enum needs at most one non-zero-sized field, but has 2 + --> $DIR/repr-transparent.rs:58:1 + | +LL | enum TooManyFieldsEnum { + | ^^^^^^^^^^^^^^^^^^^^^^ needs at most one non-zero-sized field, but has 2 +LL | Foo(u32, String), + | --- ------ this field is non-zero-sized + | | + | this field is non-zero-sized + +error[E0731]: transparent enum needs exactly one variant, but has 2 + --> $DIR/repr-transparent.rs:64:1 + | +LL | enum MultipleVariants { + | ^^^^^^^^^^^^^^^^^^^^^ needs exactly one variant, but has 2 +LL | Foo(String), + | --- +LL | Bar, + | --- too many variants in `MultipleVariants` + +error[E0691]: zero-sized field in transparent enum has alignment larger than 1 + --> $DIR/repr-transparent.rs:71:14 + | +LL | Foo(u32, [u16; 0]), + | ^^^^^^^^ has alignment larger than 1 + +error[E0691]: zero-sized field in transparent enum has alignment larger than 1 + --> $DIR/repr-transparent.rs:76:11 + | +LL | Foo { bar: ZstAlign32, baz: u32 } + | ^^^^^^^^^^^^^^^^^^ has alignment larger than 1 + +error[E0690]: transparent union needs at most one non-zero-sized field, but has 2 + --> $DIR/repr-transparent.rs:85:1 + | +LL | union TooManyFields { + | ^^^^^^^^^^^^^^^^^^^ needs at most one non-zero-sized field, but has 2 +LL | u: u32, + | ------ this field is non-zero-sized +LL | s: i32 + | ------ this field is non-zero-sized + +error: aborting due to 11 previous errors + +Some errors have detailed explanations: E0084, E0690, E0691, E0731. +For more information about an error, try `rustc --explain E0084`. diff --git a/tests/ui/repr/repr.rs b/tests/ui/repr/repr.rs new file mode 100644 index 000000000..564d67326 --- /dev/null +++ b/tests/ui/repr/repr.rs @@ -0,0 +1,13 @@ +#[repr] //~ ERROR malformed `repr` attribute +struct _A {} + +#[repr = "B"] //~ ERROR malformed `repr` attribute +struct _B {} + +#[repr = "C"] //~ ERROR malformed `repr` attribute +struct _C {} + +#[repr(C)] +struct _D {} + +fn main() {} diff --git a/tests/ui/repr/repr.stderr b/tests/ui/repr/repr.stderr new file mode 100644 index 000000000..e0bec6663 --- /dev/null +++ b/tests/ui/repr/repr.stderr @@ -0,0 +1,20 @@ +error: malformed `repr` attribute input + --> $DIR/repr.rs:1:1 + | +LL | #[repr] + | ^^^^^^^ help: must be of the form: `#[repr(C)]` + +error: malformed `repr` attribute input + --> $DIR/repr.rs:4:1 + | +LL | #[repr = "B"] + | ^^^^^^^^^^^^^ help: must be of the form: `#[repr(C)]` + +error: malformed `repr` attribute input + --> $DIR/repr.rs:7:1 + | +LL | #[repr = "C"] + | ^^^^^^^^^^^^^ help: must be of the form: `#[repr(C)]` + +error: aborting due to 3 previous errors + diff --git a/tests/ui/repr/repr_c_int_align.rs b/tests/ui/repr/repr_c_int_align.rs new file mode 100644 index 000000000..fdd14fc2d --- /dev/null +++ b/tests/ui/repr/repr_c_int_align.rs @@ -0,0 +1,46 @@ +// run-pass +// compile-flags: -O + +#![allow(dead_code)] + +#[repr(C, u8)] +enum ReprCu8 { + A(u16), + B, +} + +#[repr(u8)] +enum Repru8 { + A(u16), + B, +} + +#[repr(C)] +struct ReprC { + tag: u8, + padding: u8, + payload: u16, +} + +fn main() { + // Test `repr(C, u8)`. + let r1 = ReprC { tag: 0, padding: 0, payload: 0 }; + let r2 = ReprC { tag: 0, padding: 1, payload: 1 }; + + let t1: &ReprCu8 = unsafe { std::mem::transmute(&r1) }; + let t2: &ReprCu8 = unsafe { std::mem::transmute(&r2) }; + + match (t1, t2) { + (ReprCu8::A(_), ReprCu8::A(_)) => (), + _ => assert!(false) + }; + + // Test `repr(u8)`. + let t1: &Repru8 = unsafe { std::mem::transmute(&r1) }; + let t2: &Repru8 = unsafe { std::mem::transmute(&r2) }; + + match (t1, t2) { + (Repru8::A(_), Repru8::A(_)) => (), + _ => assert!(false) + }; +} diff --git a/tests/ui/repr/transparent-enum-too-many-variants.rs b/tests/ui/repr/transparent-enum-too-many-variants.rs new file mode 100644 index 000000000..0dd4b4e68 --- /dev/null +++ b/tests/ui/repr/transparent-enum-too-many-variants.rs @@ -0,0 +1,10 @@ +use std::mem::size_of; + +#[repr(transparent)] +enum Foo { //~ ERROR E0731 + A(u8), B(u8), +} + +fn main() { + println!("Foo: {}", size_of::()); +} diff --git a/tests/ui/repr/transparent-enum-too-many-variants.stderr b/tests/ui/repr/transparent-enum-too-many-variants.stderr new file mode 100644 index 000000000..fb44757ef --- /dev/null +++ b/tests/ui/repr/transparent-enum-too-many-variants.stderr @@ -0,0 +1,11 @@ +error[E0731]: transparent enum needs exactly one variant, but has 2 + --> $DIR/transparent-enum-too-many-variants.rs:4:1 + | +LL | enum Foo { + | ^^^^^^^^ needs exactly one variant, but has 2 +LL | A(u8), B(u8), + | - - too many variants in `Foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0731`. -- cgit v1.2.3