Avoid follow-up errors on erroneous patterns

This commit is contained in:
Oli Scherer 2024-06-11 09:57:16 +00:00
parent bbe9a9c20b
commit 2733b8ab8d
7 changed files with 97 additions and 49 deletions

View File

@ -1223,12 +1223,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Type-check the tuple struct pattern against the expected type.
let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, pat_info.top_info);
let had_err = if let Some(err) = diag {
err.emit();
true
} else {
false
};
let had_err = diag.map(|diag| diag.emit());
// Type-check subpatterns.
if subpats.len() == variant.fields.len()
@ -1249,6 +1244,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None,
);
}
if let Some(e) = had_err {
on_error(e);
return Ty::new_error(tcx, e);
}
} else {
let e = self.emit_err_pat_wrong_number_of_fields(
pat.span,
@ -1257,7 +1256,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
subpats,
&variant.fields.raw,
expected,
had_err,
had_err.is_some(),
);
on_error(e);
return Ty::new_error(tcx, e);

View File

@ -1,22 +0,0 @@
//@ known-bug: #109812
#![warn(rust_2021_incompatible_closure_captures)]
enum Either {
One(X),
Two(X),
}
struct X(Y);
struct Y;
fn move_into_fnmut() {
let x = X(Y);
consume_fnmut(|| {
let Either::Two(ref mut _t) = x;
let X(mut _t) = x;
});
}

View File

@ -1,20 +0,0 @@
//@ known-bug: rust-lang/rust#125914
enum AstKind<'ast> {
ExprInt,
}
enum Foo {
Bar(isize),
Baz,
}
enum Other {
Other1(Foo),
Other2(AstKind),
}
fn main() {
match Other::Other1(Foo::Baz) {
::Other::Other2(::Foo::Bar(..)) => {}
}
}

View File

@ -0,0 +1,25 @@
//! This test used to ICE: rust-lang/rust#125914
//! Instead of actually analyzing the erroneous patterns,
//! we instead stop after typeck where errors are already
//! reported.
enum AstKind<'ast> {
//~^ ERROR: `'ast` is never used
ExprInt,
}
enum Foo {
Bar(isize),
Baz,
}
enum Other {
Other1(Foo),
Other2(AstKind), //~ ERROR: missing lifetime specifier
}
fn main() {
match Other::Other1(Foo::Baz) {
::Other::Other2(::Foo::Bar(..)) => {}
}
}

View File

@ -0,0 +1,25 @@
error[E0106]: missing lifetime specifier
--> $DIR/missing_lifetime.rs:18:12
|
LL | Other2(AstKind),
| ^^^^^^^ expected named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
LL ~ enum Other<'a> {
LL | Other1(Foo),
LL ~ Other2(AstKind<'a>),
|
error[E0392]: lifetime parameter `'ast` is never used
--> $DIR/missing_lifetime.rs:6:14
|
LL | enum AstKind<'ast> {
| ^^^^ unused lifetime parameter
|
= help: consider removing `'ast`, referring to it in a field, or using a marker such as `PhantomData`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0106, E0392.
For more information about an error, try `rustc --explain E0106`.

View File

@ -0,0 +1,30 @@
//! This test used to ICE: rust-lang/rust#109812
//! Instead of actually analyzing the erroneous patterns,
//! we instead stop after typeck where errors are already
//! reported.
#![warn(rust_2021_incompatible_closure_captures)]
enum Either {
One(X),
Two(X),
}
struct X(Y);
struct Y;
fn consume_fnmut(_: impl FnMut()) {}
fn move_into_fnmut() {
let x = X(Y);
consume_fnmut(|| {
let Either::Two(ref mut _t) = x;
//~^ ERROR: mismatched types
let X(mut _t) = x;
});
}
fn main() {}

View File

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