-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
More expressions correctly are marked to end with curly braces #118880
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @nnethercote (or someone else) soon. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs tests for every one of these expressions. Please add them to some relevant subdirectory in tests/ui
, maybe just tests/ui/parser
, though you could add a subdirectory to tests/ui/parser
... up to you.
Also, this causes some code to go from passing to failing, right? If so, we need to nominate this for T-lang discussion.
Not any stable code. The only behavior changes in the PR are to #[cfg(any())]
fn repro() {
let _ = const {} else {};
let _ = do yeet {} else {};
let _ = become {} else {};
} error[E0658]: inline-const is experimental
--> src/lib.rs:3:13
|
3 | let _ = const {} else {};
| ^^^^^
|
= note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
= help: add `#![feature(inline_const)]` to the crate attributes to enable
error[E0658]: `do yeet` expression is experimental
--> src/lib.rs:4:13
|
4 | let _ = do yeet {} else {};
| ^^^^^^^^^^
|
= note: see issue #96373 <https://github.com/rust-lang/rust/issues/96373> for more information
= help: add `#![feature(yeet_expr)]` to the crate attributes to enable
error[E0658]: `become` expression is experimental
--> src/lib.rs:5:13
|
5 | let _ = become {} else {};
| ^^^^^^^^^
|
= note: see issue #112788 <https://github.com/rust-lang/rust/issues/112788> for more information
= help: add `#![feature(explicit_tail_calls)]` to the crate attributes to enable |
Break(_, _) | ||
| Range(_, _, _) | ||
| Ret(_) | ||
| Yield(_) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you make this more precise? The only pattern that must be matched here is Yield(None)
. Same with a few of the other below patterns.
Right, I misread that What about |
But I would like @rust-lang/lang to comment on other cases ending in brace, not touched in this PR, which are stable. // ExprKind::FormatArgs
let _ = format_args! {
"..."
} else {
return;
}; // ExprKind::MacCall
let Ok(_) = writeln! {
io::sink(),
"...",
} else {
return;
}; // ExprKind::IncludedBytes
let b"..." = include_bytes! {
concat!(env!("OUT_DIR"), "/the_bytes")
} else {
return;
}; // ExprKind::InlineAsm
let 0isize = asm! {
...
} else {
return;
}; and finally, unstable |
Nominating for T-lang discussion as per the comment above |
Michael is already effectively serving as reviewer, and clearly knows more about this particular piece of code than I do. Therefore: |
I have added tests for these cases, and made the match expression more explicit. |
This comment was marked as resolved.
This comment was marked as resolved.
858e9f9
to
b21631d
Compare
(removed the
has-merge-commits
|
@rustbot labels -I-lang-nominated We discussed this in the T-lang meeting today. There was a feeling that the current behavior may not in fact be ambiguous and that it may be fine to leave it as-is. However, we were a bit unsure about the ask. @dtolnay: If there's a specific rule that you would propose here for the handling of this kind of thing, please describe that and why it would be better and then renominate this issue for further discussion. |
We've talked about this today in @rust-lang/lang triage meeting. We were not sure what you are asking/proposing, @dtolnay, maybe you can clarify? Specifically it was unclear why we would want to prohibit macro examples in your comment (#118880 (comment)). Since macros use We even talked about maybe instead allowing more expressions ending in Reading the test (my personal opinions):
oops, was writing the comment at the same time as @traviscross and github did not show his post to me |
A design aspect of the let-else RFC that was important enough to feature in the 6-sentence summary is that the This restriction ended up in the RFC based on multiple rounds of feedback.
The compiler's implementation of let-else did not implement the restriction described by the accepted RFC, so some programs that the RFC says are invalid syntax are accepted by stable Rust compilers since 1.65.0. To understand why disallowing only ExpressionWithBlock is not sufficient, see the code samples containing Separately from the ambiguities explained in that comment, steffahn also was I think the first to note a human value in having rust-lang/rfcs#3137 (comment) has a summary of the consensus from Zulip and the state of the RFC after the second strengthening of the restriction. rust-lang/rfcs#3137 (comment) expresses the author's fondness in favor of the second strengthened restriction, "to be clear to human readers", which I also agree with, and is further reinforced by a lang team consensus expressed by Josh in Zulip: "Based on the lang team consensus, the thing we wanted to avoid was At the time, only one single exception to the must-not-end-in- The issue of Mentioning some of the contributors whose comments I have paraphrased, in case their view has changed since then or has not been adequately captured here: @Fishrock123 @digama0 @steffahn @camsteffen @bstrie
The rule I like is that To the extent that the compiler is going to accept some |
Thanks for the detailed history, @dtolnay. @GearsDatapacks: As for this PR, the fact that these remaining expressions can't be fixed without breaking existing code should be recorded in a FIXME, so it isn't forgotten. Since the PR only changes unstable syntax, I can r+ it after that. Also, please squash all these commits into one. @rustbot author |
…sion kinds to specify whether they contain a brace Add inline const and other possible curly brace expressions to expr_trailing_brace Add tests for `}` before `else` in `let...else` error Change to explicit cases for expressions with optional values when being checked for trailing braces Add tests for more complex cases of `}` before `else` in `let..else` statement Move other possible `}` cases into separate arm and add FIXME for future reference
b21631d
to
1fc6dbc
Compare
I added the FIXME, and squashed the commits into one. |
Is the FIXME actually fixable? If it's an edition thing, how to we record todos for the next edition? |
@bors r+ |
Not clear.
I also have no idea. I think we may want to open a new tracking issue after T-lang weighs in on the existing inconsistencies, and we can add the relevant 2024 tags to that issue. |
Yes. Currently on crates.io, here is the prevalence of each kind of expression in the EXPRESSION part of a let-else (using syn::Expr's naming):
Of the 81 macro calls, all 81 use parenthesis delimiter. 0 use square bracket delimiter or brace delimiter. |
I'm curious about the I'm surprised the |
It's parser test cases from rust-analyzer in ra_ap_parser 0.0.189. test_data/parser/err/0049_let_else_right_curly_brace_for.rs |
…iaskrgr Rollup of 4 pull requests Successful merges: - rust-lang#118880 (More expressions correctly are marked to end with curly braces) - rust-lang#118928 (fix: Overlapping spans in delimited meta-vars) - rust-lang#119022 (Remove unnecessary constness from ProjectionCandidate) - rust-lang#119052 (Avoid overflow in GVN constant indexing.) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#118880 - GearsDatapacks:issue-118859-fix, r=compiler-errors More expressions correctly are marked to end with curly braces Fixes rust-lang#118859, and replaces the mentioned match statement with an exhaustive list, so that this code doesn't get overlooked in the future
Disallow cast with trailing braced macro in let-else This fixes an edge case I noticed while porting rust-lang#118880 and rust-lang#119062 to syn. Previously, rustc incorrectly accepted code such as: ```rust let foo = &std::ptr::null as &'static dyn std::ops::Fn() -> *const primitive! { 8 } else { return; }; ``` even though a right curl brace `}` directly before `else` in a `let...else` statement is not supposed to be valid syntax.
Rollup merge of rust-lang#125049 - dtolnay:castbrace, r=compiler-errors Disallow cast with trailing braced macro in let-else This fixes an edge case I noticed while porting rust-lang#118880 and rust-lang#119062 to syn. Previously, rustc incorrectly accepted code such as: ```rust let foo = &std::ptr::null as &'static dyn std::ops::Fn() -> *const primitive! { 8 } else { return; }; ``` even though a right curl brace `}` directly before `else` in a `let...else` statement is not supposed to be valid syntax.
Fixes #118859, and replaces the mentioned match statement with an exhaustive list, so that this code doesn't get overlooked in the future