Detect missing if
blocks
When unnecessarily using a fat arrow after an if condition, suggest the removal of it. When finding an if statement with no block, point at the `if` keyword to provide more context.
This commit is contained in:
parent
0c9afa87ba
commit
ba7039cfd6
5 changed files with 60 additions and 10 deletions
|
@ -652,9 +652,11 @@ impl<'a> Parser<'a> {
|
||||||
} else {
|
} else {
|
||||||
let token_str = Parser::token_to_string(t);
|
let token_str = Parser::token_to_string(t);
|
||||||
let this_token_str = self.this_token_to_string();
|
let this_token_str = self.this_token_to_string();
|
||||||
Err(self.fatal(&format!("expected `{}`, found `{}`",
|
let mut err = self.fatal(&format!("expected `{}`, found `{}`",
|
||||||
token_str,
|
token_str,
|
||||||
this_token_str)))
|
this_token_str));
|
||||||
|
err.span_label(self.span, format!("expected `{}`", token_str));
|
||||||
|
Err(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.expect_one_of(unsafe { slice::from_raw_parts(t, 1) }, &[])
|
self.expect_one_of(unsafe { slice::from_raw_parts(t, 1) }, &[])
|
||||||
|
@ -3212,7 +3214,23 @@ impl<'a> Parser<'a> {
|
||||||
err.span_label(sp, "expected if condition here");
|
err.span_label(sp, "expected if condition here");
|
||||||
return Err(err)
|
return Err(err)
|
||||||
}
|
}
|
||||||
let thn = self.parse_block()?;
|
let not_block = self.token != token::OpenDelim(token::Brace);
|
||||||
|
let fat_arrow_sp = if self.token == token::FatArrow {
|
||||||
|
Some(self.span)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let thn = self.parse_block().map_err(|mut err| {
|
||||||
|
if let Some(sp) = fat_arrow_sp {
|
||||||
|
// if cond => expr
|
||||||
|
err.span_suggestion(sp,
|
||||||
|
"only necessary in match arms, not before if blocks",
|
||||||
|
"".to_string());
|
||||||
|
} else if not_block {
|
||||||
|
err.span_label(lo, "this `if` statement has a condition, but no block");
|
||||||
|
}
|
||||||
|
err
|
||||||
|
})?;
|
||||||
let mut els: Option<P<Expr>> = None;
|
let mut els: Option<P<Expr>> = None;
|
||||||
let mut hi = thn.span;
|
let mut hi = thn.span;
|
||||||
if self.eat_keyword(keywords::Else) {
|
if self.eat_keyword(keywords::Else) {
|
||||||
|
@ -3629,8 +3647,9 @@ impl<'a> Parser<'a> {
|
||||||
self.bump();
|
self.bump();
|
||||||
if self.token != token::CloseDelim(token::Brace) {
|
if self.token != token::CloseDelim(token::Brace) {
|
||||||
let token_str = self.this_token_to_string();
|
let token_str = self.this_token_to_string();
|
||||||
return Err(self.fatal(&format!("expected `{}`, found `{}`", "}",
|
let mut err = self.fatal(&format!("expected `{}`, found `{}`", "}", token_str));
|
||||||
token_str)))
|
err.span_label(self.span, "expected `}`");
|
||||||
|
return Err(err);
|
||||||
}
|
}
|
||||||
etc = true;
|
etc = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -19,7 +19,7 @@ error: expected `[`, found `#`
|
||||||
--> $DIR/issue-40006.rs:20:17
|
--> $DIR/issue-40006.rs:20:17
|
||||||
|
|
|
|
||||||
LL | fn xxx() { ### } //~ ERROR missing
|
LL | fn xxx() { ### } //~ ERROR missing
|
||||||
| ^
|
| ^ expected `[`
|
||||||
|
|
||||||
error: missing `fn`, `type`, or `const` for trait-item declaration
|
error: missing `fn`, `type`, or `const` for trait-item declaration
|
||||||
--> $DIR/issue-40006.rs:20:21
|
--> $DIR/issue-40006.rs:20:21
|
||||||
|
|
18
src/test/ui/if-without-block.rs
Normal file
18
src/test/ui/if-without-block.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = 1;
|
||||||
|
if 5 == {
|
||||||
|
//~^ NOTE this `if` statement has a condition, but no block
|
||||||
|
println!("five");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//~^ ERROR expected `{`, found `}`
|
11
src/test/ui/if-without-block.stderr
Normal file
11
src/test/ui/if-without-block.stderr
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
error: expected `{`, found `}`
|
||||||
|
--> $DIR/if-without-block.rs:17:1
|
||||||
|
|
|
||||||
|
13 | if 5 == {
|
||||||
|
| -- this `if` statement has a condition, but no block
|
||||||
|
...
|
||||||
|
17 | }
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
|
@ -2,11 +2,13 @@ error: expected `{`, found `=>`
|
||||||
--> $DIR/missing-block-hint.rs:13:18
|
--> $DIR/missing-block-hint.rs:13:18
|
||||||
|
|
|
|
||||||
LL | if (foo) => {} //~ ERROR expected `{`, found `=>`
|
LL | if (foo) => {} //~ ERROR expected `{`, found `=>`
|
||||||
| ^^
|
| ^^ help: only necessary in match arms, not before if blocks
|
||||||
|
|
||||||
error: expected `{`, found `bar`
|
error: expected `{`, found `bar`
|
||||||
--> $DIR/missing-block-hint.rs:17:13
|
--> $DIR/missing-block-hint.rs:17:13
|
||||||
|
|
|
|
||||||
|
LL | if (foo)
|
||||||
|
| -- this `if` statement has a condition, but no block
|
||||||
LL | bar; //~ ERROR expected `{`, found `bar`
|
LL | bar; //~ ERROR expected `{`, found `bar`
|
||||||
| ^^^-
|
| ^^^-
|
||||||
| |
|
| |
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue