Increase accuracy of if
condition misparse suggestion
Look at the expression that was parsed when trying to recover from a bad `if` condition to determine what was likely intended by the user beyond "maybe this was meant to be an `else` body". ``` error: expected `{`, found `map` --> $DIR/missing-dot-on-if-condition-expression-fixable.rs:4:30 | LL | for _ in [1, 2, 3].iter()map(|x| x) {} | ^^^ expected `{` | help: you might have meant to write a method call | LL | for _ in [1, 2, 3].iter().map(|x| x) {} | + ```
This commit is contained in:
parent
917a50a039
commit
04fe839177
8 changed files with 385 additions and 17 deletions
|
@ -475,6 +475,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
fn error_block_no_opening_brace_msg(&mut self, msg: Cow<'static, str>) -> Diag<'a> {
|
||||
let prev = self.prev_token.span;
|
||||
let sp = self.token.span;
|
||||
let mut e = self.dcx().struct_span_err(sp, msg);
|
||||
let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon;
|
||||
|
@ -514,15 +515,94 @@ impl<'a> Parser<'a> {
|
|||
} else {
|
||||
stmt.span
|
||||
};
|
||||
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,
|
||||
);
|
||||
match (&self.token.kind, &stmt.kind) {
|
||||
(token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
|
||||
if let ExprKind::Call(..) = expr.kind =>
|
||||
{
|
||||
// for _ in x y() {}
|
||||
e.span_suggestion_verbose(
|
||||
prev.between(sp),
|
||||
"you might have meant to write a method call",
|
||||
".".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
(token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
|
||||
if let ExprKind::Field(..) = expr.kind =>
|
||||
{
|
||||
// for _ in x y.z {}
|
||||
e.span_suggestion_verbose(
|
||||
prev.between(sp),
|
||||
"you might have meant to write a field access",
|
||||
".".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
(token::CloseDelim(Delimiter::Brace), StmtKind::Expr(expr))
|
||||
if let ExprKind::Struct(expr) = &expr.kind
|
||||
&& let None = expr.qself
|
||||
&& expr.path.segments.len() == 1 =>
|
||||
{
|
||||
// This is specific to "mistyped `if` condition followed by empty body"
|
||||
//
|
||||
// for _ in x y {}
|
||||
e.span_suggestion_verbose(
|
||||
prev.between(sp),
|
||||
"you might have meant to write a field access",
|
||||
".".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
(token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
|
||||
if let ExprKind::Lit(lit) = expr.kind
|
||||
&& let None = lit.suffix
|
||||
&& let token::LitKind::Integer | token::LitKind::Float = lit.kind =>
|
||||
{
|
||||
// for _ in x 0 {}
|
||||
// for _ in x 0.0 {}
|
||||
e.span_suggestion_verbose(
|
||||
prev.between(sp),
|
||||
format!("you might have meant to write a field access"),
|
||||
".".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
(token::OpenDelim(Delimiter::Brace), StmtKind::Expr(expr))
|
||||
if let ExprKind::Loop(..)
|
||||
| ExprKind::If(..)
|
||||
| ExprKind::While(..)
|
||||
| ExprKind::Match(..)
|
||||
| ExprKind::ForLoop { .. }
|
||||
| ExprKind::TryBlock(..)
|
||||
| ExprKind::Ret(..)
|
||||
| ExprKind::Closure(..)
|
||||
| ExprKind::Struct(..)
|
||||
| ExprKind::Try(..) = expr.kind =>
|
||||
{
|
||||
// These are more likely to have been meant as a block body.
|
||||
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,
|
||||
);
|
||||
}
|
||||
(token::OpenDelim(Delimiter::Brace), _) => {}
|
||||
(_, _) => {
|
||||
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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue