mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 02:03:53 +00:00
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
@ -475,6 +475,7 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn error_block_no_opening_brace_msg(&mut self, msg: Cow<'static, str>) -> Diag<'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 sp = self.token.span;
|
||||||
let mut e = self.dcx().struct_span_err(sp, msg);
|
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;
|
let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon;
|
||||||
@ -514,6 +515,71 @@ impl<'a> Parser<'a> {
|
|||||||
} else {
|
} else {
|
||||||
stmt.span
|
stmt.span
|
||||||
};
|
};
|
||||||
|
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(
|
e.multipart_suggestion(
|
||||||
"try placing this code inside a block",
|
"try placing this code inside a block",
|
||||||
vec![
|
vec![
|
||||||
@ -524,6 +590,20 @@ impl<'a> Parser<'a> {
|
|||||||
Applicability::MaybeIncorrect,
|
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) => {
|
Err(e) => {
|
||||||
self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
|
self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
|
||||||
e.cancel();
|
e.cancel();
|
||||||
|
@ -16,10 +16,10 @@ LL | if $tgt.has_$field() {}
|
|||||||
LL | get_opt!(bar, foo);
|
LL | get_opt!(bar, foo);
|
||||||
| ------------------ in this macro invocation
|
| ------------------ in this macro invocation
|
||||||
= note: this error originates in the macro `get_opt` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `get_opt` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
help: try placing this code inside a block
|
help: you might have meant to write a method call
|
||||||
|
|
|
|
||||||
LL | if $tgt.has_{ $field() } {}
|
LL | if $tgt.has_.$field() {}
|
||||||
| + +
|
| +
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
@ -75,11 +75,6 @@ error: expected `{`, found `falsy`
|
|||||||
|
|
|
|
||||||
LL | } else falsy! {} {
|
LL | } else falsy! {} {
|
||||||
| ^^^^^ expected `{`
|
| ^^^^^ expected `{`
|
||||||
|
|
|
||||||
help: try placing this code inside a block
|
|
||||||
|
|
|
||||||
LL | } else { falsy! {} } {
|
|
||||||
| + +
|
|
||||||
|
|
||||||
error: expected `{`, found `falsy`
|
error: expected `{`, found `falsy`
|
||||||
--> $DIR/else-no-if.rs:54:12
|
--> $DIR/else-no-if.rs:54:12
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
//@ run-rustfix
|
||||||
|
#![allow(dead_code)]
|
||||||
|
fn main() {
|
||||||
|
for _ in [1, 2, 3].iter().map(|x| x) {}
|
||||||
|
//~^ ERROR expected `{`, found `map`
|
||||||
|
//~| HELP you might have meant to write a method call
|
||||||
|
}
|
||||||
|
fn foo5() {
|
||||||
|
let x = (vec![1, 2, 3],);
|
||||||
|
for _ in x.0 {}
|
||||||
|
//~^ ERROR expected `{`, found `0`
|
||||||
|
//~| HELP you might have meant to write a field access
|
||||||
|
}
|
||||||
|
fn foo6() {
|
||||||
|
let x = ((vec![1, 2, 3],),);
|
||||||
|
for _ in x.0.0 {}
|
||||||
|
//~^ ERROR expected `{`, found `0.0`
|
||||||
|
//~| HELP you might have meant to write a field access
|
||||||
|
}
|
||||||
|
fn foo7() {
|
||||||
|
let x = Some(vec![1, 2, 3]);
|
||||||
|
for _ in x.unwrap() {}
|
||||||
|
//~^ ERROR expected `{`, found `unwrap`
|
||||||
|
//~| HELP you might have meant to write a method call
|
||||||
|
}
|
||||||
|
fn foo8() {
|
||||||
|
let x = S { a: A { b: vec![1, 2, 3] } };
|
||||||
|
for _ in x.a.b {}
|
||||||
|
//~^ ERROR expected `{`, found `a`
|
||||||
|
//~| HELP you might have meant to write a field access
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
a: A,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct A {
|
||||||
|
b: Vec<i32>,
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
//@ run-rustfix
|
||||||
|
#![allow(dead_code)]
|
||||||
|
fn main() {
|
||||||
|
for _ in [1, 2, 3].iter()map(|x| x) {}
|
||||||
|
//~^ ERROR expected `{`, found `map`
|
||||||
|
//~| HELP you might have meant to write a method call
|
||||||
|
}
|
||||||
|
fn foo5() {
|
||||||
|
let x = (vec![1, 2, 3],);
|
||||||
|
for _ in x 0 {}
|
||||||
|
//~^ ERROR expected `{`, found `0`
|
||||||
|
//~| HELP you might have meant to write a field access
|
||||||
|
}
|
||||||
|
fn foo6() {
|
||||||
|
let x = ((vec![1, 2, 3],),);
|
||||||
|
for _ in x 0.0 {}
|
||||||
|
//~^ ERROR expected `{`, found `0.0`
|
||||||
|
//~| HELP you might have meant to write a field access
|
||||||
|
}
|
||||||
|
fn foo7() {
|
||||||
|
let x = Some(vec![1, 2, 3]);
|
||||||
|
for _ in x unwrap() {}
|
||||||
|
//~^ ERROR expected `{`, found `unwrap`
|
||||||
|
//~| HELP you might have meant to write a method call
|
||||||
|
}
|
||||||
|
fn foo8() {
|
||||||
|
let x = S { a: A { b: vec![1, 2, 3] } };
|
||||||
|
for _ in x a.b {}
|
||||||
|
//~^ ERROR expected `{`, found `a`
|
||||||
|
//~| HELP you might have meant to write a field access
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
a: A,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct A {
|
||||||
|
b: Vec<i32>,
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
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) {}
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: expected `{`, found `0`
|
||||||
|
--> $DIR/missing-dot-on-if-condition-expression-fixable.rs:10:16
|
||||||
|
|
|
||||||
|
LL | for _ in x 0 {}
|
||||||
|
| ^ expected `{`
|
||||||
|
|
|
||||||
|
help: you might have meant to write a field access
|
||||||
|
|
|
||||||
|
LL | for _ in x.0 {}
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: expected `{`, found `0.0`
|
||||||
|
--> $DIR/missing-dot-on-if-condition-expression-fixable.rs:16:16
|
||||||
|
|
|
||||||
|
LL | for _ in x 0.0 {}
|
||||||
|
| ^^^ expected `{`
|
||||||
|
|
|
||||||
|
help: you might have meant to write a field access
|
||||||
|
|
|
||||||
|
LL | for _ in x.0.0 {}
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: expected `{`, found `unwrap`
|
||||||
|
--> $DIR/missing-dot-on-if-condition-expression-fixable.rs:22:16
|
||||||
|
|
|
||||||
|
LL | for _ in x unwrap() {}
|
||||||
|
| ^^^^^^ expected `{`
|
||||||
|
|
|
||||||
|
help: you might have meant to write a method call
|
||||||
|
|
|
||||||
|
LL | for _ in x.unwrap() {}
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: expected `{`, found `a`
|
||||||
|
--> $DIR/missing-dot-on-if-condition-expression-fixable.rs:28:16
|
||||||
|
|
|
||||||
|
LL | for _ in x a.b {}
|
||||||
|
| ^ expected `{`
|
||||||
|
|
|
||||||
|
help: you might have meant to write a field access
|
||||||
|
|
|
||||||
|
LL | for _ in x.a.b {}
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
@ -0,0 +1,57 @@
|
|||||||
|
fn main() {
|
||||||
|
for _ in [1, 2, 3].iter()map(|x| x) {}
|
||||||
|
//~^ ERROR expected `{`, found `map`
|
||||||
|
//~| HELP you might have meant to write a method call
|
||||||
|
}
|
||||||
|
fn foo1() {
|
||||||
|
for _ in 1.3f64 cos() {}
|
||||||
|
//~^ ERROR expected `{`, found `cos`
|
||||||
|
//~| HELP you might have meant to write a method call
|
||||||
|
}
|
||||||
|
fn foo2() {
|
||||||
|
for _ in 1.3 cos {}
|
||||||
|
//~^ ERROR expected `{`, found `cos`
|
||||||
|
//~| HELP you might have meant to write a field access
|
||||||
|
}
|
||||||
|
fn foo3() {
|
||||||
|
for _ in 1 cos() {}
|
||||||
|
//~^ ERROR expected `{`, found `cos`
|
||||||
|
//~| HELP you might have meant to write a method call
|
||||||
|
}
|
||||||
|
fn foo4() {
|
||||||
|
for _ in 1 cos {}
|
||||||
|
//~^ ERROR expected `{`, found `cos`
|
||||||
|
//~| HELP you might have meant to write a field access
|
||||||
|
}
|
||||||
|
fn foo5() {
|
||||||
|
let x = (vec![1, 2, 3],);
|
||||||
|
for _ in x 0 {}
|
||||||
|
//~^ ERROR expected `{`, found `0`
|
||||||
|
//~| HELP you might have meant to write a field access
|
||||||
|
}
|
||||||
|
fn foo6() {
|
||||||
|
let x = ((vec![1, 2, 3],),);
|
||||||
|
for _ in x 0.0 {}
|
||||||
|
//~^ ERROR expected `{`, found `0.0`
|
||||||
|
//~| HELP you might have meant to write a field access
|
||||||
|
}
|
||||||
|
fn foo7() {
|
||||||
|
let x = Some(vec![1, 2, 3]);
|
||||||
|
for _ in x unwrap() {}
|
||||||
|
//~^ ERROR expected `{`, found `unwrap`
|
||||||
|
//~| HELP you might have meant to write a method call
|
||||||
|
}
|
||||||
|
fn foo8() {
|
||||||
|
let x = S { a: A { b: vec![1, 2, 3] } };
|
||||||
|
for _ in x a.b {}
|
||||||
|
//~^ ERROR expected `{`, found `a`
|
||||||
|
//~| HELP you might have meant to write a field access
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S {
|
||||||
|
a: A,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct A {
|
||||||
|
b: Vec<i32>,
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
error: expected `{`, found `map`
|
||||||
|
--> $DIR/missing-dot-on-if-condition-expression.rs:2: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) {}
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: expected `{`, found `cos`
|
||||||
|
--> $DIR/missing-dot-on-if-condition-expression.rs:7:21
|
||||||
|
|
|
||||||
|
LL | for _ in 1.3f64 cos() {}
|
||||||
|
| ^^^ expected `{`
|
||||||
|
|
|
||||||
|
help: you might have meant to write a method call
|
||||||
|
|
|
||||||
|
LL | for _ in 1.3f64.cos() {}
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: expected `{`, found `cos`
|
||||||
|
--> $DIR/missing-dot-on-if-condition-expression.rs:12:18
|
||||||
|
|
|
||||||
|
LL | for _ in 1.3 cos {}
|
||||||
|
| ^^^ expected `{`
|
||||||
|
|
|
||||||
|
help: you might have meant to write a field access
|
||||||
|
|
|
||||||
|
LL | for _ in 1.3.cos {}
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: expected `{`, found `cos`
|
||||||
|
--> $DIR/missing-dot-on-if-condition-expression.rs:17:16
|
||||||
|
|
|
||||||
|
LL | for _ in 1 cos() {}
|
||||||
|
| ^^^ expected `{`
|
||||||
|
|
|
||||||
|
help: you might have meant to write a method call
|
||||||
|
|
|
||||||
|
LL | for _ in 1.cos() {}
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: expected `{`, found `cos`
|
||||||
|
--> $DIR/missing-dot-on-if-condition-expression.rs:22:16
|
||||||
|
|
|
||||||
|
LL | for _ in 1 cos {}
|
||||||
|
| ^^^ expected `{`
|
||||||
|
|
|
||||||
|
help: you might have meant to write a field access
|
||||||
|
|
|
||||||
|
LL | for _ in 1.cos {}
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: expected `{`, found `0`
|
||||||
|
--> $DIR/missing-dot-on-if-condition-expression.rs:28:16
|
||||||
|
|
|
||||||
|
LL | for _ in x 0 {}
|
||||||
|
| ^ expected `{`
|
||||||
|
|
|
||||||
|
help: you might have meant to write a field access
|
||||||
|
|
|
||||||
|
LL | for _ in x.0 {}
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: expected `{`, found `0.0`
|
||||||
|
--> $DIR/missing-dot-on-if-condition-expression.rs:34:16
|
||||||
|
|
|
||||||
|
LL | for _ in x 0.0 {}
|
||||||
|
| ^^^ expected `{`
|
||||||
|
|
|
||||||
|
help: you might have meant to write a field access
|
||||||
|
|
|
||||||
|
LL | for _ in x.0.0 {}
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: expected `{`, found `unwrap`
|
||||||
|
--> $DIR/missing-dot-on-if-condition-expression.rs:40:16
|
||||||
|
|
|
||||||
|
LL | for _ in x unwrap() {}
|
||||||
|
| ^^^^^^ expected `{`
|
||||||
|
|
|
||||||
|
help: you might have meant to write a method call
|
||||||
|
|
|
||||||
|
LL | for _ in x.unwrap() {}
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: expected `{`, found `a`
|
||||||
|
--> $DIR/missing-dot-on-if-condition-expression.rs:46:16
|
||||||
|
|
|
||||||
|
LL | for _ in x a.b {}
|
||||||
|
| ^ expected `{`
|
||||||
|
|
|
||||||
|
help: you might have meant to write a field access
|
||||||
|
|
|
||||||
|
LL | for _ in x.a.b {}
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: aborting due to 9 previous errors
|
||||||
|
|
Loading…
Reference in New Issue
Block a user