Skip to content

Commit 8c52eaa

Browse files
committed
Avoid emitting the non_exhaustive error if other errors already occurred
1 parent 968f3cd commit 8c52eaa

File tree

11 files changed

+34
-90
lines changed

11 files changed

+34
-90
lines changed

compiler/rustc_middle/src/thir.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -581,13 +581,13 @@ pub enum BindingMode {
581581
ByRef(BorrowKind),
582582
}
583583

584-
#[derive(Clone, Debug, HashStable)]
584+
#[derive(Clone, Debug, HashStable, TypeVisitable)]
585585
pub struct FieldPat<'tcx> {
586586
pub field: FieldIdx,
587587
pub pattern: Box<Pat<'tcx>>,
588588
}
589589

590-
#[derive(Clone, Debug, HashStable)]
590+
#[derive(Clone, Debug, HashStable, TypeVisitable)]
591591
pub struct Pat<'tcx> {
592592
pub ty: Ty<'tcx>,
593593
pub span: Span,
@@ -664,7 +664,7 @@ impl<'tcx> IntoDiagnosticArg for Pat<'tcx> {
664664
}
665665
}
666666

667-
#[derive(Clone, Debug, HashStable)]
667+
#[derive(Clone, Debug, HashStable, TypeVisitable)]
668668
pub struct Ascription<'tcx> {
669669
pub annotation: CanonicalUserTypeAnnotation<'tcx>,
670670
/// Variance to use when relating the `user_ty` to the **type of the value being
@@ -688,7 +688,7 @@ pub struct Ascription<'tcx> {
688688
pub variance: ty::Variance,
689689
}
690690

691-
#[derive(Clone, Debug, HashStable)]
691+
#[derive(Clone, Debug, HashStable, TypeVisitable)]
692692
pub enum PatKind<'tcx> {
693693
/// A wildcard pattern: `_`.
694694
Wild,
@@ -702,7 +702,9 @@ pub enum PatKind<'tcx> {
702702
Binding {
703703
mutability: Mutability,
704704
name: Symbol,
705+
#[type_visitable(ignore)]
705706
mode: BindingMode,
707+
#[type_visitable(ignore)]
706708
var: LocalVarId,
707709
ty: Ty<'tcx>,
708710
subpattern: Option<Box<Pat<'tcx>>>,
@@ -767,10 +769,11 @@ pub enum PatKind<'tcx> {
767769
},
768770
}
769771

