Auto merge of #88835 - FabianWolff:issue-88770, r=petrochenkov

Fix error recovery in format macro parsing

Fixes #88770. Basically, the assumption in the following comment is incorrect:
b69fe57261/compiler/rustc_builtin_macros/src/format.rs (L167-L172)

This is only true in the first iteration of the loop, when [`p.clear_expected_tokens()`](b69fe57261/compiler/rustc_builtin_macros/src/format.rs (L164)) is called. In subsequent iterations, `p.expected_tokens` won't be empty, so `p.expect()` won't actually call `unexpected_try_recover()`:
b69fe57261/compiler/rustc_parse/src/parser/mod.rs (L487-L498)

Instead, it will call `expect_one_of()`, which _can_ recover and return `Ok()`. This PR handles this case to fix the ICE in #88770.
This commit is contained in:
bors 2021-09-24 11:54:29 +00:00
commit a0648eab36
4 changed files with 94 additions and 18 deletions

View file

@ -164,23 +164,22 @@ fn parse_args<'a>(
p.clear_expected_tokens();
}
// `Parser::expect` tries to recover using the
// `Parser::unexpected_try_recover` function. This function is able
// to recover if the expected token is a closing delimiter.
//
// As `,` is not a closing delimiter, it will always return an `Err`
// variant.
let mut err = p.expect(&token::Comma).unwrap_err();
match token::TokenKind::Comma.similar_tokens() {
Some(tks) if tks.contains(&p.token.kind) => {
// If a similar token is found, then it may be a typo. We
// consider it as a comma, and continue parsing.
err.emit();
p.bump();
match p.expect(&token::Comma) {
Err(mut err) => {
match token::TokenKind::Comma.similar_tokens() {
Some(tks) if tks.contains(&p.token.kind) => {
// If a similar token is found, then it may be a typo. We
// consider it as a comma, and continue parsing.
err.emit();
p.bump();
}
// Otherwise stop the parsing and return the error.
_ => return Err(err),
}
}
Ok(recovered) => {
assert!(recovered);
}
// Otherwise stop the parsing and return the error.
_ => return Err(err),
}
}
first = false;