forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#97474 - compiler-errors:if-cond-and-block, …
…r=oli-obk Improve parsing errors and suggestions for bad `if` statements 1. Parses `if {}` as `if <err> {}` (block-like conditions that are missing a "then" block), and `if true && {}` as `if true && <err> {}` (unfinished binary operation), which is a more faithful recovery and leads to better typeck errors later on. 1. Points out the span of the condition if we don't see a "then" block after it, to help the user understand what is being parsed as a condition (and by elimination, what isn't). 1. Allow `if cond token else { }` to be fixed properly to `if cond { token } else { }`. 1. Fudge with the error messages a bit. This is somewhat arbitrary and I can revert my rewordings if they're useless. ---- Also this PR addresses a strange parsing regression (1.20 -> 1.21) where we chose to reject this piece of code somewhat arbitrarily, even though we should parse it fine: ```rust fn main() { if { if true { return } else { return }; } {} } ``` For context, all of these other expressions parse correctly: ```rust fn main() { if { if true { return } else { return } } {} if { return; } {} if { return } {} if { return if true { } else { }; } {} } ``` The parser used a heuristic to determine if the "the parsed `if` condition makes sense as a condition" that did like a one-expr-deep reachability analysis. This should not be handled by the parser though.
- Loading branch information
Showing
21 changed files
with
325 additions
and
143 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,7 @@ | ||
fn main() { | ||
let n = 1; | ||
if 5 == { | ||
//~^ NOTE this `if` expression has a condition, but no block | ||
//~^ ERROR this `if` expression is missing a block after the condition | ||
println!("five"); | ||
} | ||
} | ||
//~^ ERROR expected `{`, found `}` | ||
//~| NOTE expected `{` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,14 @@ | ||
error: expected `{`, found `}` | ||
--> $DIR/if-without-block.rs:7:1 | ||
error: this `if` expression is missing a block after the condition | ||
--> $DIR/if-without-block.rs:3:5 | ||
| | ||
LL | if 5 == { | ||
| -- this `if` expression has a condition, but no block | ||
... | ||
LL | } | ||
| ^ expected `{` | ||
| ^^ | ||
| | ||
help: maybe you forgot the right operand of the condition? | ||
--> $DIR/if-without-block.rs:3:10 | ||
help: this binary operation is possibly unfinished | ||
--> $DIR/if-without-block.rs:3:8 | ||
| | ||
LL | if 5 == { | ||
| ^^ | ||
| ^^^^ | ||
|
||
error: aborting due to previous error | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
fn a() { | ||
if {} | ||
//~^ ERROR missing condition for `if` expression | ||
} | ||
|
||
fn b() { | ||
if true && {} | ||
//~^ ERROR this `if` expression is missing a block after the condition | ||
} | ||
|
||
fn c() { | ||
let x = {}; | ||
if true x | ||
//~^ ERROR expected `{`, found `x` | ||
} | ||
|
||
fn a2() { | ||
if {} else {} | ||
//~^ ERROR missing condition for `if` expression | ||
} | ||
|
||
fn b2() { | ||
if true && {} else {} | ||
//~^ ERROR this `if` expression is missing a block after the condition | ||
} | ||
|
||
fn c2() { | ||
let x = {}; | ||
if true x else {} | ||
//~^ ERROR expected `{`, found `x` | ||
} | ||
|
||
fn d() { | ||
if true else {} | ||
//~^ ERROR this `if` expression is missing a block after the condition | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
error: missing condition for `if` expression | ||
--> $DIR/bad-if-statements.rs:2:7 | ||
| | ||
LL | if {} | ||
| ^- if this block is the condition of the `if` expression, then it must be followed by another block | ||
| | | ||
| expected condition here | ||
|
||
error: this `if` expression is missing a block after the condition | ||
--> $DIR/bad-if-statements.rs:7:5 | ||
| | ||
LL | if true && {} | ||
| ^^ | ||
| | ||
help: this binary operation is possibly unfinished | ||
--> $DIR/bad-if-statements.rs:7:8 | ||
| | ||
LL | if true && {} | ||
| ^^^^^^^ | ||
|
||
error: expected `{`, found `x` | ||
--> $DIR/bad-if-statements.rs:13:13 | ||
| | ||
LL | if true x | ||
| ^ expected `{` | ||
| | ||
note: the `if` expression is missing a block after this condition | ||
--> $DIR/bad-if-statements.rs:13:8 | ||
| | ||
LL | if true x | ||
| ^^^^ | ||
help: try placing this code inside a block | ||
| | ||
LL | if true { x } | ||
| + + | ||
|
||
error: missing condition for `if` expression | ||
--> $DIR/bad-if-statements.rs:18:7 | ||
| | ||
LL | if {} else {} | ||
| ^- if this block is the condition of the `if` expression, then it must be followed by another block | ||
| | | ||
| expected condition here | ||
|
||
error: this `if` expression is missing a block after the condition | ||
--> $DIR/bad-if-statements.rs:23:5 | ||
| | ||
LL | if true && {} else {} | ||
| ^^ | ||
| | ||
help: this binary operation is possibly unfinished | ||
--> $DIR/bad-if-statements.rs:23:8 | ||
| | ||
LL | if true && {} else {} | ||
| ^^^^^^^ | ||
|
||
error: expected `{`, found `x` | ||
--> $DIR/bad-if-statements.rs:29:13 | ||
| | ||
LL | if true x else {} | ||
| ^ expected `{` | ||
| | ||
note: the `if` expression is missing a block after this condition | ||
--> $DIR/bad-if-statements.rs:29:8 | ||
| | ||
LL | if true x else {} | ||
| ^^^^ | ||
help: try placing this code inside a block | ||
| | ||
LL | if true { x } else {} | ||
| + + | ||
|
||
error: this `if` expression is missing a block after the condition | ||
--> $DIR/bad-if-statements.rs:34:5 | ||
| | ||
LL | if true else {} | ||
| ^^ | ||
| | ||
help: add a block here | ||
--> $DIR/bad-if-statements.rs:34:12 | ||
| | ||
LL | if true else {} | ||
| ^ | ||
|
||
error: aborting due to 7 previous errors | ||
|
Oops, something went wrong.