I propose that we stabilize #![feature(if_while_or_patterns)].
Originally proposed in RFC https://github.com/rust-lang/rfcs/pull/2175, then amended by https://github.com/rust-lang/rfcs/pull/2530, implemented (partially, see below) in https://github.com/rust-lang/rust/pull/48490 by @petrochenkov, and available in nightly since ~25th February, #![feature(if_while_or_patterns)] permits users to write multiple "or patterns" A(x) | B in if let, while let, for expressions and let statements.
See the motivation for an extended discussion; The primary reasons why this is useful are:
It permits more expressive and ergonomic control flow.
It is consistent with the behaviour of match expressions.
The next version is 1.32 which goes into beta the 7th of December; It is quite possible that this will slip into 1.33 however depending on how long the review process takes.
Users are now permitted to write for example:
enum Thing { Alpha, Beta(u8), Gamma }
if let Thing::Alpha | Thing::Gamma = Thing::Gamma {
...
}
if let 0 | 1 = 0 { ... } else { ... }
let mut iter = make_thing_iter();
while let | Thing::Beta(_) | Thing::Gamma = iter.next() {
...
}
Per https://github.com/rust-lang/rfcs/pull/2530, leading vertical bars (|) are permitted; however, this behaviour cannot be observed on nightly right now. This is a fairly minor thing that will need to be fixed (+ test) in the stabilization PR.
EDIT: A clarification: you can write if let A(x) | B(x) = expr { ... }. In other words, bindings do work.
Users are not yet permitted to write:
if let A(0 | 1) = expr { ... };
This is the generalization of or-patterns as provided for by https://github.com/rust-lang/rfcs/pull/2535. @varkor is currently working on an implementation for that generalization.
let Ok(x) | Err(x) = expr; or for Ok(x) | Err(x) in iter { ... }.
This is provided for by the RFC but the implementation was more complex so this will be implemented in the future, possibly by @varkor in the generalization.
This is a divergence from the RFC since a subset of the RFC is implemented.
@rfcbot merge
Tracking issue is: https://github.com/rust-lang/rust/issues/48215
Team member @Centril has proposed to merge this. The next step is review by the rest of the tagged teams:
Concerns:
Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!
See this document for info about what commands tagged team members can give me.
@rfcbot concern subset-without-bindings
I feel like there's little point in stabilizing this without stabilizing bindings (the Ok/Err case). What's the urgency?
@joshtriplett
There's not an urgency per se; it's just useful to have if let A | B = expr { ... } in stable Rust so that people can start using it; for example, there are places in the standard library where this would make code nicer. Targeting 1.32 is just because it's the closest nearby; if it slips to 1.33 then that's entirely fine, or we can, as @petrochenkov suggested, backport the stabilization PR to beta.
Wrt. the subset-without bindings, I had the same reaction as you, https://github.com/rust-lang/rust/issues/48215#issuecomment-435208387; this was then discussed by @petrochenkov (https://github.com/rust-lang/rust/issues/48215#issuecomment-435213531), with me being unsure in https://github.com/rust-lang/rust/issues/48215#issuecomment-435216078, and Niko noting finally in https://github.com/rust-lang/rust/issues/48215#issuecomment-435397697 that piecemeal stabilization seems fine.
Thanks for the edit clarifying the current status of bindings.
@rfcbot resolved subset-without-bindings
@rfcbot reviewed
:bell: This is now entering its final comment period, as per the review above. :bell:
Is this perhaps supposed to say while let | instead of while |?
while | Thing::Beta(_) | Thing::Gamma = iter.next()
@jonas-schievink yes, oops, thanks :) (edit: fixed)
Stabilized (https://github.com/rust-lang/rust/pull/57532) just now so closing.
Most helpful comment
:bell: This is now entering its final comment period, as per the review above. :bell: