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 064afed9f7d44..bcecd0ff9db2f 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 2032cf13bc26e..6dc1425cf037e 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 cd88e6a22e4a5..51f2f276bbe2e 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 usize>` defined here - --> $DIR/consts-opaque.rs:106:12 + --> $DIR/consts-opaque.rs:104:12 | LL | struct Wrap(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`.