Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Improve parsing errors and suggestions for bad if statements #97474

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
Collaborator

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
Contributor

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
Contributor

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
Contributor

bors commented Jun 15, 2022

⌛ Testing commit d1ba2d2 with merge ddb6cc8...

@bors
Copy link
Contributor

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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