about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-04-06 16:49:43 +0000
committerMichael Goulet <michael@errs.io>2023-04-06 16:49:43 +0000
commit00d54c879bfb6adb5b7a611af6bd522499d07a1d (patch)
treeb71b82fc793b3e7f5c89117cfa550cc792aa80b0
parentcf7ada217c8ac63367b184afd9fffaff30f6ed44 (diff)
downloadrust-00d54c879bfb6adb5b7a611af6bd522499d07a1d.tar.gz
rust-00d54c879bfb6adb5b7a611af6bd522499d07a1d.zip
Label non_exhaustive on privacy errors
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs8
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/struct.stderr11
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/variant.stderr25
3 files changed, 40 insertions, 4 deletions
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index e69a9d0aeca..bb473d62a7b 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1607,7 +1607,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let mut err =
             struct_span_err!(self.tcx.sess, ident.span, E0603, "{} `{}` is private", descr, ident);
         err.span_label(ident.span, &format!("private {}", descr));
-        if let Some(span) = ctor_fields_span {
+
+        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]`"));
+        } 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) {
                 err.multipart_suggestion_verbose(
diff --git a/tests/ui/rfc-2008-non-exhaustive/struct.stderr b/tests/ui/rfc-2008-non-exhaustive/struct.stderr
index 2cb9ba0d1d1..36154fe51a4 100644
--- a/tests/ui/rfc-2008-non-exhaustive/struct.stderr
+++ b/tests/ui/rfc-2008-non-exhaustive/struct.stderr
@@ -10,10 +10,10 @@ error[E0603]: tuple struct constructor `TupleStruct` is private
 LL |     let ts_explicit = structs::TupleStruct(640, 480);
    |                                ^^^^^^^^^^^ private tuple struct constructor
    |
-  ::: $DIR/auxiliary/structs.rs:12:24
+  ::: $DIR/auxiliary/structs.rs:11:1
    |
-LL | pub struct TupleStruct(pub u16, pub u16);
-   |                        ---------------- a constructor is private if any of the fields is private
+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
@@ -27,6 +27,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
    |
diff --git a/tests/ui/rfc-2008-non-exhaustive/variant.stderr b/tests/ui/rfc-2008-non-exhaustive/variant.stderr
index 720b7b119ce..551ecb5acf2 100644
--- a/tests/ui/rfc-2008-non-exhaustive/variant.stderr
+++ b/tests/ui/rfc-2008-non-exhaustive/variant.stderr
@@ -4,6 +4,11 @@ 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
    |
@@ -16,6 +21,11 @@ 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
    |
@@ -28,6 +38,11 @@ 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
    |
@@ -40,6 +55,11 @@ 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
    |
@@ -52,6 +72,11 @@ 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
    |