about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2023-09-19 11:49:49 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2023-10-11 12:49:57 +0000
commite83467c3b8ffae2322f293b148b6ddaead706adb (patch)
treee3de6c707b2743f57d120d3e704873d74e5566d9
parentd1fd11f3f94a5e4f739a027adb904db714286325 (diff)
downloadrust-e83467c3b8ffae2322f293b148b6ddaead706adb.tar.gz
rust-e83467c3b8ffae2322f293b148b6ddaead706adb.zip
Avoid emitting the non_exhaustive error if other errors already occurred
-rw-r--r--compiler/rustc_middle/src/thir.rs13
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs8
-rw-r--r--compiler/rustc_type_ir/src/structural_impls.rs6
-rw-r--r--tests/ui/consts/match_ice.rs2
-rw-r--r--tests/ui/consts/match_ice.stderr21
-rw-r--r--tests/ui/pattern/issue-72565.rs2
-rw-r--r--tests/ui/pattern/issue-72565.stderr15
-rw-r--r--tests/ui/pattern/non-structural-match-types.rs8
-rw-r--r--tests/ui/pattern/non-structural-match-types.stderr31
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.rs2
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.stderr16
11 files changed, 34 insertions, 90 deletions
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 89934e4350e..08f7434a4a9 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -581,13 +581,13 @@ pub enum BindingMode {
     ByRef(BorrowKind),
 }
 
-#[derive(Clone, Debug, HashStable)]
+#[derive(Clone, Debug, HashStable, TypeVisitable)]
 pub struct FieldPat<'tcx> {
     pub field: FieldIdx,
     pub pattern: Box<Pat<'tcx>>,
 }
 
-#[derive(Clone, Debug, HashStable)]
+#[derive(Clone, Debug, HashStable, TypeVisitable)]
 pub struct Pat<'tcx> {
     pub ty: Ty<'tcx>,
     pub span: Span,
@@ -664,7 +664,7 @@ impl<'tcx> IntoDiagnosticArg for Pat<'tcx> {
     }
 }
 
-#[derive(Clone, Debug, HashStable)]
+#[derive(Clone, Debug, HashStable, TypeVisitable)]
 pub struct Ascription<'tcx> {
     pub annotation: CanonicalUserTypeAnnotation<'tcx>,
     /// Variance to use when relating the `user_ty` to the **type of the value being
@@ -688,7 +688,7 @@ pub struct Ascription<'tcx> {
     pub variance: ty::Variance,
 }
 
-#[derive(Clone, Debug, HashStable)]
+#[derive(Clone, Debug, HashStable, TypeVisitable)]
 pub enum PatKind<'tcx> {
     /// A wildcard pattern: `_`.
     Wild,
@@ -702,7 +702,9 @@ pub enum PatKind<'tcx> {
     Binding {
         mutability: Mutability,
         name: Symbol,
+        #[type_visitable(ignore)]
         mode: BindingMode,
+        #[type_visitable(ignore)]
         var: LocalVarId,
         ty: Ty<'tcx>,
         subpattern: Option<Box<Pat<'tcx>>>,
@@ -771,10 +773,11 @@ pub enum PatKind<'tcx> {
     },
 }
 
-#[derive(Clone, Debug, PartialEq, HashStable)]
+#[derive(Clone, Debug, PartialEq, HashStable, TypeVisitable)]
 pub struct PatRange<'tcx> {
     pub lo: mir::Const<'tcx>,
     pub hi: mir::Const<'tcx>,
+    #[type_visitable(ignore)]
     pub end: RangeEnd,
 }
 
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index d440ca31926..93434dd3cc2 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -19,7 +19,7 @@ use rustc_hir::HirId;
 use rustc_middle::thir::visit::{self, Visitor};
 use rustc_middle::thir::*;
 use rustc_middle::ty::print::with_no_trimmed_paths;
-use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
+use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt};
 use rustc_session::lint::builtin::{
     BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS,
 };
