about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-09-17 15:20:44 +0000
committerbors <bors@rust-lang.org>2023-09-17 15:20:44 +0000
commit203c57dbe20aee67eaa8f7be45d1e4ef0b274109 (patch)
treedff297ec14f9b108ee8c775862f19bb8ff9a51fa /tests
parentdb9c21fd944b942a3a83e1fbce0d7c1c9164bc2a (diff)
parenta6ccd265e6b0cad3107187fccbfee24d08158385 (diff)
downloadrust-203c57dbe20aee67eaa8f7be45d1e4ef0b274109.tar.gz
rust-203c57dbe20aee67eaa8f7be45d1e4ef0b274109.zip
Auto merge of #115334 - RalfJung:transparent-aligned-zst, r=compiler-errors
repr(transparent): it's fine if the one non-1-ZST field is a ZST

This code currently gets rejected:
```rust
#[repr(transparent)]
struct MyType([u16; 0])
```
That clearly seems like a bug to me: `repr(transparent)` [got defined ](https://github.com/rust-lang/rust/issues/77841#issuecomment-716575747) as having any number of 1-ZST fields plus optionally one more field; `MyType` clearly satisfies that definition.

This PR changes the `repr(transparent)` logic to actually match that definition.
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/repr/repr-transparent.rs23
-rw-r--r--tests/ui/repr/repr-transparent.stderr82
2 files changed, 61 insertions, 44 deletions
diff --git a/tests/ui/repr/repr-transparent.rs b/tests/ui/repr/repr-transparent.rs
index 8c9d1639c0a..87cf59ce9af 100644
--- a/tests/ui/repr/repr-transparent.rs
+++ b/tests/ui/repr/repr-transparent.rs
@@ -23,23 +23,26 @@ struct ContainsMultipleZst(PhantomData<*const i32>, NoFields);
 struct ContainsZstAndNonZst((), [i32; 2]);
 
 #[repr(transparent)]
-struct MultipleNonZst(u8, u8); //~ ERROR needs at most one non-zero-sized field
+struct MultipleNonZst(u8, u8); //~ ERROR needs at most one field with non-trivial size or alignment
 
 trait Mirror { type It: ?Sized; }
 impl<T: ?Sized> Mirror for T { type It = Self; }
 
 #[repr(transparent)]
 pub struct StructWithProjection(f32, <f32 as Mirror>::It);
-//~^ ERROR needs at most one non-zero-sized field
+//~^ ERROR needs at most one field with non-trivial size or alignment
 
 #[repr(transparent)]
-struct NontrivialAlignZst(u32, [u16; 0]); //~ ERROR alignment larger than 1
+struct NontrivialAlignZst(u32, [u16; 0]); //~ ERROR needs at most one field with non-trivial size or alignment
 
 #[repr(align(32))]
 struct ZstAlign32<T>(PhantomData<T>);
 
 #[repr(transparent)]
-struct GenericAlign<T>(ZstAlign32<T>, u32); //~ ERROR alignment larger than 1
+struct GenericAlign<T>(ZstAlign32<T>, u32); //~ ERROR needs at most one field with non-trivial size or alignment
+
+#[repr(transparent)]
+struct WrapsZstWithAlignment([i32; 0]);
 
 #[repr(transparent)] //~ ERROR unsupported representation for zero-variant enum
 enum Void {} //~ ERROR transparent enum needs exactly one variant, but has 0
@@ -58,7 +61,7 @@ enum UnitFieldEnum {
 enum TooManyFieldsEnum {
     Foo(u32, String),
 }
-//~^^^ ERROR transparent enum needs at most one non-zero-sized field, but has 2
+//~^^^ ERROR transparent enum needs at most one field with non-trivial size or alignment, but has 2
 
 #[repr(transparent)]
 enum MultipleVariants { //~ ERROR transparent enum needs exactly one variant, but has 2
@@ -67,13 +70,13 @@ enum MultipleVariants { //~ ERROR transparent enum needs exactly one variant, bu
 }
 
 #[repr(transparent)]
-enum NontrivialAlignZstEnum {
-    Foo(u32, [u16; 0]), //~ ERROR alignment larger than 1
+enum NontrivialAlignZstEnum { //~ ERROR needs at most one field with non-trivial size or alignment
+    Foo(u32, [u16; 0]),
 }
 
 #[repr(transparent)]
-enum GenericAlignEnum<T> {
-    Foo { bar: ZstAlign32<T>, baz: u32 } //~ ERROR alignment larger than 1
+enum GenericAlignEnum<T> { //~ ERROR needs at most one field with non-trivial size or alignment
+    Foo { bar: ZstAlign32<T>, baz: u32 }
 }
 
 #[repr(transparent)]
@@ -82,7 +85,7 @@ union UnitUnion {
 }
 
 #[repr(transparent)]
-union TooManyFields { //~ ERROR transparent union needs at most one non-zero-sized field, but has 2
+union TooManyFields { //~ ERROR transparent union needs at most one field with non-trivial size or alignment, but has 2
     u: u32,
     s: i32
 }
diff --git a/tests/ui/repr/repr-transparent.stderr b/tests/ui/repr/repr-transparent.stderr
index 028fc25db46..d0c78a8418a 100644
--- a/tests/ui/repr/repr-transparent.stderr
+++ b/tests/ui/repr/repr-transparent.stderr
@@ -1,35 +1,41 @@
-error[E0690]: transparent struct needs at most one non-zero-sized field, but has 2
+error[E0690]: transparent struct needs at most one field with non-trivial size or alignment, but has 2
   --> $DIR/repr-transparent.rs:26:1
    |
 LL | struct MultipleNonZst(u8, u8);
-   | ^^^^^^^^^^^^^^^^^^^^^ --  -- this field is non-zero-sized
+   | ^^^^^^^^^^^^^^^^^^^^^ --  -- this field has non-zero size or requires alignment
    | |                     |
-   | |                     this field is non-zero-sized
-   | needs at most one non-zero-sized field, but has 2
+   | |                     this field has non-zero size or requires alignment
+   | needs at most one field with non-trivial size or alignment, but has 2
 
-error[E0690]: transparent struct needs at most one non-zero-sized field, but has 2
+error[E0690]: transparent struct needs at most one field with non-trivial size or alignment, but has 2
   --> $DIR/repr-transparent.rs:32:1
    |
 LL | pub struct StructWithProjection(f32, <f32 as Mirror>::It);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---  ------------------- this field is non-zero-sized
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---  ------------------- this field has non-zero size or requires alignment
    | |                               |
-   | |                               this field is non-zero-sized
-   | needs at most one non-zero-sized field, but has 2
+   | |                               this field has non-zero size or requires alignment
+   | needs at most one field with non-trivial size or alignment, but has 2
 
-error[E0691]: zero-sized field in transparent struct has alignment larger than 1
-  --> $DIR/repr-transparent.rs:36:32
+error[E0690]: transparent struct needs at most one field with non-trivial size or alignment, but has 2
+  --> $DIR/repr-transparent.rs:36:1
    |
 LL | struct NontrivialAlignZst(u32, [u16; 0]);
-   |                                ^^^^^^^^ has alignment of 2, which is larger than 1
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ ---  -------- this field has non-zero size or requires alignment
+   | |                         |
+   | |                         this field has non-zero size or requires alignment
+   | needs at most one field with non-trivial size or alignment, but has 2
 
-error[E0691]: zero-sized field in transparent struct has alignment larger than 1
-  --> $DIR/repr-transparent.rs:42:24
+error[E0690]: transparent struct needs at most one field with non-trivial size or alignment, but has 2
+  --> $DIR/repr-transparent.rs:42:1
    |
 LL | struct GenericAlign<T>(ZstAlign32<T>, u32);
-   |                        ^^^^^^^^^^^^^ has alignment of 32, which is larger than 1
+   | ^^^^^^^^^^^^^^^^^^^^^^ -------------  --- this field has non-zero size or requires alignment
+   | |                      |
+   | |                      this field has non-zero size or requires alignment
+   | needs at most one field with non-trivial size or alignment, but has 2
 
 error[E0084]: unsupported representation for zero-variant enum
-  --> $DIR/repr-transparent.rs:44:1
+  --> $DIR/repr-transparent.rs:47:1
    |
 LL | #[repr(transparent)]
    | ^^^^^^^^^^^^^^^^^^^^
@@ -37,23 +43,23 @@ LL | enum Void {}
    | --------- zero-variant enum
 
 error[E0731]: transparent enum needs exactly one variant, but has 0
-  --> $DIR/repr-transparent.rs:45:1
+  --> $DIR/repr-transparent.rs:48: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
+error[E0690]: the variant of a transparent enum needs at most one field with non-trivial size or alignment, but has 2
+  --> $DIR/repr-transparent.rs:61:1
    |
 LL | enum TooManyFieldsEnum {
-   | ^^^^^^^^^^^^^^^^^^^^^^ needs at most one non-zero-sized field, but has 2
+   | ^^^^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2
 LL |     Foo(u32, String),
-   |         ---  ------ this field is non-zero-sized
+   |         ---  ------ this field has non-zero size or requires alignment
    |         |
-   |         this field is non-zero-sized
+   |         this field has non-zero size or requires alignment
 
 error[E0731]: transparent enum needs exactly one variant, but has 2
-  --> $DIR/repr-transparent.rs:64:1
+  --> $DIR/repr-transparent.rs:67:1
    |
 LL | enum MultipleVariants {
    | ^^^^^^^^^^^^^^^^^^^^^ needs exactly one variant, but has 2
@@ -62,29 +68,37 @@ 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
+error[E0690]: the variant of a transparent enum needs at most one field with non-trivial size or alignment, but has 2
+  --> $DIR/repr-transparent.rs:73:1
    |
+LL | enum NontrivialAlignZstEnum {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2
 LL |     Foo(u32, [u16; 0]),
-   |              ^^^^^^^^ has alignment of 2, which is larger than 1
+   |         ---  -------- this field has non-zero size or requires alignment
+   |         |
+   |         this field has non-zero size or requires alignment
 
-error[E0691]: zero-sized field in transparent enum has alignment larger than 1
-  --> $DIR/repr-transparent.rs:76:11
+error[E0690]: the variant of a transparent enum needs at most one field with non-trivial size or alignment, but has 2
+  --> $DIR/repr-transparent.rs:78:1
    |
+LL | enum GenericAlignEnum<T> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2
 LL |     Foo { bar: ZstAlign32<T>, baz: u32 }
-   |           ^^^^^^^^^^^^^^^^^^ has alignment of 32, which is larger than 1
+   |           ------------------  -------- this field has non-zero size or requires alignment
+   |           |
+   |           this field has non-zero size or requires alignment
 
-error[E0690]: transparent union needs at most one non-zero-sized field, but has 2
-  --> $DIR/repr-transparent.rs:85:1
+error[E0690]: transparent union needs at most one field with non-trivial size or alignment, but has 2
+  --> $DIR/repr-transparent.rs:88:1
    |
 LL | union TooManyFields {
-   | ^^^^^^^^^^^^^^^^^^^ needs at most one non-zero-sized field, but has 2
+   | ^^^^^^^^^^^^^^^^^^^ needs at most one field with non-trivial size or alignment, but has 2
 LL |     u: u32,
-   |     ------ this field is non-zero-sized
+   |     ------ this field has non-zero size or requires alignment
 LL |     s: i32
-   |     ------ this field is non-zero-sized
+   |     ------ this field has non-zero size or requires alignment
 
 error: aborting due to 11 previous errors
 
-Some errors have detailed explanations: E0084, E0690, E0691, E0731.
+Some errors have detailed explanations: E0084, E0690, E0731.
 For more information about an error, try `rustc --explain E0084`.