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

Suggest replacing braces for brackets on array-esque invalid block expr #87830

Merged

Conversation

hkmatsumoto
Copy link
Member

Newcomers may write {1, 2, 3} for making arrays, and the current error message is not informative enough to quickly convince them what is needed to fix the error.

This PR implements a diagnostic for this case, and its output looks like this:

error: this code is interpreted as a block expression, not an array
 --> src/lib.rs:1:22
  |
1 |   const FOO: [u8; 3] = {
  |  ______________________^
2 | |     1, 2, 3
3 | | };
  | |_^
  |
  = note: to define an array, one would use square brackets instead of curly braces
help: try using [] instead of {}
  |
1 | const FOO: [u8; 3] = [
2 |     1, 2, 3
3 | ];
  |

Fix #87672

@rust-highfive
Copy link
Collaborator

r? @estebank

(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 Aug 6, 2021
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@hkmatsumoto hkmatsumoto force-pushed the suggest-brackets-for-array-esque-block-expr branch from 37b31b4 to 464351c Compare August 7, 2021 08:19
@lqd
Copy link
Member

lqd commented Aug 11, 2021

@bors try @rust-timer queue

@bors
Copy link
Contributor

bors commented Aug 11, 2021

⌛ Trying commit 82f0454953c87b55491dd1d0a0a8c08aa0a77133 with merge 3337a035d2b47609aaf087adc04a0cbba7e3beb0...

@bors
Copy link
Contributor

bors commented Aug 11, 2021

☀️ Try build successful - checks-actions
Build commit: 3337a035d2b47609aaf087adc04a0cbba7e3beb0 (3337a035d2b47609aaf087adc04a0cbba7e3beb0)

@Mark-Simulacrum
Copy link
Member

@rust-timer build 3337a035d2b47609aaf087adc04a0cbba7e3beb0

@rust-timer
Copy link
Collaborator

Queued 3337a035d2b47609aaf087adc04a0cbba7e3beb0 with parent d488de8, future comparison URL.

@rust-timer
Copy link
Collaborator

Finished benchmarking try commit (3337a035d2b47609aaf087adc04a0cbba7e3beb0): comparison url.

Summary: This benchmark run did not return any significant changes.

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

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up.

@bors rollup=never
@rustbot label: +S-waiting-on-review -S-waiting-on-perf -perf-regression

@inquisitivecrystal inquisitivecrystal added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Aug 24, 2021
@JohnCSimon JohnCSimon added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Sep 13, 2021
];

// We keep calling `look_ahead` until we reach the end of the block expression.
loop {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a somewhat different approach that might be able to make some of this code easier to reason about.

Instead of using look_ahead for cases where we kind of need to parse things with non-deterministic lookahead, I do let snapthot = self.clone() on the Parser and try to successfully parse what the "fake" syntax would be. If that succeeds, we know that we can provide an accurate suggestion, if that doesn't, we cancel the error and rollback the parser to the previous state to emit the "normal" error we currently see and let the existing error recovery machinery take its course. With this approach, it should be possible to emit a suggestion on a case like {0, if 1 < 2 {1} else {1}, 2, 3}. Because cloning is somewhat expensive (but not terrible, from what I've seen), we want to avoid it on the "happy path" of well-formed code, but you can use limited look_ahead to see if it could be this case, like doing self.look_ahead(2, |t| t.kind == &Comma) or something.

We could even try to keep information on the Parser for "we are in a const assignment, of array type" that we check here in maybe_suggest_brackets_instead_of_braces, and if it is not the case, we exit early, like we do for things coming from a macro.

What do you think? (Sorry for the delay in reviewing)

Copy link
Member Author

@hkmatsumoto hkmatsumoto Sep 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's very smart of you to come up with the approach :)
What's nice is that by cloning the parser the codebase will be significantly simplified while the suggestion keeps working almost as-is except in some cases like {if 1 < 2 {1} else {1}, 2, 3}, but that's compromisable. I assume it's unlikely to initialize an array with complex expressions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, you're too kind.

Yes, I agree that this gets 80% there for 20% of the effort. If we were relying on this for the actual language and not just for error recovery, the story would be different.

@hkmatsumoto hkmatsumoto force-pushed the suggest-brackets-for-array-esque-block-expr branch from 82f0454 to c0f4711 Compare September 18, 2021 08:50
Copy link
Contributor

@estebank estebank left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a test as well :)

compiler/rustc_parse/src/parser/expr.rs Outdated Show resolved Hide resolved
compiler/rustc_parse/src/parser/expr.rs Show resolved Hide resolved
compiler/rustc_parse/src/parser/expr.rs Outdated Show resolved Hide resolved
compiler/rustc_parse/src/parser/expr.rs Outdated Show resolved Hide resolved
@hkmatsumoto hkmatsumoto force-pushed the suggest-brackets-for-array-esque-block-expr branch 2 times, most recently from f06fb8c to 505ce05 Compare September 19, 2021 10:41
@rust-log-analyzer

This comment has been minimized.

Newcomers may write `{1, 2, 3}` for making arrays, and the current error
message is not informative enough to quickly convince them what is
needed to fix the error.
This PR implements a diagnostic for this case, and its output looks like
this:
```text
error: this code is interpreted as a block expression, not an array
 --> src/lib.rs:1:22
  |
1 |   const FOO: [u8; 3] = {
  |  ______________________^
2 | |     1, 2, 3
3 | | };
  | |_^
  |
  = note: to define an array, one would use square brackets instead of curly braces
help: try using [] instead of {}
  |
1 | const FOO: [u8; 3] = [
2 |     1, 2, 3
3 | ];
  |
```

Fix rust-lang#87672
@hkmatsumoto hkmatsumoto force-pushed the suggest-brackets-for-array-esque-block-expr branch from 505ce05 to 21eff8f Compare September 19, 2021 11:01
@estebank
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Sep 20, 2021

📌 Commit 21eff8f has been approved by estebank

@bors bors removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Sep 20, 2021
@bors bors added the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Sep 20, 2021
@bors
Copy link
Contributor

bors commented Sep 21, 2021

⌛ Testing commit 21eff8f with merge e7958d3...

@bors
Copy link
Contributor

bors commented Sep 21, 2021

☀️ Test successful - checks-actions
Approved by: estebank
Pushing e7958d3 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Sep 21, 2021
@bors bors merged commit e7958d3 into rust-lang:master Sep 21, 2021
@rustbot rustbot added this to the 1.57.0 milestone Sep 21, 2021
@hkmatsumoto hkmatsumoto deleted the suggest-brackets-for-array-esque-block-expr branch September 21, 2021 04:03
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.

Better Diagnostics When Using Wrong Brackets to Create an Array