@@ -682,6 +682,12 @@ fn non_exhaustive_match<'p, 'tcx>(
     arms: &[ArmId],
     expr_span: Span,
 ) -> ErrorGuaranteed {
+    for &arm in arms {
+        if let Err(err) = thir[arm].pattern.error_reported() {
+            return err;
+        }
+    }
+
     let is_empty_match = arms.is_empty();
     let non_empty_enum = match scrut_ty.kind() {
         ty::Adt(def, _) => def.is_enum() && !def.variants().is_empty(),
diff --git a/compiler/rustc_type_ir/src/structural_impls.rs b/compiler/rustc_type_ir/src/structural_impls.rs
index f36f4ec8697..f1037fe0baf 100644
--- a/compiler/rustc_type_ir/src/structural_impls.rs
+++ b/compiler/rustc_type_ir/src/structural_impls.rs
@@ -153,6 +153,12 @@ impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for &[T] {
     }
 }
 
+impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Box<[T]> {
+    fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
+        self.iter().try_for_each(|t| t.visit_with(visitor))
+    }
+}
+
 impl<I: Interner, T: TypeFoldable<I>, Ix: Idx> TypeFoldable<I> for IndexVec<Ix, T> {
     fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
         self.try_map_id(|x| x.try_fold_with(folder))
diff --git a/tests/ui/consts/match_ice.rs b/tests/ui/consts/match_ice.rs
index bb31fe22126..632335c841e 100644
--- a/tests/ui/consts/match_ice.rs
+++ b/tests/ui/consts/match_ice.rs
@@ -7,7 +7,7 @@ struct T;
 
 fn main() {
     const C: &S = &S;
-    match C { //~ ERROR: non-exhaustive patterns: `&_` not covered
+    match C {
         C => {}
         //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
     }
diff --git a/tests/ui/consts/match_ice.stderr b/tests/ui/consts/match_ice.stderr
index cb0d22303ac..342d94ed31c 100644
--- a/tests/ui/consts/match_ice.stderr
+++ b/tests/ui/consts/match_ice.stderr
@@ -7,24 +7,5 @@ LL |         C => {}
    = note: the traits must be derived, manual `impl`s are not sufficient
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
 
-error[E0004]: non-exhaustive patterns: `&_` not covered
-  --> $DIR/match_ice.rs:10:11
-   |
-LL |     match C {
-   |           ^ pattern `&_` not covered
-   |
-note: `S` defined here
-  --> $DIR/match_ice.rs:3:8
-   |
-LL | struct S;
-   |        ^
-   = note: the matched value is of type `&S`
-help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
-   |
-LL ~         C => {},
-LL +         &_ => todo!()
-   |
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/issue-72565.rs b/tests/ui/pattern/issue-72565.rs
index a9a5427d2ca..21edb26de08 100644
--- a/tests/ui/pattern/issue-72565.rs
+++ b/tests/ui/pattern/issue-72565.rs
@@ -2,7 +2,7 @@ const F: &'static dyn PartialEq<u32> = &7u32;
 
 fn main() {
     let a: &dyn PartialEq<u32> = &7u32;
-    match a { //~ ERROR: non-exhaustive patterns: `&_` not covered
+    match a {
         F => panic!(), //~ ERROR: `dyn PartialEq<u32>` cannot be used in patterns
     }
 }
diff --git a/tests/ui/pattern/issue-72565.stderr b/tests/ui/pattern/issue-72565.stderr
index fc9ffc06301..0519720694d 100644
--- a/tests/ui/pattern/issue-72565.stderr
+++ b/tests/ui/pattern/issue-72565.stderr
@@ -4,18 +4,5 @@ error: `dyn PartialEq<u32>` cannot be used in patterns
 LL |         F => panic!(),
    |         ^
 
-error[E0004]: non-exhaustive patterns: `&_` not covered
-  --> $DIR/issue-72565.rs:5:11
-   |
-LL |     match a {
-   |           ^ pattern `&_` not covered
-   |
-   = note: the matched value is of type `&dyn PartialEq<u32>`
-help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
-   |
-LL |         F => panic!(), &_ => todo!(),
-   |                      +++++++++++++++
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/non-structural-match-types.rs b/tests/ui/pattern/non-structural-match-types.rs
index e822a402931..fc52ee3d013 100644
--- a/tests/ui/pattern/non-structural-match-types.rs
+++ b/tests/ui/pattern/non-structural-match-types.rs
@@ -5,10 +5,10 @@
 #![feature(inline_const_pat)]
 
 fn main() {
-    match loop {} { //~ ERROR: non-exhaustive patterns: `_` not covered
-        const { || {} } => {}, //~ ERROR cannot be used in patterns
+    match loop {} {
+        const { || {} } => {} //~ ERROR cannot be used in patterns
     }
-    match loop {} { //~ ERROR: non-exhaustive patterns: `_` not covered
-        const { async {} } => {}, //~ ERROR cannot be used in patterns
+    match loop {} {
+        const { async {} } => {} //~ ERROR cannot be used in patterns
     }
 }
diff --git a/tests/ui/pattern/non-structural-match-types.stderr b/tests/ui/pattern/non-structural-match-types.stderr
index 984dd3fbc15..f3e0665fef5 100644
--- a/tests/ui/pattern/non-structural-match-types.stderr
+++ b/tests/ui/pattern/non-structural-match-types.stderr
@@ -1,39 +1,14 @@
 error: `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used in patterns
   --> $DIR/non-structural-match-types.rs:9:9
    |
-LL |         const { || {} } => {},
+LL |         const { || {} } => {}
    |         ^^^^^^^^^^^^^^^
 
 error: `{async block@$DIR/non-structural-match-types.rs:12:17: 12:25}` cannot be used in patterns
   --> $DIR/non-structural-match-types.rs:12:9
    |
-LL |         const { async {} } => {},
+LL |         const { async {} } => {}
    |         ^^^^^^^^^^^^^^^^^^
 
-error[E0004]: non-exhaustive patterns: `_` not covered
-  --> $DIR/non-structural-match-types.rs:8:11
-   |
-LL |     match loop {} {
-   |           ^^^^^^^ pattern `_` not covered
-   |
-   = note: the matched value is of type `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}`
-help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
-   |
-LL |         const { || {} } => {}, _ => todo!(),
-   |                              ++++++++++++++
-
-error[E0004]: non-exhaustive patterns: `_` not covered
-  --> $DIR/non-structural-match-types.rs:11:11
-   |
-LL |     match loop {} {
-   |           ^^^^^^^ pattern `_` not covered
-   |
-   = note: the matched value is of type `{async block@$DIR/non-structural-match-types.rs:12:17: 12:25}`
-help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
-   |
-LL |         const { async {} } => {}, _ => todo!(),
-   |                                 ++++++++++++++
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.rs
index 91a5e5a58e1..151a475c919 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.rs
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.rs
@@ -12,7 +12,7 @@ struct B(i32);
 
 fn main() {
     const FOO: [B; 1] = [B(0)];
-    match [B(1)] { //~ ERROR: non-exhaustive patterns: `[_]` not covered
+    match [B(1)] {
         FOO => { }
         //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
     }
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.stderr
index 5b81af98dfa..6adebada043 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.stderr
@@ -7,19 +7,5 @@ LL |         FOO => { }
    = note: the traits must be derived, manual `impl`s are not sufficient
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
 
-error[E0004]: non-exhaustive patterns: `[_]` not covered
-  --> $DIR/match-nonempty-array-forbidden-without-eq.rs:15:11
-   |
-LL |     match [B(1)] {
-   |           ^^^^^^ pattern `[_]` not covered
-   |
-   = note: the matched value is of type `[B; 1]`
-help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
-   |
-LL ~         FOO => { },
-LL +         [_] => todo!()
-   |
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0004`.