about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-06-19 01:52:01 +0200
committerGitHub <noreply@github.com>2019-06-19 01:52:01 +0200
commit06d2a891c72fa29477114d67c8672e0eaacddd0b (patch)
tree2fe2b4750f475d713c22a999346d95768cdff14d
parent65da792afa91b9b2c981d3da23681f4a2b168276 (diff)
parentf06b76122cde7ddd4f6778d77952b63baa70bdfe (diff)
downloadrust-06d2a891c72fa29477114d67c8672e0eaacddd0b.tar.gz
rust-06d2a891c72fa29477114d67c8672e0eaacddd0b.zip
Rollup merge of #61748 - estebank:transparent-span, r=Centril
Tweak transparent enums and unions diagnostic spans
-rw-r--r--src/librustc_typeck/check/mod.rs101
-rw-r--r--src/test/ui/feature-gates/feature-gate-transparent_enums.stderr6
-rw-r--r--src/test/ui/feature-gates/feature-gate-transparent_unions.stderr7
-rw-r--r--src/test/ui/repr/repr-transparent.stderr94
4 files changed, 106 insertions, 102 deletions
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 864f19933a5..d09f6683d0e 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1788,32 +1788,71 @@ fn check_packed_inner<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, stack: &mut Vec<De
     false
 }
 
+/// Emit an error when encountering more or less than one variant 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.iter().map(|variant| {
+        tcx.hir().span_if_local(variant.def_id).unwrap()
+    }).collect();
+    let msg = format!(
+        "needs exactly one variant, but has {}",
+        adt.variants.len(),
+    );
+    let mut err = struct_span_err!(tcx.sess, sp, E0731, "transparent enum {}", msg);
+    err.span_label(sp, &msg);
+    if let &[ref start.., ref end] = &variant_spans[..] {
+        for variant_span in start {
+            err.span_label(*variant_span, "");
+        }
+        err.span_label(*end, &format!("too many variants in `{}`", tcx.def_path_str(did)));
+    }
+    err.emit();
+}
+
+/// Emit an error when encountering more or less than one non-zero-sized field in a transparent
+/// enum.
+fn bad_non_zero_sized_fields<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    adt: &'tcx ty::AdtDef,
+    field_count: usize,
+    field_spans: impl Iterator<Item = Span>,
+    sp: Span,
+) {
+    let msg = format!("needs exactly one non-zero-sized field, but has {}", field_count);
+    let mut err = struct_span_err!(
+        tcx.sess,
+        sp,
+        E0690,
+        "{}transparent {} {}",
+        if adt.is_enum() { "the variant of a " } else { "" },
+        adt.descr(),
+        msg,
+    );
+    err.span_label(sp, &msg);
+    for sp in field_spans {
+        err.span_label(sp, "this field is non-zero-sized");
+    }
+    err.emit();
+}
+
 fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
     let adt = tcx.adt_def(def_id);
     if !adt.repr.transparent() {
         return;
     }
+    let sp = tcx.sess.source_map().def_span(sp);
 
     if adt.is_enum() {
         if !tcx.features().transparent_enums {
-            emit_feature_err(&tcx.sess.parse_sess,
-                             sym::transparent_enums,
-                             sp,
-                             GateIssue::Language,
-                             "transparent enums are unstable");
+            emit_feature_err(
+                &tcx.sess.parse_sess,
+                sym::transparent_enums,
+                sp,
+                GateIssue::Language,
+                "transparent enums are unstable",
+            );
         }
         if adt.variants.len() != 1 {
-            let variant_spans: Vec<_> = adt.variants.iter().map(|variant| {
-                tcx.hir().span_if_local(variant.def_id).unwrap()
-            }).collect();
-            let mut err = struct_span_err!(tcx.sess, sp, E0731,
-                            "transparent enum needs exactly one variant, but has {}",
-                            adt.variants.len());
-            if !variant_spans.is_empty() {
-                err.span_note(variant_spans, &format!("the following variants exist on `{}`",
-                                                      tcx.def_path_str(def_id)));
-            }
-            err.emit();
+            bad_variant_count(tcx, adt, sp, def_id);
             if adt.variants.is_empty() {
                 // Don't bother checking the fields. No variants (and thus no fields) exist.
                 return;
@@ -1841,28 +1880,24 @@ fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, def_id: DefId) {
         (span, zst, align1)
     });
 
-    let non_zst_fields = field_infos.clone().filter(|(_span, zst, _align1)| !*zst);
+    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 {
-        let field_spans: Vec<_> = non_zst_fields.map(|(span, _zst, _align1)| span).collect();
-
-        let mut err = struct_span_err!(tcx.sess, sp, E0690,
-                         "{}transparent {} needs exactly one non-zero-sized field, but has {}",
-                         if adt.is_enum() { "the variant of a " } else { "" },
-                         adt.descr(),
-                         non_zst_count);
-        if !field_spans.is_empty() {
-            err.span_note(field_spans,
-                          &format!("the following non-zero-sized fields exist on `{}`:",
-                                   tcx.def_path_str(def_id)));
-        }
-        err.emit();
+        bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, sp);
     }
     for (span, zst, align1) in field_infos {
         if zst && !align1 {
-            span_err!(tcx.sess, span, E0691,
-                      "zero-sized field in transparent {} has alignment larger than 1",
-                      adt.descr());
+            struct_span_err!(
+                tcx.sess,
+                span,
+                E0691,
+                "zero-sized field in transparent {} has alignment larger than 1",
+                adt.descr(),
+            ).span_label(span, "has alignment larger than 1").emit();
         }
     }
 }
diff --git a/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr b/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr
index 4b22654e9e4..8ba079b89f5 100644
--- a/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr
+++ b/src/test/ui/feature-gates/feature-gate-transparent_enums.stderr
@@ -1,10 +1,8 @@
 error[E0658]: transparent enums are unstable
   --> $DIR/feature-gate-transparent_enums.rs:2:1
    |
-LL | / enum OkButUnstableEnum {
-LL | |     Foo((), String, ()),
-LL | | }
-   | |_^
+LL | enum OkButUnstableEnum {
+   | ^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/60405
    = help: add #![feature(transparent_enums)] to the crate attributes to enable
diff --git a/src/test/ui/feature-gates/feature-gate-transparent_unions.stderr b/src/test/ui/feature-gates/feature-gate-transparent_unions.stderr
index 933b227de63..341324c3d67 100644
--- a/src/test/ui/feature-gates/feature-gate-transparent_unions.stderr
+++ b/src/test/ui/feature-gates/feature-gate-transparent_unions.stderr
@@ -1,11 +1,8 @@
 error[E0658]: transparent unions are unstable
   --> $DIR/feature-gate-transparent_unions.rs:2:1
    |
-LL | / union OkButUnstableUnion {
-LL | |     field: u8,
-LL | |     zst: (),
-LL | | }
-   | |_^
+LL | union OkButUnstableUnion {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/60405
    = help: add #![feature(transparent_unions)] to the crate attributes to enable
diff --git a/src/test/ui/repr/repr-transparent.stderr b/src/test/ui/repr/repr-transparent.stderr
index ea16bdf5378..f0c1fbe8ac9 100644
--- a/src/test/ui/repr/repr-transparent.stderr
+++ b/src/test/ui/repr/repr-transparent.stderr
@@ -2,61 +2,57 @@ error[E0690]: transparent struct needs exactly one non-zero-sized field, but has
   --> $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
    |
 LL | struct MultipleNonZst(u8, u8);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: the following non-zero-sized fields exist on `MultipleNonZst`:
-  --> $DIR/repr-transparent.rs:24:23
-   |
-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
 
 error[E0690]: transparent struct needs exactly one non-zero-sized field, but has 2
   --> $DIR/repr-transparent.rs:30:1
    |
 LL | pub struct StructWithProjection(f32, <f32 as Mirror>::It);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-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);
-   |                                 ^^^  ^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^^-------------------^^
+   | |                               |    |
+   | |                               |    this field is non-zero-sized
+   | |                               this field is non-zero-sized
+   | needs exactly 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
    |
 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
    |
 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
@@ -70,71 +66,49 @@ error[E0731]: transparent enum needs exactly one variant, but has 0
   --> $DIR/repr-transparent.rs:43: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 {
-LL | |     Foo,
-LL | | }
-   | |_^
+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
    |
-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 | enum TooManyFieldsEnum {
+   | ^^^^^^^^^^^^^^^^^^^^^^ needs exactly 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
    |
-LL | / enum TooManyVariants {
-LL | |     Foo(String),
-LL | |     Bar,
-LL | | }
-   | |_^
-   |
-note: the following variants exist on `TooManyVariants`
-  --> $DIR/repr-transparent.rs:59:5
-   |
+LL | enum TooManyVariants {
+   | ^^^^^^^^^^^^^^^^^^^^ needs exactly one variant, but has 2
 LL |     Foo(String),
-   |     ^^^^^^^^^^^
+   |     -----------
 LL |     Bar,
-   |     ^^^
+   |     --- too many variants in `TooManyVariants`
 
 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 | | }
-   | |_^
+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: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 | union TooManyFields {
+   | ^^^^^^^^^^^^^^^^^^^ needs exactly 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 15 previous errors