-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Recover from for-else and while-else #108427
Conversation
(rustbot has picked a reviewer for you, use r? to override) |
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.
Thanks! Having a dedicated error is great, but I don't like the suggestion.
r? diagnostics |
09ac59b
to
8574085
Compare
When this sort of thing comes up I tend to recommend https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.try_for_each, and
You can invent one, and implement Or you can change your error type to: pub enum LoopElseNotSupported{
While { .. },
For { .. }
} |
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.
Thanks! This looks great. One suggestion?
As for the suggestion, remember that the user themselves might not know what they want. When you ask people what they think Python's for..else does you'll get a split of:
In Rust, a reasonable interpretation might also be "the else branch is executed if the loop never breaks with a value" i.e. they wrote for _ in iterator {
break value
} else {
fallback_value
} |
By the way, I intentionally did not add this recovery to |
I don't see why not, especially since pointing out the |
This comment has been minimized.
This comment has been minimized.
There was a failing ui test under let-else that was checking for the old error when |
@bors r+ |
…r-errors Recover from for-else and while-else This recovers from attempts at writing for-else or while-else loops, which might help users coming from e.g. Python. ```rs for _ in 0..0 { // ... } else { // ... } ``` Combined with trying to store it in a let binding, the current diagnostic can be a bit confusing. It mentions let-else and suggests wrapping the loop in parentheses, which the user probably doesn't want. let-else doesn't make sense for `for` and `while` loops, as they are of type `()` (which already is an irrefutable pattern and doesn't need let-else). <details> <summary>Current diagnostic</summary> ```rs error: right curly brace `}` before `else` in a `let...else` statement not allowed --> src/main.rs:4:5 | 4 | } else { | ^ | help: wrap the expression in parentheses | 2 ~ let _x = (for _ in 0..0 { 3 | 4 ~ }) else { | ``` </details> Some questions: - Can the wording for the error message be improved? Would "for...else loops are not allowed" fit better? - Should we be more "conservative" in case we want to support this in the future (i.e. say "for...else loops are **currently** not allowed/supported")? - Is there a better way than storing a `&'static str` for the loop type? It is used for substituting the placeholder in the locale file (since it can emit either `for...else` or `while...else`). Maybe there is an enum I could use that I couldn't find
Looks like this failed in a rollup because |
@bors r+ |
Rollup of 7 pull requests Successful merges: - rust-lang#108143 (rustdoc: search by macro when query ends with `!`) - rust-lang#108394 (Make `x doc --open` work on every book) - rust-lang#108427 (Recover from for-else and while-else) - rust-lang#108462 (Fix `VecDeque::append` capacity overflow for ZSTs) - rust-lang#108568 (Make associated_item_def_ids for traits use an unstable option to also return associated types for RPITITs) - rust-lang#108604 (Add regression test for rust-lang#107280) - rust-lang#108605 (Add regression test for rust-lang#105821) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This recovers from attempts at writing for-else or while-else loops, which might help users coming from e.g. Python.
Combined with trying to store it in a let binding, the current diagnostic can be a bit confusing. It mentions let-else and suggests wrapping the loop in parentheses, which the user probably doesn't want. let-else doesn't make sense for
for
andwhile
loops, as they are of type()
(which already is an irrefutable pattern and doesn't need let-else).Current diagnostic
Some questions:
&'static str
for the loop type? It is used for substituting the placeholder in the locale file (since it can emit eitherfor...else
orwhile...else
). Maybe there is an enum I could use that I couldn't find