-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Consider disallowing let-else expression from ending in }
, as the RFC said
#119057
Comments
Detailed context copied from #118880 (comment): 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
The rule I like is that To the extent that the compiler is going to accept some |
#118880 (comment) has stats on the prevalence of the incorrectly accepted syntax on crates.io. Currently there are 0 occurrences of |
I think this would be preferable from a user-consistency point of view as I wrote into the RFC, that was the intention and I was not aware it wasn’t implemented as such until recently. I would like to point out this wording under the discussion of this issue in the RFC
Specifically that the examples I have seen where this restriction is not upheld is in relation to macros, and the RFC was specific in that the intention was for this check to happen before macro expansion (or in a way which considers a trailing |
Thanks @Fishrock123! My interpretation of that part of the RFC is (these might serve as useful unit tests)— macro_rules! m {
() => {
const { false }
};
}
fn main() {
// VALID SYNTAX despite containing `} else` after macro expansion
let false = m!() else { return; };
} macro_rules! m {
() => {
false
};
}
fn main() {
// INVALID SYNTAX due to `} else` before macro expansion
let false = m! {} else { return; };
} "Before macro expansion" isn't a completely clear way to describe the restriction because macro expansion isn't one atomic step in compilation. It is interleaved with parsing — syntax trees transit back and force between macro expansion and parsing. The parsing steps must enforce the macro_rules! m {
($($tt:tt)*) => {
let false = $($tt)* else { return; };
};
}
fn main() {
// INVALID SYNTAX during macro expansion
m!(const { false });
} macro_rules! m {
($e:expr) => {
let false = $e else { return; };
};
}
fn main() {
// ???
m!(unsafe { false });
} |
@dtolnay Yes you correctly understand how the RFC intended it. The first with I suppose it could become confusing when spectating macro expansions for debugging if the expanded output had
Fair enough; a more clear description was not pointed out to me, and sadly I have not had time to learn the internals of rustc. |
Thank you for the detailed history, @dtolnay ! That's really helpful. |
@rustbot labels -I-lang-nominated In the T-lang triage meeting today, on the basis of the outstanding history and analysis provided by @dtolnay, the consensus was that this is indeed a bug fix, and one that is safe to do. The result of this is a proposed FCP merge over in PR #119062. We appreciate @dtolnay for raising this issue and pushing it forward. |
…=davidtwco,est31 Deny braced macro invocations in let-else Fixes rust-lang#119057 Pending T-lang decision cc `@dtolnay`
Rollup merge of rust-lang#119062 - compiler-errors:asm-in-let-else, r=davidtwco,est31 Deny braced macro invocations in let-else Fixes rust-lang#119057 Pending T-lang decision cc `@dtolnay`
This is a followup to #118880 / #118859.
The compiler's implementation of let-else does not implement restrictions described by the accepted let-else RFC, so some programs that the RFC says are invalid syntax are accepted by stable Rust compilers since 1.65.0.
#118880 (comment) has the relevant examples of such code.
The text was updated successfully, but these errors were encountered: