]> git.lizzy.rs Git - rust.git/commitdiff
Permit zero non-zero-field on transparent types
authorYuki Okushi <yuki.okushi@huawei.com>
Sun, 13 Jun 2021 22:04:56 +0000 (07:04 +0900)
committerYuki Okushi <yuki.okushi@huawei.com>
Sun, 13 Jun 2021 22:42:14 +0000 (07:42 +0900)
compiler/rustc_typeck/src/check/check.rs
compiler/rustc_typeck/src/check/mod.rs
src/test/ui/repr/repr-transparent.rs
src/test/ui/repr/repr-transparent.stderr

index 70d85796d002e961a70149c3cb06e1d1818699d0..77644ea1c3c95046ced8fbe8bf0f23263b2f3f32 100644 (file)
@@ -1382,7 +1382,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: &'tcx ty
     let non_zst_fields =
         field_infos.clone().filter_map(|(span, zst, _align1)| if !zst { Some(span) } else { None });
     let non_zst_count = non_zst_fields.clone().count();
-    if non_zst_count != 1 {
+    if non_zst_count >= 2 {
         bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
     }
     for (span, zst, align1) in field_infos {
index ad7853b7cd0f10282626d5a4d087ca37f6ccd822..72d94c3a9c9354d8f86f11dd63f958324dab4928 100644 (file)
@@ -1029,7 +1029,7 @@ fn suggestion_signature(assoc: &ty::AssocItem, tcx: TyCtxt<'_>) -> String {
     }
 }
 
-/// Emit an error when encountering more or less than one variant in a transparent enum.
+/// Emit an error when encountering two or more variants in a transparent enum.
 fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, did: DefId) {
     let variant_spans: Vec<_> = adt
         .variants
@@ -1048,7 +1048,7 @@ fn bad_variant_count<'tcx>(tcx: TyCtxt<'tcx>, adt: &'tcx ty::AdtDef, sp: Span, d
     err.emit();
 }
 
-/// Emit an error when encountering more or less than one non-zero-sized field in a transparent
+/// Emit an error when encountering two or more non-zero-sized fields in a transparent
 /// enum.
 fn bad_non_zero_sized_fields<'tcx>(
     tcx: TyCtxt<'tcx>,