770-
#[derive(Clone, Debug, PartialEq, HashStable)]
772+
#[derive(Clone, Debug, PartialEq, HashStable, TypeVisitable)]
771773
pub struct PatRange<'tcx> {
772774
pub lo: mir::Const<'tcx>,
773775
pub hi: mir::Const<'tcx>,
776+
#[type_visitable(ignore)]
774777
pub end: RangeEnd,
775778
}
776779

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_hir::HirId;
1919
use rustc_middle::thir::visit::{self, Visitor};
2020
use rustc_middle::thir::*;
2121
use rustc_middle::ty::print::with_no_trimmed_paths;
22-
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
22+
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeVisitableExt};
2323
use rustc_session::lint::builtin::{
2424
BINDINGS_WITH_VARIANT_NAME, IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERNS,
2525
};
@@ -682,6 +682,12 @@ fn non_exhaustive_match<'p, 'tcx>(
682682
arms: &[ArmId],
683683
expr_span: Span,
684684
) -> ErrorGuaranteed {
685+
for &arm in arms {
686+
if let Err(err) = thir[arm].pattern.error_reported() {
687+
return err;
688+
}
689+
}
690+
685691
let is_empty_match = arms.is_empty();
686692
let non_empty_enum = match scrut_ty.kind() {
687693
ty::Adt(def, _) => def.is_enum() && !def.variants().is_empty(),

compiler/rustc_type_ir/src/structural_impls.rs

+6
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@ impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for &[T] {
153153
}
154154
}
155155

156+
impl<I: Interner, T: TypeVisitable<I>> TypeVisitable<I> for Box<[T]> {
157+
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
158+
self.iter().try_for_each(|t| t.visit_with(visitor))
159+
}
160+
}
161+
156162
impl<I: Interner, T: TypeFoldable<I>, Ix: Idx> TypeFoldable<I> for IndexVec<Ix, T> {
157163
fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> {
158164
self.try_map_id(|x| x.try_fold_with(folder))

tests/ui/consts/match_ice.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ struct T;
77

88
fn main() {
99
const C: &S = &S;
10-
match C { //~ ERROR: non-exhaustive patterns: `&_` not covered
10+
match C {
1111
C => {}
1212
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
1313
}

tests/ui/consts/match_ice.stderr

+1-20
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,5 @@ LL | C => {}
77
= note: the traits must be derived, manual `impl`s are not sufficient
88
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
99

10-
error[E0004]: non-exhaustive patterns: `&_` not covered
11-
--> $DIR/match_ice.rs:10:11
12-
|
13-
LL | match C {
14-
| ^ pattern `&_` not covered
15-
|
16-
note: `S` defined here
17-
--> $DIR/match_ice.rs:3:8
18-
|
19-
LL | struct S;
20-
| ^
21-
= note: the matched value is of type `&S`
22-
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
23-
|
24-
LL ~ C => {},
25-
LL + &_ => todo!()
26-
|
27-
28-
error: aborting due to 2 previous errors
10+
error: aborting due to previous error
2911

30-
For more information about this error, try `rustc --explain E0004`.

tests/ui/pattern/issue-72565.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const F: &'static dyn PartialEq<u32> = &7u32;
22

33
fn main() {
44
let a: &dyn PartialEq<u32> = &7u32;
5-
match a { //~ ERROR: non-exhaustive patterns: `&_` not covered
5+
match a {
66
F => panic!(), //~ ERROR: `dyn PartialEq<u32>` cannot be used in patterns
77
}
88
}

tests/ui/pattern/issue-72565.stderr

+1-14
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,5 @@ error: `dyn PartialEq<u32>` cannot be used in patterns
44
LL | F => panic!(),
55
| ^
66

7-
error[E0004]: non-exhaustive patterns: `&_` not covered
8-
--> $DIR/issue-72565.rs:5:11
9-
|
10-
LL | match a {
11-
| ^ pattern `&_` not covered
12-
|
13-
= note: the matched value is of type `&dyn PartialEq<u32>`
14-
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
15-
|
16-
LL | F => panic!(), &_ => todo!(),
17-
| +++++++++++++++
18-
19-
error: aborting due to 2 previous errors
7+
error: aborting due to previous error
208

21-
For more information about this error, try `rustc --explain E0004`.

tests/ui/pattern/non-structural-match-types.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
#![feature(inline_const_pat)]
66

77
fn main() {
8-
match loop {} { //~ ERROR: non-exhaustive patterns: `_` not covered
9-
const { || {} } => {}, //~ ERROR cannot be used in patterns
8+
match loop {} {
9+
const { || {} } => {} //~ ERROR cannot be used in patterns
1010
}
11-
match loop {} { //~ ERROR: non-exhaustive patterns: `_` not covered
12-
const { async {} } => {}, //~ ERROR cannot be used in patterns
11+
match loop {} {
12+
const { async {} } => {} //~ ERROR cannot be used in patterns
1313
}
1414
}
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,14 @@
11
error: `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used in patterns
22
--> $DIR/non-structural-match-types.rs:9:9
33
|
4-
LL | const { || {} } => {},
4+
LL | const { || {} } => {}
55
| ^^^^^^^^^^^^^^^
66

77
error: `{async block@$DIR/non-structural-match-types.rs:12:17: 12:25}` cannot be used in patterns
88
--> $DIR/non-structural-match-types.rs:12:9
99
|
10-
LL | const { async {} } => {},
10+
LL | const { async {} } => {}
1111
| ^^^^^^^^^^^^^^^^^^
1212

13-
error[E0004]: non-exhaustive patterns: `_` not covered
14-
--> $DIR/non-structural-match-types.rs:8:11
15-
|
16-
LL | match loop {} {
17-
| ^^^^^^^ pattern `_` not covered
18-
|
19-
= note: the matched value is of type `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}`
20-
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
21-
|
22-
LL | const { || {} } => {}, _ => todo!(),
23-
| ++++++++++++++
24-
25-
error[E0004]: non-exhaustive patterns: `_` not covered
26-
--> $DIR/non-structural-match-types.rs:11:11
27-
|
28-
LL | match loop {} {
29-
| ^^^^^^^ pattern `_` not covered
30-
|
31-
= note: the matched value is of type `{async block@$DIR/non-structural-match-types.rs:12:17: 12:25}`
32-
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
33-
|
34-
LL | const { async {} } => {}, _ => todo!(),
35-
| ++++++++++++++
36-
37-
error: aborting due to 4 previous errors
13+
error: aborting due to 2 previous errors
3814

39-
For more information about this error, try `rustc --explain E0004`.

tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ struct B(i32);
1212

1313
fn main() {
1414
const FOO: [B; 1] = [B(0)];
15-
match [B(1)] { //~ ERROR: non-exhaustive patterns: `[_]` not covered
15+
match [B(1)] {
1616
FOO => { }
1717
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]`
1818
}

tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.stderr

+1-15
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,5 @@ LL | FOO => { }
77
= note: the traits must be derived, manual `impl`s are not sufficient
88
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details
99

10-
error[E0004]: non-exhaustive patterns: `[_]` not covered
11-
--> $DIR/match-nonempty-array-forbidden-without-eq.rs:15:11
12-
|
13-
LL | match [B(1)] {
14-
| ^^^^^^ pattern `[_]` not covered
15-
|
16-
= note: the matched value is of type `[B; 1]`
17-
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
18-
|
19-
LL ~ FOO => { },
20-
LL + [_] => todo!()
21-
|
22-
23-
error: aborting due to 2 previous errors
10+
error: aborting due to previous error
2411

25-
For more information about this error, try `rustc --explain E0004`.

0 commit comments

Comments
 (0)