diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 61f1069d5716..72b12759315e 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -692,11 +692,11 @@ pub(super) fn is_unstable_variant(&self, pcx: PatCtxt<'_, '_, 'tcx>) -> bool { } /// Checks if the `Constructor` is a `Constructor::Variant` with a `#[doc(hidden)]` - /// attribute. + /// attribute from a type not local to the current crate. pub(super) fn is_doc_hidden_variant(&self, pcx: PatCtxt<'_, '_, 'tcx>) -> bool { if let Constructor::Variant(idx) = self && let ty::Adt(adt, _) = pcx.ty.kind() { - let variant_def_id = adt.variant(*idx).def_id; - return pcx.cx.tcx.is_doc_hidden(variant_def_id); + let variant_def_id = adt.variants[*idx].def_id; + return pcx.cx.tcx.is_doc_hidden(variant_def_id) && !variant_def_id.is_local(); } false } diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 155f9f899f62..6a9870d708f5 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -1313,7 +1313,8 @@ fn check_struct_pat_fields( tcx.eval_stability(field.did, None, DUMMY_SP, None), EvalResult::Deny { .. } ) - && !tcx.is_doc_hidden(field.did) + // We only want to report the error if it is hidden and not local + && !(tcx.is_doc_hidden(field.did) && !field.did.is_local()) }) .collect(); diff --git a/src/test/ui/pattern/usefulness/doc-hidden-fields.rs b/src/test/ui/pattern/usefulness/doc-hidden-fields.rs index e947c223eded..aad3809a410a 100644 --- a/src/test/ui/pattern/usefulness/doc-hidden-fields.rs +++ b/src/test/ui/pattern/usefulness/doc-hidden-fields.rs @@ -4,6 +4,13 @@ use hidden::HiddenStruct; +struct InCrate { + a: usize, + b: bool, + #[doc(hidden)] + im_hidden: u8 +} + fn main() { let HiddenStruct { one, two, } = HiddenStruct::default(); //~^ pattern requires `..` due to inaccessible fields @@ -13,4 +20,7 @@ fn main() { let HiddenStruct { one, hide } = HiddenStruct::default(); //~^ pattern does not mention field `two` + + let InCrate { a, b } = InCrate { a: 0, b: false, im_hidden: 0 }; + //~^ pattern does not mention field `im_hidden` } diff --git a/src/test/ui/pattern/usefulness/doc-hidden-fields.stderr b/src/test/ui/pattern/usefulness/doc-hidden-fields.stderr index 9e48925479bb..2f1575bfa416 100644 --- a/src/test/ui/pattern/usefulness/doc-hidden-fields.stderr +++ b/src/test/ui/pattern/usefulness/doc-hidden-fields.stderr @@ -1,5 +1,5 @@ error: pattern requires `..` due to inaccessible fields - --> $DIR/doc-hidden-fields.rs:8:9 + --> $DIR/doc-hidden-fields.rs:15:9 | LL | let HiddenStruct { one, two, } = HiddenStruct::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | let HiddenStruct { one, two, .., } = HiddenStruct::default(); | ++++ error[E0027]: pattern does not mention field `two` and inaccessible fields - --> $DIR/doc-hidden-fields.rs:11:9 + --> $DIR/doc-hidden-fields.rs:18:9 | LL | let HiddenStruct { one, } = HiddenStruct::default(); | ^^^^^^^^^^^^^^^^^^^^^ missing field `two` and inaccessible fields @@ -25,7 +25,7 @@ LL | let HiddenStruct { one, .. } = HiddenStruct::default(); | ~~~~~~ error[E0027]: pattern does not mention field `two` - --> $DIR/doc-hidden-fields.rs:14:9 + --> $DIR/doc-hidden-fields.rs:21:9 | LL | let HiddenStruct { one, hide } = HiddenStruct::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ missing field `two` @@ -39,6 +39,21 @@ help: if you don't care about this missing field, you can explicitly ignore it LL | let HiddenStruct { one, hide, .. } = HiddenStruct::default(); | ~~~~~~ -error: aborting due to 3 previous errors +error[E0027]: pattern does not mention field `im_hidden` + --> $DIR/doc-hidden-fields.rs:24:9 + | +LL | let InCrate { a, b } = InCrate { a: 0, b: false, im_hidden: 0 }; + | ^^^^^^^^^^^^^^^^ missing field `im_hidden` + | +help: include the missing field in the pattern + | +LL | let InCrate { a, b, im_hidden } = InCrate { a: 0, b: false, im_hidden: 0 }; + | ~~~~~~~~~~~~~ +help: if you don't care about this missing field, you can explicitly ignore it + | +LL | let InCrate { a, b, .. } = InCrate { a: 0, b: false, im_hidden: 0 }; + | ~~~~~~ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0027`. diff --git a/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.rs b/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.rs index 23c57f2bc6ab..d968c48fb1ab 100644 --- a/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.rs +++ b/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.rs @@ -4,6 +4,13 @@ use hidden::HiddenEnum; +enum InCrate { + A, + B, + #[doc(hidden)] + C, +} + fn main() { match HiddenEnum::A { HiddenEnum::A => {} @@ -27,4 +34,10 @@ fn main() { Some(HiddenEnum::A) => {} } //~^^^^ non-exhaustive patterns: `Some(B)` and `Some(_)` not covered + + match InCrate::A { + InCrate::A => {} + InCrate::B => {} + } + //~^^^^ non-exhaustive patterns: `C` not covered } diff --git a/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr b/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr index 41cdb8fdedb0..729716cb723d 100644 --- a/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr +++ b/src/test/ui/pattern/usefulness/doc-hidden-non-exhaustive.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/doc-hidden-non-exhaustive.rs:8:11 + --> $DIR/doc-hidden-non-exhaustive.rs:15:11 | LL | match HiddenEnum::A { | ^^^^^^^^^^^^^ pattern `_` not covered @@ -8,7 +8,7 @@ LL | match HiddenEnum::A { = note: the matched value is of type `HiddenEnum` error[E0004]: non-exhaustive patterns: `B` not covered - --> $DIR/doc-hidden-non-exhaustive.rs:14:11 + --> $DIR/doc-hidden-non-exhaustive.rs:21:11 | LL | match HiddenEnum::A { | ^^^^^^^^^^^^^ pattern `B` not covered @@ -23,7 +23,7 @@ LL | B, = note: the matched value is of type `HiddenEnum` error[E0004]: non-exhaustive patterns: `B` and `_` not covered - --> $DIR/doc-hidden-non-exhaustive.rs:20:11 + --> $DIR/doc-hidden-non-exhaustive.rs:27:11 | LL | match HiddenEnum::A { | ^^^^^^^^^^^^^ patterns `B` and `_` not covered @@ -38,7 +38,7 @@ LL | B, = note: the matched value is of type `HiddenEnum` error[E0004]: non-exhaustive patterns: `Some(B)` and `Some(_)` not covered - --> $DIR/doc-hidden-non-exhaustive.rs:25:11 + --> $DIR/doc-hidden-non-exhaustive.rs:32:11 | LL | match None { | ^^^^ patterns `Some(B)` and `Some(_)` not covered @@ -52,6 +52,24 @@ LL | Some(#[stable(feature = "rust1", since = "1.0.0")] T), = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms = note: the matched value is of type `Option` -error: aborting due to 4 previous errors +error[E0004]: non-exhaustive patterns: `C` not covered + --> $DIR/doc-hidden-non-exhaustive.rs:38:11 + | +LL | / enum InCrate { +LL | | A, +LL | | B, +LL | | #[doc(hidden)] +LL | | C, + | | - not covered +LL | | } + | |_- `InCrate` defined here +... +LL | match InCrate::A { + | ^^^^^^^^^^ pattern `C` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `InCrate` + +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0004`.