Skip to content

Improve parsing errors and suggestions for bad if statements #97474

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 1 commit into from
Jun 15, 2022

Conversation

compiler-errors
Copy link
Member

@compiler-errors compiler-errors commented May 28, 2022

  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.
  2. 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).
  3. Allow if cond token else { } to be fixed properly to if cond { token } else { }.
  4. 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:

fn main() {
    if { if true { return } else { return }; } {}
}

For context, all of these other expressions parse correctly:

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.

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label May 28, 2022
@rust-highfive
Copy link
Contributor

r? @oli-obk

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 28, 2022
@compiler-errors compiler-errors force-pushed the if-cond-and-block branch 2 times, most recently from c4f62b0 to 47c56f4 Compare May 28, 2022 05:25
@oli-obk
Copy link
Contributor

oli-obk commented May 31, 2022

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:

oof yea, nonsense code, but should still parse and compile.

I liked how the parser code actually got more readable with your changes.

Anyway, I think we should merge this as is, but since it affects what code is accepted, cc @rust-lang/wg-diagnostics @rust-lang/compiler for visibility. Will merge this next week unless there are complaints. I think this is a minor bugfix that reverts a previous accidental breaking change, so we don't need to MCP this for any team.

@bors
Copy link
Collaborator

bors commented Jun 3, 2022

☔ The latest upstream changes (presumably #97497) made this pull request unmergeable. Please resolve the merge conflicts.

@compiler-errors
Copy link
Member Author

@oli-obk this is ready to r+, I think!

@oli-obk
Copy link
Contributor

oli-obk commented Jun 14, 2022

@bors r+

@bors
Copy link
Collaborator

bors commented Jun 14, 2022

📌 Commit d1ba2d2 has been approved by oli-obk

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 14, 2022
Dylan-DPC added a commit to Dylan-DPC/rust that referenced this pull request Jun 14, 2022
…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.
@bors
Copy link
Collaborator

bors commented Jun 15, 2022

⌛ Testing commit d1ba2d2 with merge ddb6cc8...

@bors
Copy link
Collaborator

bors commented Jun 15, 2022

☀️ Test successful - checks-actions
Approved by: oli-obk
Pushing ddb6cc8 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Jun 15, 2022
@bors bors merged commit ddb6cc8 into rust-lang:master Jun 15, 2022
@rustbot rustbot added this to the 1.63.0 milestone Jun 15, 2022
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (ddb6cc8): comparison url.

Instruction count

This benchmark run did not return any relevant results for this metric.

Max RSS (memory usage)

Results
  • Primary benchmarks: mixed results
  • Secondary benchmarks: 😿 relevant regression found
mean1 max count2
Regressions 😿
(primary)
2.0% 2.0% 1
Regressions 😿
(secondary)
2.1% 2.1% 1
Improvements 🎉
(primary)
-2.9% -5.3% 3
Improvements 🎉
(secondary)
N/A N/A 0
All 😿🎉 (primary) -1.7% -5.3% 4

Cycles

Results
  • Primary benchmarks: no relevant changes found
  • Secondary benchmarks: 😿 relevant regression found
mean1 max count2
Regressions 😿
(primary)
N/A N/A 0
Regressions 😿
(secondary)
2.2% 2.2% 1
Improvements 🎉
(primary)
N/A N/A 0
Improvements 🎉
(secondary)
N/A N/A 0
All 😿🎉 (primary) N/A N/A 0

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

@rustbot label: -perf-regression

Footnotes

  1. the arithmetic mean of the percent change 2

  2. number of relevant changes 2

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Oct 27, 2022
…, r=fee1-dead

Remove an unused parser function (`Expr::returns`)

I removed the only usage in rust-lang#97474
@compiler-errors compiler-errors deleted the if-cond-and-block branch August 11, 2023 20:02
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants