Skip to content

Commit ba7039c

Browse files
committed
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.
1 parent 0c9afa8 commit ba7039c

File tree

5 files changed

+60
-10
lines changed

5 files changed

+60
-10
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -652,9 +652,11 @@ impl<'a> Parser<'a> {
652652
} else {
653653
let token_str = Parser::token_to_string(t);
654654
let this_token_str = self.this_token_to_string();
655-
Err(self.fatal(&format!("expected `{}`, found `{}`",
656-
token_str,
657-
this_token_str)))
655+
let mut err = self.fatal(&format!("expected `{}`, found `{}`",
656+
token_str,
657+
this_token_str));
658+
err.span_label(self.span, format!("expected `{}`", token_str));
659+
Err(err)
658660
}
659661
} else {
660662
self.expect_one_of(unsafe { slice::from_raw_parts(t, 1) }, &[])
@@ -1172,7 +1174,7 @@ impl<'a> Parser<'a> {
11721174
sep: SeqSep,
11731175
f: F)
11741176
-> PResult<'a, Vec<T>> where
1175-
F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
1177+
F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
11761178
{
11771179
self.expect(bra)?;
11781180
let result = self.parse_seq_to_before_end(ket, sep, f)?;
@@ -1190,7 +1192,7 @@ impl<'a> Parser<'a> {
11901192
sep: SeqSep,
11911193
f: F)
11921194
-> PResult<'a, Spanned<Vec<T>>> where
1193-
F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
1195+
F: FnMut(&mut Parser<'a>) -> PResult<'a, T>,
11941196
{
11951197
let lo = self.span;
11961198
self.expect(bra)?;
@@ -3212,7 +3214,23 @@ impl<'a> Parser<'a> {
32123214
err.span_label(sp, "expected if condition here");
32133215
return Err(err)
32143216
}
3215-
let thn = self.parse_block()?;
3217+
let not_block = self.token != token::OpenDelim(token::Brace);
3218+
let fat_arrow_sp = if self.token == token::FatArrow {
3219+
Some(self.span)
3220+
} else {
3221+
None
3222+
};
3223+
let thn = self.parse_block().map_err(|mut err| {
3224+
if let Some(sp) = fat_arrow_sp {
3225+
// if cond => expr
3226+
err.span_suggestion(sp,
3227+
"only necessary in match arms, not before if blocks",
3228+
"".to_string());
3229+
} else if not_block {
3230+
err.span_label(lo, "this `if` statement has a condition, but no block");
3231+
}
3232+
err
3233+
})?;
32163234
let mut els: Option<P<Expr>> = None;
32173235
let mut hi = thn.span;
32183236
if self.eat_keyword(keywords::Else) {
@@ -3629,8 +3647,9 @@ impl<'a> Parser<'a> {
36293647
self.bump();
36303648
if self.token != token::CloseDelim(token::Brace) {
36313649
let token_str = self.this_token_to_string();
3632-
return Err(self.fatal(&format!("expected `{}`, found `{}`", "}",
3633-
token_str)))
3650+
let mut err = self.fatal(&format!("expected `{}`, found `{}`", "}", token_str));
3651+
err.span_label(self.span, "expected `}`");
3652+
return Err(err);
36343653
}
36353654
etc = true;
36363655
break;

src/test/ui/did_you_mean/issue-40006.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ error: expected `[`, found `#`
1919
--> $DIR/issue-40006.rs:20:17
2020
|
2121
LL | fn xxx() { ### } //~ ERROR missing
22-
| ^
22+
| ^ expected `[`
2323

2424
error: missing `fn`, `type`, or `const` for trait-item declaration
2525
--> $DIR/issue-40006.rs:20:21

src/test/ui/if-without-block.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
let n = 1;
13+
if 5 == {
14+
//~^ NOTE this `if` statement has a condition, but no block
15+
println!("five");
16+
}
17+
}
18+
//~^ ERROR expected `{`, found `}`

src/test/ui/if-without-block.stderr

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: expected `{`, found `}`
2+
--> $DIR/if-without-block.rs:17:1
3+
|
4+
13 | if 5 == {
5+
| -- this `if` statement has a condition, but no block
6+
...
7+
17 | }
8+
| ^
9+
10+
error: aborting due to previous error
11+

src/test/ui/missing-block-hint.stderr

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ error: expected `{`, found `=>`
22
--> $DIR/missing-block-hint.rs:13:18
33
|
44
LL | if (foo) => {} //~ ERROR expected `{`, found `=>`
5-
| ^^
5+
| ^^ help: only necessary in match arms, not before if blocks
66

77
error: expected `{`, found `bar`
88
--> $DIR/missing-block-hint.rs:17:13
99
|
10+
LL | if (foo)
11+
| -- this `if` statement has a condition, but no block
1012
LL | bar; //~ ERROR expected `{`, found `bar`
1113
| ^^^-
1214
| |

0 commit comments

Comments
 (0)