Tweak diagnostics
* Recover from invalid `'label: ` before block. * Make suggestion to enclose statements in a block multipart. * Point at `match`, `while`, `loop` and `unsafe` keywords when failing to parse their expression. * Do not suggest `{ ; }`. * Do not suggest `|` when very unlikely to be what was wanted (in `let` statements).
This commit is contained in:
parent
97cde9fe08
commit
f42b4f595e
26 changed files with 316 additions and 161 deletions
|
@ -434,6 +434,8 @@ impl<'a> Parser<'a> {
|
|||
Ok(Some(_))
|
||||
if self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace))
|
||||
|| do_not_suggest_help => {}
|
||||
// Do not suggest `if foo println!("") {;}` (as would be seen in test for #46836).
|
||||
Ok(Some(Stmt { kind: StmtKind::Empty, .. })) => {}
|
||||
Ok(Some(stmt)) => {
|
||||
let stmt_own_line = self.sess.source_map().is_line_before_span_empty(sp);
|
||||
let stmt_span = if stmt_own_line && self.eat(&token::Semi) {
|
||||
|
@ -442,15 +444,15 @@ impl<'a> Parser<'a> {
|
|||
} else {
|
||||
stmt.span
|
||||
};
|
||||
if let Ok(snippet) = self.span_to_snippet(stmt_span) {
|
||||
e.span_suggestion(
|
||||
stmt_span,
|
||||
"try placing this code inside a block",
|
||||
format!("{{ {} }}", snippet),
|
||||
// Speculative; has been misleading in the past (#46836).
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
e.multipart_suggestion(
|
||||
"try placing this code inside a block",
|
||||
vec![
|
||||
(stmt_span.shrink_to_lo(), "{ ".to_string()),
|
||||
(stmt_span.shrink_to_hi(), " }".to_string()),
|
||||
],
|
||||
// Speculative; has been misleading in the past (#46836).
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
|
||||
|
@ -483,15 +485,15 @@ impl<'a> Parser<'a> {
|
|||
) -> PResult<'a, (Vec<Attribute>, P<Block>)> {
|
||||
maybe_whole!(self, NtBlock, |x| (Vec::new(), x));
|
||||
|
||||
self.maybe_recover_unexpected_block_label();
|
||||
if !self.eat(&token::OpenDelim(token::Brace)) {
|
||||
return self.error_block_no_opening_brace();
|
||||
}
|
||||
|
||||
let attrs = self.parse_inner_attributes()?;
|
||||
let tail = if let Some(tail) = self.maybe_suggest_struct_literal(lo, blk_mode) {
|
||||
tail?
|
||||
} else {
|
||||
self.parse_block_tail(lo, blk_mode, AttemptLocalParseRecovery::Yes)?
|
||||
let tail = match self.maybe_suggest_struct_literal(lo, blk_mode) {
|
||||
Some(tail) => tail?,
|
||||
None => self.parse_block_tail(lo, blk_mode, AttemptLocalParseRecovery::Yes)?,
|
||||
};
|
||||
Ok((attrs, tail))
|
||||
}
|
||||
|
@ -587,11 +589,11 @@ impl<'a> Parser<'a> {
|
|||
// We might be at the `,` in `let x = foo<bar, baz>;`. Try to recover.
|
||||
match &mut local.kind {
|
||||
LocalKind::Init(expr) | LocalKind::InitElse(expr, _) => {
|
||||
self.check_mistyped_turbofish_with_multiple_type_params(e, expr)?;
|
||||
// We found `foo<bar, baz>`, have we fully recovered?
|
||||
self.expect_semi()?;
|
||||
}
|
||||
LocalKind::Decl => return Err(e),
|
||||
self.check_mistyped_turbofish_with_multiple_type_params(e, expr)?;
|
||||
// We found `foo<bar, baz>`, have we fully recovered?
|
||||
self.expect_semi()?;
|
||||
}
|
||||
LocalKind::Decl => return Err(e),
|
||||
}
|
||||
eat_semi = false;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue