about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNadrieril <nadrieril+git@gmail.com>2023-10-14 03:06:18 +0200
committerNadrieril <nadrieril+git@gmail.com>2023-10-14 13:38:04 +0200
commit89f75ff4d05d22ca3b9b3d70fc6bcd225c8dbf12 (patch)
tree84b9c674b13761fcb02757f9e57fa2e58130cb23
parent8646afb9c5ddad4e7c6805390d5265db54203f0d (diff)
downloadrust-89f75ff4d05d22ca3b9b3d70fc6bcd225c8dbf12.tar.gz
rust-89f75ff4d05d22ca3b9b3d70fc6bcd225c8dbf12.zip
Skip most of check_match checks in the presence of `PatKind::Error`
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs26
-rw-r--r--tests/ui/pattern/usefulness/consts-opaque.rs2
-rw-r--r--tests/ui/pattern/usefulness/consts-opaque.stderr41
3 files changed, 28 insertions, 41 deletions
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 064afed9f7d..bcecd0ff9db 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -231,6 +231,10 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
         if let LetSource::None = source {
             return;
         }
+        if let Err(err) = pat.pat_error_reported() {
+            self.error = Err(err);
+            return;
+        }
         self.check_patterns(pat, Refutable);
         let mut cx = self.new_cx(self.lint_level, true);
         let tpat = self.lower_pattern(&mut cx, pat);
@@ -252,6 +256,10 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
             self.with_lint_level(arm.lint_level, |this| {
                 this.check_patterns(&arm.pattern, Refutable);
             });
+            if let Err(err) = arm.pattern.pat_error_reported() {
+                self.error = Err(err);
+                return;
+            }
         }
 
         let tarms: Vec<_> = arms
@@ -334,7 +342,8 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
         // and record chain members that aren't let exprs.
         let mut chain_refutabilities = Vec::new();
 
-        let add = |expr: ExprId, mut local_lint_level| {
+        let mut error = Ok(());
+        let mut add = |expr: ExprId, mut local_lint_level| {
             // `local_lint_level` is the lint level enclosing the pattern inside `expr`.
             let mut expr = &self.thir[expr];
             debug!(?expr, ?local_lint_level, "add");
@@ -348,6 +357,10 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
             debug!(?expr, ?local_lint_level, "after scopes");
             match expr.kind {
                 ExprKind::Let { box ref pat, expr: _ } => {
+                    if let Err(err) = pat.pat_error_reported() {
+                        error = Err(err);
+                        return None;
+                    }
                     let mut ncx = self.new_cx(local_lint_level, true);
                     let tpat = self.lower_pattern(&mut ncx, pat);
                     let refutable = !is_let_irrefutable(&mut ncx, local_lint_level, tpat);
@@ -380,6 +393,11 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
         debug!(?chain_refutabilities);
         chain_refutabilities.reverse();
 
+        if error.is_err() {
+            self.error = error;
+            return;
+        }
+
         // Third, emit the actual warnings.
         if chain_refutabilities.iter().all(|r| matches!(*r, Some((_, false)))) {
             // The entire chain is made up of irrefutable `let` statements
@@ -688,12 +706,6 @@ fn non_exhaustive_match<'p, 'tcx>(
     arms: &[ArmId],
     expr_span: Span,
 ) -> ErrorGuaranteed {
-    for &arm in arms {
-        if let Err(err) = thir[arm].pattern.pat_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/tests/ui/pattern/usefulness/consts-opaque.rs b/tests/ui/pattern/usefulness/consts-opaque.rs
index 2032cf13bc2..6dc1425cf03 100644
--- a/tests/ui/pattern/usefulness/consts-opaque.rs
+++ b/tests/ui/pattern/usefulness/consts-opaque.rs
@@ -52,7 +52,6 @@ fn main() {
         BAR => {}
         //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
         _ => {}
-        //~^ ERROR unreachable pattern
     }
 
     match BAR {
@@ -60,7 +59,6 @@ fn main() {
         //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
         Bar => {}
         _ => {}
-        //~^ ERROR unreachable pattern
     }
 
     match BAR {
diff --git a/tests/ui/pattern/usefulness/consts-opaque.stderr b/tests/ui/pattern/usefulness/consts-opaque.stderr
index cd88e6a22e4..51f2f276bbe 100644
--- a/tests/ui/pattern/usefulness/consts-opaque.stderr
+++ b/tests/ui/pattern/usefulness/consts-opaque.stderr
@@ -38,7 +38,7 @@ LL |         BAR => {}
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
 
 error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:59:9
+  --> $DIR/consts-opaque.rs:58:9
    |
 LL |         BAR => {}
    |         ^^^
@@ -47,7 +47,7 @@ LL |         BAR => {}
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
 
 error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:67:9
+  --> $DIR/consts-opaque.rs:65:9
    |
 LL |         BAR => {}
    |         ^^^
@@ -56,7 +56,7 @@ LL |         BAR => {}
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
 
 error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:69:9
+  --> $DIR/consts-opaque.rs:67:9
    |
 LL |         BAR => {}
    |         ^^^
@@ -65,7 +65,7 @@ LL |         BAR => {}
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
 
 error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:75:9
+  --> $DIR/consts-opaque.rs:73:9
    |
 LL |         BAZ => {}
    |         ^^^
@@ -74,7 +74,7 @@ LL |         BAZ => {}
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
 
 error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:83:9
+  --> $DIR/consts-opaque.rs:81:9
    |
 LL |         BAZ => {}
    |         ^^^
@@ -83,7 +83,7 @@ LL |         BAZ => {}
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
 
 error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]`
-  --> $DIR/consts-opaque.rs:89:9
+  --> $DIR/consts-opaque.rs:87:9
    |
 LL |         BAZ => {}
    |         ^^^
@@ -91,37 +91,14 @@ LL |         BAZ => {}
    = 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: unreachable pattern
-  --> $DIR/consts-opaque.rs:54:9
-   |
-LL |         Bar => {}
-   |         --- matches any value
-...
-LL |         _ => {}
-   |         ^ unreachable pattern
-   |
-note: the lint level is defined here
-  --> $DIR/consts-opaque.rs:6:9
-   |
-LL | #![deny(unreachable_patterns)]
-   |         ^^^^^^^^^^^^^^^^^^^^
-
-error: unreachable pattern
-  --> $DIR/consts-opaque.rs:62:9
-   |
-LL |         Bar => {}
-   |         --- matches any value
-LL |         _ => {}
-   |         ^ unreachable pattern
-
 error[E0004]: non-exhaustive patterns: `Wrap(_)` not covered
-  --> $DIR/consts-opaque.rs:124:11
+  --> $DIR/consts-opaque.rs:122:11
    |
 LL |     match WRAPQUUX {
    |           ^^^^^^^^ pattern `Wrap(_)` not covered
    |
 note: `Wrap<fn(usize, usize) -> usize>` defined here
-  --> $DIR/consts-opaque.rs:106:12
+  --> $DIR/consts-opaque.rs:104:12
    |
 LL |     struct Wrap<T>(T);
    |            ^^^^
@@ -132,6 +109,6 @@ LL ~         WRAPQUUX => {},
 LL +         Wrap(_) => todo!()
    |
 
-error: aborting due to 12 previous errors; 1 warning emitted
+error: aborting due to 10 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0004`.