Skip to content

Commit b6adf21

Browse files
committed
Avoid follow-up errors on erroneous patterns
1 parent 56e112a commit b6adf21

File tree

7 files changed

+97
-49
lines changed

7 files changed

+97
-49
lines changed

compiler/rustc_hir_typeck/src/pat.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -1223,12 +1223,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12231223

12241224
// Type-check the tuple struct pattern against the expected type.
12251225
let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, pat_info.top_info);
1226-
let had_err = if let Some(err) = diag {
1227-
err.emit();
1228-
true
1229-
} else {
1230-
false
1231-
};
1226+
let had_err = diag.map(|diag| diag.emit());
12321227

12331228
// Type-check subpatterns.
12341229
if subpats.len() == variant.fields.len()
@@ -1249,6 +1244,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12491244
None,
12501245
);
12511246
}
1247+
if let Some(e) = had_err {
1248+
on_error(e);
1249+
return Ty::new_error(tcx, e);
1250+
}
12521251
} else {
12531252
let e = self.emit_err_pat_wrong_number_of_fields(
12541253
pat.span,
@@ -1257,7 +1256,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12571256
subpats,
12581257
&variant.fields.raw,
12591258
expected,
1260-
had_err,
1259+
had_err.is_some(),
12611260
);
12621261
on_error(e);
12631262
return Ty::new_error(tcx, e);

tests/crashes/109812.rs

-22
This file was deleted.

tests/crashes/125914.rs

-20
This file was deleted.

tests/ui/pattern/missing_lifetime.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//! This test used to ICE: rust-lang/rust#125914
2+
//! Instead of actually analyzing the erroneous patterns,
3+
//! we instead stop after typeck where errors are already
4+
//! reported.
5+
//!
6+
enum AstKind<'ast> {
7+
//~^ ERROR: `'ast` is never used
8+
ExprInt,
9+
}
10+
11+
enum Foo {
12+
Bar(isize),
13+
Baz,
14+
}
15+
16+
enum Other {
17+
Other1(Foo),
18+
Other2(AstKind), //~ ERROR: missing lifetime specifier
19+
}
20+
21+
fn main() {
22+
match Other::Other1(Foo::Baz) {
23+
::Other::Other2(::Foo::Bar(..)) => {}
24+
}
25+
}
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
error[E0106]: missing lifetime specifier
2+
--> $DIR/missing_lifetime.rs:18:12
3+
|
4+
LL | Other2(AstKind),
5+
| ^^^^^^^ expected named lifetime parameter
6+
|
7+
help: consider introducing a named lifetime parameter
8+
|
9+
LL ~ enum Other<'a> {
10+
LL | Other1(Foo),
11+
LL ~ Other2(AstKind<'a>),
12+
|
13+
14+
error[E0392]: lifetime parameter `'ast` is never used
15+
--> $DIR/missing_lifetime.rs:6:14
16+
|
17+
LL | enum AstKind<'ast> {
18+
| ^^^^ unused lifetime parameter
19+
|
20+
= help: consider removing `'ast`, referring to it in a field, or using a marker such as `PhantomData`
21+
22+
error: aborting due to 2 previous errors
23+
24+
Some errors have detailed explanations: E0106, E0392.
25+
For more information about an error, try `rustc --explain E0106`.

tests/ui/pattern/type_mismatch.rs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//! This test used to ICE: rust-lang/rust#109812
2+
//! Instead of actually analyzing the erroneous patterns,
3+
//! we instead stop after typeck where errors are already
4+
//! reported.
5+
6+
#![warn(rust_2021_incompatible_closure_captures)]
7+
8+
enum Either {
9+
One(X),
10+
Two(X),
11+
}
12+
13+
struct X(Y);
14+
15+
struct Y;
16+
17+
fn consume_fnmut(_: impl FnMut()) {}
18+
19+
fn move_into_fnmut() {
20+
let x = X(Y);
21+
22+
consume_fnmut(|| {
23+
let Either::Two(ref mut _t) = x;
24+
//~^ ERROR: mismatched types
25+
26+
let X(mut _t) = x;
27+
});
28+
}
29+
30+
fn main() {}

tests/ui/pattern/type_mismatch.stderr

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/type_mismatch.rs:23:13
3+
|
4+
LL | let Either::Two(ref mut _t) = x;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `X`
6+
| |
7+
| expected `X`, found `Either`
8+
9+
error: aborting due to 1 previous error
10+
11+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)