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 adding missing braces in const block pattern #78173

Closed
wants to merge 9 commits into from

Conversation

camelid
Copy link
Member

@camelid camelid commented Oct 21, 2020

Fixes #78168.

Previously it would only suggest wrapping the code in braces in regular
expressions; now it does it in patterns too.

r? @spastorino

@camelid camelid added A-diagnostics Area: Messages for errors, warnings, and lints A-parser Area: The parsing of Rust source code to an AST. F-inline_const Inline constants (aka: const blocks, const expressions, anonymous constants) labels Oct 21, 2020
@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 21, 2020
@camelid camelid added the A-patterns Relating to patterns and pattern matching label Oct 21, 2020
@camelid camelid marked this pull request as ready for review October 21, 2020 03:27
@@ -1060,8 +1060,8 @@ impl<'a> Parser<'a> {
})
} else if self.eat_keyword(kw::Unsafe) {
self.parse_block_expr(None, lo, BlockCheckMode::Unsafe(ast::UserProvided), attrs)
} else if self.check_inline_const() {
self.parse_const_expr(lo.to(self.token.span))
} else if self.eat_keyword(kw::Const) {
Copy link
Member

Choose a reason for hiding this comment

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

I think @petrochenkov and others wanted to avoid eating the keyword before checking if it's really an inline const. My first reaction was like ... but we're eating Unsafe right above. I'm not sure if there's another way to solve this problem and we could still rely on checking or if we just need to eat the keyword.

Anyway, would leave this to @petrochenkov

Copy link
Member

Choose a reason for hiding this comment

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

The difference is that unsafe just modifies the block expression, whereas const needs to create the ExprKind::Const - but maybe it doesn't have to be too complicated shrug.

compiler/rustc_parse/src/parser/mod.rs Show resolved Hide resolved
@spastorino
Copy link
Member

Another thought, I've 2 PRs open for inline consts that changes in some way the code you're also touching. It may be good to land those first and base your work on those.

@camelid
Copy link
Member Author

camelid commented Oct 21, 2020

Yeah, I expected to have merge conflicts :)

Weirdly, GitHub is reporting merge conflicts but bors is not. I think this issue has happened before; I’ll let T-infra take a look before I fix the conflicts so they can perhaps figure out the cause.

@camelid
Copy link
Member Author

camelid commented Oct 21, 2020

Rebased.

@camelid camelid added the A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. label Oct 22, 2020
|
LL | let const = "foo";
| ^^^^^ expected identifier, found keyword
Copy link
Member

Choose a reason for hiding this comment

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

This has regressed a bit now.
cc @oli-obk

Copy link
Member Author

Choose a reason for hiding this comment

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

The thing is that this:

let const { "foo" } = "foo";

is a totally valid statement (although it ICEs; see #78174). Perhaps we could give the old warning if it's just const and then = immediately after?

Copy link
Member

Choose a reason for hiding this comment

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

I see, but, what do you expect that code to do?.
I'd expect an error anyway something like error[E0005]: refutable pattern in local binding: ``&_`` not covered.

Copy link
Member Author

@camelid camelid Oct 22, 2020

Choose a reason for hiding this comment

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

It's valid syntactically, not semantically. (And either way it shouldn't ICE.)

And yes, the error you suggested is correct; it's the one that occurs for let "foo" = "foo";: error[E0005]: refutable pattern in local binding: `&_` not covered

Copy link
Member

Choose a reason for hiding this comment

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

exactly, 👍

@spastorino
Copy link
Member

Now both of my follow up PRs are in and you would need to rebase again :). I think this is fine modulo the eat_keyword part, which to be honest I'm not sure. I'm not sure if there's a way to avoid it, my first solution used it too and then after some reviews I got rid of it.

Anyway, this is fine by me but would leave this up to r? @petrochenkov

@petrochenkov
Copy link
Contributor

@camelid
Could you rebase this over #78116? There were some significant changes in the same area in that PR.

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 24, 2020
@camelid camelid added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Oct 24, 2020
@petrochenkov
Copy link
Contributor

@camelid
I have a suggestion for a different approach for const in expressions.
In expressions we have a well established precedent for general-purpose unary operators, including keyword-based ones like box.

So I suggest to parse const expr in expressions exactly like a unary operator box expr, but then report a non-fatal error if expr is not actually a block.
The only difference would be an extra check at statement start to avoid interpreting const IDENT: ... or const _: ... items as const expressions.

In patterns we have the unary box operator too, so const recovery can potentially work in the same way as in expressions (parse const PAT, error if PAT is not a block), but I'm not sure about interactions with range patterns, they may require special cases.

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 24, 2020
@JohnCSimon
Copy link
Member

hello from triage:
@camelid - can you address the comment from petrochenkov

@camelid
Copy link
Member Author

camelid commented Nov 9, 2020

Yes, this is on my todo list to figure out.

@crlf0710
Copy link
Member

@camelid Ping from triage: Any updates on this?

@crlf0710 crlf0710 added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Nov 28, 2020
@camelid
Copy link
Member Author

camelid commented Dec 18, 2020

I'm hoping to get to this at some point soon, I just need to understand this part of the codebase better.

@petrochenkov
Copy link
Contributor

This can be split into two parts - one for expressions (which should be pretty much a copypaste of what box does), and another for patterns which may require some more thought.

@camelid
Copy link
Member Author

camelid commented Dec 31, 2020

Starting with a rebase.

@camelid
Copy link
Member Author

camelid commented Jan 1, 2021

I have a suggestion for a different approach for const in expressions.
In expressions we have a well established precedent for general-purpose unary operators, including keyword-based ones like box.

So I suggest to parse const expr in expressions exactly like a unary operator box expr, but then report a non-fatal error if expr is not actually a block.

@petrochenkov One issue with this is that prefix operators have high precedence, so the suggestion for wrapping the code in a block doesn't capture what it should:

error: expected inline const block
  --> $DIR/inline-const-without-block.rs:50:19
   |
LL |     let y = const 1 + 2 * 3 / 4;
   |                   ^ help: try placing this code inside a block: `{ 1 }`

I'm not sure if there's a good way to resolve this because of the precedence of prefix operators. I haven't made many changes to the parser before, so I would appreciate some extra guidance! Thanks :)

@camelid camelid added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 1, 2021
@petrochenkov
Copy link
Contributor

const { 1 } is the behavior that I expected, if const starts working without braces like box, then it's exactly the priority that it will have.
We also don't know what it "should" capture in general case - code like const { f() } + 1 is as reasonable as const { f() + 1 }.

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 1, 2021
@JohnCSimon JohnCSimon added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 19, 2021
@JohnCSimon JohnCSimon added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 14, 2021
@petrochenkov
Copy link
Contributor

Closing due to inactivity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-parser Area: The parsing of Rust source code to an AST. A-patterns Relating to patterns and pattern matching A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix`. F-inline_const Inline constants (aka: const blocks, const expressions, anonymous constants) S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improve error for missing braces in const block
7 participants