fix ICE when parsing lifetime as function argument

This commit is contained in:
Michael Goulet 2022-02-02 10:33:13 -08:00
parent d5f9c40e6a
commit b79fc92db3
6 changed files with 60 additions and 15 deletions

View file

@ -1457,9 +1457,9 @@ impl<'a> Parser<'a> {
} else if self.check(&token::OpenDelim(token::Brace)) || self.token.is_whole_block() {
self.parse_block_expr(label, lo, BlockCheckMode::Default, attrs)
} else if !ate_colon && (self.check(&TokenKind::Comma) || self.check(&TokenKind::Gt)) {
// We're probably inside of a `Path<'a>` that needs a turbofish, so suppress the
// "must be followed by a colon" error, and the "expected one of" error.
self.diagnostic().delay_span_bug(lo, "this label wasn't parsed correctly");
// We're probably inside of a `Path<'a>` that needs a turbofish
let msg = "expected `while`, `for`, `loop` or `{` after a label";
self.struct_span_err(self.token.span, msg).span_label(self.token.span, msg).emit();
consume_colon = false;
Ok(self.mk_expr_err(lo))
} else {

View file

@ -865,14 +865,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
),
..
}) => {
// We have a situation like `while Some(0) = value.get(0) {`, where `while let`
// was more likely intended.
err.span_suggestion_verbose(
expr.span.shrink_to_lo(),
"you might have meant to use pattern destructuring",
"let ".to_string(),
Applicability::MachineApplicable,
);
// Check if our lhs is a child of the condition of a while loop
let expr_is_ancestor = std::iter::successors(Some(lhs.hir_id), |id| {
self.tcx.hir().find_parent_node(*id)
})
.take_while(|id| *id != parent)
.any(|id| id == expr.hir_id);
// if it is, then we have a situation like `while Some(0) = value.get(0) {`,
// where `while let` was more likely intended.
if expr_is_ancestor {
err.span_suggestion_verbose(
expr.span.shrink_to_lo(),
"you might have meant to use pattern destructuring",
"let ".to_string(),
Applicability::MachineApplicable,
);
}
break;
}
hir::Node::Item(_)

View file

@ -1,4 +1,15 @@
fn main() {
f<'a,>
//~^ ERROR expected
//~| ERROR expected
}
fn bar(a: usize, b: usize) -> usize {
a + b
}
fn foo() {
let x = 1;
bar('y, x);
//~^ ERROR expected
}

View file

@ -1,3 +1,9 @@
error: expected `while`, `for`, `loop` or `{` after a label
--> $DIR/issue-93282.rs:2:9
|
LL | f<'a,>
| ^ expected `while`, `for`, `loop` or `{` after a label
error: expected one of `.`, `:`, `;`, `?`, `for`, `loop`, `while`, `{`, `}`, or an operator, found `,`
--> $DIR/issue-93282.rs:2:9
|
@ -9,5 +15,11 @@ help: use `::<...>` instead of `<...>` to specify lifetime, type, or const argum
LL | f::<'a,>
| ++
error: aborting due to previous error
error: expected `while`, `for`, `loop` or `{` after a label
--> $DIR/issue-93282.rs:13:11
|
LL | bar('y, x);
| ^ expected `while`, `for`, `loop` or `{` after a label
error: aborting due to 3 previous errors

View file

@ -22,10 +22,12 @@ fn main() {
let _ = f<'_, i8>();
//~^ ERROR expected one of
//~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
//~| ERROR expected
f<'_>();
//~^ comparison operators cannot be chained
//~| HELP use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
//~| ERROR expected
let _ = f<u8>;
//~^ ERROR comparison operators cannot be chained

View file

@ -53,6 +53,12 @@ help: use `::<...>` instead of `<...>` to specify lifetime, type, or const argum
LL | let _ = f::<u8, i8>();
| ++
error: expected `while`, `for`, `loop` or `{` after a label
--> $DIR/require-parens-for-chained-comparison.rs:22:17
|
LL | let _ = f<'_, i8>();
| ^ expected `while`, `for`, `loop` or `{` after a label
error: expected one of `.`, `:`, `;`, `?`, `else`, `for`, `loop`, `while`, `{`, or an operator, found `,`
--> $DIR/require-parens-for-chained-comparison.rs:22:17
|
@ -64,8 +70,14 @@ help: use `::<...>` instead of `<...>` to specify lifetime, type, or const argum
LL | let _ = f::<'_, i8>();
| ++
error: expected `while`, `for`, `loop` or `{` after a label
--> $DIR/require-parens-for-chained-comparison.rs:27:9
|
LL | f<'_>();
| ^ expected `while`, `for`, `loop` or `{` after a label
error: comparison operators cannot be chained
--> $DIR/require-parens-for-chained-comparison.rs:26:6
--> $DIR/require-parens-for-chained-comparison.rs:27:6
|
LL | f<'_>();
| ^ ^
@ -76,7 +88,7 @@ LL | f::<'_>();
| ++
error: comparison operators cannot be chained
--> $DIR/require-parens-for-chained-comparison.rs:30:14
--> $DIR/require-parens-for-chained-comparison.rs:32:14
|
LL | let _ = f<u8>;
| ^ ^
@ -84,5 +96,5 @@ LL | let _ = f<u8>;
= help: use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments
= help: or use `(...)` if you meant to specify fn arguments
error: aborting due to 8 previous errors
error: aborting due to 10 previous errors