@@ -1057,7 +1057,7 @@ fn bad_non_zero_sized_fields<'tcx>(
     field_spans: impl Iterator<Item = Span>,
     sp: Span,
 ) {
-    let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
+    let msg = format!("needs at most one non-zero-sized field, but has {}", field_count);
     let mut err = struct_span_err!(
         tcx.sess,
         sp,
index 8fbdb4cc80b5e14bebc5fb9ac61b1841ddb11689..8c9d1639c0a51ffc965388a2204fdf14dc4fd1f6 100644 (file)
@@ -8,27 +8,29 @@
 use std::marker::PhantomData;
 
 #[repr(transparent)]
-struct NoFields; //~ ERROR needs exactly one non-zero-sized field
+struct NoFields;
 
 #[repr(transparent)]
-struct ContainsOnlyZst(()); //~ ERROR needs exactly one non-zero-sized field
+struct ContainsOnlyZst(());
 
 #[repr(transparent)]
-struct ContainsOnlyZstArray([bool; 0]); //~ ERROR needs exactly one non-zero-sized field
+struct ContainsOnlyZstArray([bool; 0]);
 
 #[repr(transparent)]
 struct ContainsMultipleZst(PhantomData<*const i32>, NoFields);
-//~^ ERROR needs exactly one non-zero-sized field
 
 #[repr(transparent)]
-struct MultipleNonZst(u8, u8); //~ ERROR needs exactly one non-zero-sized field
+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<T: ?Sized> Mirror for T { type It = Self; }
 
 #[repr(transparent)]
 pub struct StructWithProjection(f32, <f32 as Mirror>::It);
-//~^ ERROR needs exactly one non-zero-sized field
+//~^ ERROR needs at most one non-zero-sized field
 
 #[repr(transparent)]
 struct NontrivialAlignZst(u32, [u16; 0]); //~ ERROR alignment larger than 1
 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
+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
+enum FieldlessEnum {
     Foo,
 }
 
+#[repr(transparent)]
+enum UnitFieldEnum {
+    Foo(()),
+}
+
 #[repr(transparent)]
 enum TooManyFieldsEnum {
     Foo(u32, String),
 }
-//~^^^ ERROR transparent enum needs exactly one non-zero-sized field, but has 2
+//~^^^ ERROR transparent enum needs at most one non-zero-sized field, but has 2
 
 #[repr(transparent)]
-enum TooManyVariants { //~ ERROR transparent enum needs exactly one variant, but has 2
+enum MultipleVariants { //~ ERROR transparent enum needs exactly one variant, but has 2
     Foo(String),
     Bar,
 }
@@ -71,12 +77,12 @@ enum GenericAlignEnum<T> {
 }
 
 #[repr(transparent)]
-union UnitUnion { //~ ERROR transparent union needs exactly one non-zero-sized field, but has 0
+union UnitUnion {
     u: (),
 }
 
 #[repr(transparent)]
-union TooManyFields { //~ ERROR transparent union needs exactly one non-zero-sized field, but has 2
+union TooManyFields { //~ ERROR transparent union needs at most one non-zero-sized field, but has 2
     u: u32,
     s: i32
 }
index cbc74fbb6a2cf48b638f60fe14afbcdd8ddfceeb..001a181881f14cf5775fc3b9e0b73c89e0b86e8b 100644 (file)
@@ -1,61 +1,37 @@
-error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0
-  --> $DIR/repr-transparent.rs:11:1
-   |
-LL | struct NoFields;
-   | ^^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 0
-
-error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 0
-  --> $DIR/repr-transparent.rs:14:1
-   |
-LL | struct ContainsOnlyZst(());
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 0
-
-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]);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 0
-
-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);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 0
-
-error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 2
-  --> $DIR/repr-transparent.rs:24:1
+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 exactly one non-zero-sized field, but has 2
+   | needs at most one non-zero-sized field, but has 2
 
-error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 2
-  --> $DIR/repr-transparent.rs:30:1
+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, <f32 as Mirror>::It);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^^-------------------^^
    | |                               |    |
    | |                               |    this field is non-zero-sized
    | |                               this field is non-zero-sized
-   | needs exactly one non-zero-sized field, but has 2
+   | 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:34:32
+  --> $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:40:24
+  --> $DIR/repr-transparent.rs:42:24
    |
 LL | struct GenericAlign<T>(ZstAlign32<T>, u32);
    |                        ^^^^^^^^^^^^^ has alignment larger than 1
 
 error[E0084]: unsupported representation for zero-variant enum
-  --> $DIR/repr-transparent.rs:42:1
+  --> $DIR/repr-transparent.rs:44:1
    |
 LL | #[repr(transparent)]
    | ^^^^^^^^^^^^^^^^^^^^
@@ -63,66 +39,54 @@ LL | enum Void {}
    | ------------ zero-variant enum
 
 error[E0731]: transparent enum needs exactly one variant, but has 0
-  --> $DIR/repr-transparent.rs:43:1
+  --> $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 exactly one non-zero-sized field, but has 0
-  --> $DIR/repr-transparent.rs:47:1
-   |
-LL | enum FieldlessEnum {
-   | ^^^^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 0
-
-error[E0690]: the variant of a transparent enum needs exactly one non-zero-sized field, but has 2
-  --> $DIR/repr-transparent.rs:52:1
+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 exactly one non-zero-sized field, but has 2
+   | ^^^^^^^^^^^^^^^^^^^^^^ 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:58:1
+  --> $DIR/repr-transparent.rs:64:1
    |
-LL | enum TooManyVariants {
-   | ^^^^^^^^^^^^^^^^^^^^ needs exactly one variant, but has 2
+LL | enum MultipleVariants {
+   | ^^^^^^^^^^^^^^^^^^^^^ needs exactly one variant, but has 2
 LL |     Foo(String),
    |     -----------
 LL |     Bar,
-   |     --- too many variants in `TooManyVariants`
+   |     --- too many variants in `MultipleVariants`
 
 error[E0691]: zero-sized field in transparent enum has alignment larger than 1
-  --> $DIR/repr-transparent.rs:65:14
+  --> $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:70:11
+  --> $DIR/repr-transparent.rs:76:11
    |
 LL |     Foo { bar: ZstAlign32<T>, baz: u32 }
    |           ^^^^^^^^^^^^^^^^^^ has alignment larger than 1
 
-error[E0690]: transparent union needs exactly one non-zero-sized field, but has 0
-  --> $DIR/repr-transparent.rs:74:1
-   |
-LL | union UnitUnion {
-   | ^^^^^^^^^^^^^^^ needs exactly one non-zero-sized field, but has 0
-
-error[E0690]: transparent union needs exactly one non-zero-sized field, but has 2
-  --> $DIR/repr-transparent.rs:79: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 exactly one non-zero-sized field, but has 2
+   | ^^^^^^^^^^^^^^^^^^^ 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 17 previous errors
+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`.