Skip to content

Commit

Permalink
Skip most of check_match checks in the presence of PatKind::Error
Browse files Browse the repository at this point in the history
  • Loading branch information
Nadrieril committed Oct 14, 2023
1 parent 5eca57c commit edddcb8
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 54 deletions.
26 changes: 19 additions & 7 deletions compiler/rustc_mir_build/src/thir/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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");
Expand All @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,5 @@ LL | WHAT_A_TYPE => 0,
= 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[E0015]: cannot match on `TypeId` in constant functions
--> $DIR/typeid-equality-by-subtyping.rs:18:9
|
LL | WHAT_A_TYPE => 0,
| ^^^^^^^^^^^
|
= note: `TypeId` cannot be compared in compile-time, and therefore cannot be used in `match`es
note: impl defined here, but it is not `const`
--> $SRC_DIR/core/src/any.rs:LL:COL
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants

error: aborting due to 2 previous errors
error: aborting due to previous error

For more information about this error, try `rustc --explain E0015`.
2 changes: 0 additions & 2 deletions tests/ui/pattern/usefulness/consts-opaque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,13 @@ fn main() {
BAR => {}
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
_ => {}
//~^ ERROR unreachable pattern
}

match BAR {
BAR => {}
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
Bar => {}
_ => {}
//~^ ERROR unreachable pattern
}

match BAR {
Expand Down
41 changes: 9 additions & 32 deletions tests/ui/pattern/usefulness/consts-opaque.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {}
| ^^^
Expand All @@ -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 => {}
| ^^^
Expand All @@ -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 => {}
| ^^^
Expand All @@ -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 => {}
| ^^^
Expand All @@ -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 => {}
| ^^^
Expand All @@ -83,45 +83,22 @@ 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 => {}
| ^^^
|
= 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);
| ^^^^
Expand All @@ -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`.

0 comments on commit edddcb8

Please sign in to comment.