about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs14
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/struct.stderr14
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/variant.stderr45
3 files changed, 32 insertions, 41 deletions
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index bb473d62a7b..0c9d306081e 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1608,11 +1608,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             struct_span_err!(self.tcx.sess, ident.span, E0603, "{} `{}` is private", descr, ident);
         err.span_label(ident.span, &format!("private {}", descr));
 
+        let mut non_exhaustive = None;
+        // If an ADT is foreign and marked as `non_exhaustive`, then that's
+        // probably why we have the privacy error.
+        // Otherwise, point out if the struct has any private fields.
         if let Some(def_id) = res.opt_def_id()
             && !def_id.is_local()
             && let Some(attr) = self.tcx.get_attr(def_id, sym::non_exhaustive)
         {
-            err.span_label(attr.span, format!("the {nonimport_descr} is `#[non_exhaustive]`"));
+            non_exhaustive = Some(attr.span);
         } else if let Some(span) = ctor_fields_span {
             err.span_label(span, "a constructor is private if any of the fields is private");
             if let Res::Def(_, d) = res && let Some(fields) = self.field_visibility_spans.get(&d) {
@@ -1662,6 +1666,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             if !first && binding.vis.is_public() {
                 note_span.push_span_label(def_span, "consider importing it directly");
             }
+            // Final step in the import chain, point out if the ADT is `non_exhaustive`
+            // which is probably why this privacy violation occurred.
+            if next_binding.is_none() && let Some(span) = non_exhaustive {
+                note_span.push_span_label(
+                    span,
+                    format!("cannot be constructed because it is `#[non_exhaustive]`"),
+                );
+            }
             err.span_note(note_span, &msg);
         }
 
diff --git a/tests/ui/rfc-2008-non-exhaustive/struct.stderr b/tests/ui/rfc-2008-non-exhaustive/struct.stderr
index 36154fe51a4..39b1ef1e078 100644
--- a/tests/ui/rfc-2008-non-exhaustive/struct.stderr
+++ b/tests/ui/rfc-2008-non-exhaustive/struct.stderr
@@ -10,14 +10,11 @@ error[E0603]: tuple struct constructor `TupleStruct` is private
 LL |     let ts_explicit = structs::TupleStruct(640, 480);
    |                                ^^^^^^^^^^^ private tuple struct constructor
    |
-  ::: $DIR/auxiliary/structs.rs:11:1
-   |
-LL | #[non_exhaustive]
-   | ----------------- the tuple struct constructor is `#[non_exhaustive]`
-   |
 note: the tuple struct constructor `TupleStruct` is defined here
   --> $DIR/auxiliary/structs.rs:12:1
    |
+LL | #[non_exhaustive]
+   | ----------------- cannot be constructed because it is `#[non_exhaustive]`
 LL | pub struct TupleStruct(pub u16, pub u16);
    | ^^^^^^^^^^^^^^^^^^^^^^
 
@@ -27,14 +24,11 @@ error[E0603]: unit struct `UnitStruct` is private
 LL |     let us_explicit = structs::UnitStruct;
    |                                ^^^^^^^^^^ private unit struct
    |
-  ::: $DIR/auxiliary/structs.rs:8:1
-   |
-LL | #[non_exhaustive]
-   | ----------------- the unit struct is `#[non_exhaustive]`
-   |
 note: the unit struct `UnitStruct` is defined here
   --> $DIR/auxiliary/structs.rs:9:1
    |
+LL | #[non_exhaustive]
+   | ----------------- cannot be constructed because it is `#[non_exhaustive]`
 LL | pub struct UnitStruct;
    | ^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/tests/ui/rfc-2008-non-exhaustive/variant.stderr b/tests/ui/rfc-2008-non-exhaustive/variant.stderr
index 551ecb5acf2..4083f57a9cd 100644
--- a/tests/ui/rfc-2008-non-exhaustive/variant.stderr
+++ b/tests/ui/rfc-2008-non-exhaustive/variant.stderr
@@ -4,16 +4,13 @@ error[E0603]: tuple variant `Tuple` is private
 LL |     let variant_tuple = NonExhaustiveVariants::Tuple(640);
    |                                                ^^^^^ private tuple variant
    |
-  ::: $DIR/auxiliary/variants.rs:5:5
-   |
-LL |     #[non_exhaustive] Tuple(u32),
-   |     ----------------- the tuple variant is `#[non_exhaustive]`
-   |
 note: the tuple variant `Tuple` is defined here
   --> $DIR/auxiliary/variants.rs:5:23
    |
 LL |     #[non_exhaustive] Tuple(u32),
-   |                       ^^^^^
+   |     ----------------- ^^^^^
+   |     |
+   |     cannot be constructed because it is `#[non_exhaustive]`
 
 error[E0603]: unit variant `Unit` is private
   --> $DIR/variant.rs:14:47
@@ -21,16 +18,13 @@ error[E0603]: unit variant `Unit` is private
 LL |     let variant_unit = NonExhaustiveVariants::Unit;
    |                                               ^^^^ private unit variant
    |
-  ::: $DIR/auxiliary/variants.rs:4:5
-   |
-LL |     #[non_exhaustive] Unit,
-   |     ----------------- the unit variant is `#[non_exhaustive]`
-   |
 note: the unit variant `Unit` is defined here
   --> $DIR/auxiliary/variants.rs:4:23
    |
 LL |     #[non_exhaustive] Unit,
-   |                       ^^^^
+   |     ----------------- ^^^^
+   |     |
+   |     cannot be constructed because it is `#[non_exhaustive]`
 
 error[E0603]: unit variant `Unit` is private
   --> $DIR/variant.rs:18:32
@@ -38,16 +32,13 @@ error[E0603]: unit variant `Unit` is private
 LL |         NonExhaustiveVariants::Unit => "",
    |                                ^^^^ private unit variant
    |
-  ::: $DIR/auxiliary/variants.rs:4:5
-   |
-LL |     #[non_exhaustive] Unit,
-   |     ----------------- the unit variant is `#[non_exhaustive]`
-   |
 note: the unit variant `Unit` is defined here
   --> $DIR/auxiliary/variants.rs:4:23
    |
 LL |     #[non_exhaustive] Unit,
-   |                       ^^^^
+   |     ----------------- ^^^^
+   |     |
+   |     cannot be constructed because it is `#[non_exhaustive]`
 
 error[E0603]: tuple variant `Tuple` is private
   --> $DIR/variant.rs:20:32
@@ -55,16 +46,13 @@ error[E0603]: tuple variant `Tuple` is private
 LL |         NonExhaustiveVariants::Tuple(fe_tpl) => "",
    |                                ^^^^^ private tuple variant
    |
-  ::: $DIR/auxiliary/variants.rs:5:5
-   |
-LL |     #[non_exhaustive] Tuple(u32),
-   |     ----------------- the tuple variant is `#[non_exhaustive]`
-   |
 note: the tuple variant `Tuple` is defined here
   --> $DIR/auxiliary/variants.rs:5:23
    |
 LL |     #[non_exhaustive] Tuple(u32),
-   |                       ^^^^^
+   |     ----------------- ^^^^^
+   |     |
+   |     cannot be constructed because it is `#[non_exhaustive]`
 
 error[E0603]: tuple variant `Tuple` is private
   --> $DIR/variant.rs:26:35
@@ -72,16 +60,13 @@ error[E0603]: tuple variant `Tuple` is private
 LL |     if let NonExhaustiveVariants::Tuple(fe_tpl) = variant_struct {
    |                                   ^^^^^ private tuple variant
    |
-  ::: $DIR/auxiliary/variants.rs:5:5
-   |
-LL |     #[non_exhaustive] Tuple(u32),
-   |     ----------------- the tuple variant is `#[non_exhaustive]`
-   |
 note: the tuple variant `Tuple` is defined here
   --> $DIR/auxiliary/variants.rs:5:23
    |
 LL |     #[non_exhaustive] Tuple(u32),
-   |                       ^^^^^
+   |     ----------------- ^^^^^
+   |     |
+   |     cannot be constructed because it is `#[non_exhaustive]`
 
 error[E0639]: cannot create non-exhaustive variant using struct expression
   --> $DIR/variant.rs:8:26