owned this note
owned this note
Published
Linked with GitHub
# Stabilization Report
This is a stabilization report for the `or_patterns` feature. It does _NOT_ stabilize the `edition_macro_pat` feature; i.e. `:pat2018/21` remain unstable.
A mighty Thank You to the many people who designed, implemented, and reviewed this feature, including (in no particular order, and apologies to any I have missed) Centril, varkor, Nadrieril, matthewjasper, petrochenkov, alexreg, estebank, davidtwco, nikomatsakis, arielb1, nnethercote, pnkfelix, nagisa, eddyb, thekuom, sapir, Nemo157, and joshtriplett :tada:
# Examples
This stabilization allows nested or-patterns in stable Rust in all of the following cases:
1. `if let` expressions:
```rust
if let Foo::Bar | Foo::Quux(1 | 2) = some_computation() {
...
}
```
1. `while let` expressions:
```rust
while let Ok(1 | 2) | Err(3) = different_computation() {
...
}
```
3. `let` statements:
```rust
let Ok(x) | Err(x) = another_computation();
```
In this case, the pattern must be irrefutable as `Ok(x) | Err(x)` is.
4. `fn` arguments:
```rust
fn foo((Ok(x) | Err(x)): Result<u8, u8>) {
...
}
```
Here too, the pattern must be irrefutable.
5. `match` patterns:
```rust
match foo {
Foo::Bar | Foo::Quux(1 | 2) => { ... }
...
}
```
It does _not_ stabilize or-patterns in closure arguments or macro `:pat` matchers (more below).
# Test cases
Test cases can be found in [the dedicated folder](https://github.com/rust-lang/rust/tree/a4cbb44ae2c80545db957763b502dc7f6ea22085/src/test/ui/or-patterns).
Additionally, the following tests test the behavior of `:pat` in different editions:
- [src/test/ui/macros/macro-pat-follow.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/macros/macro-pat-follow.rs)
- [src/test/ui/macros/macro-pat-follow-2018.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/macros/macro-pat-follow-2018.rs)
- [src/test/ui/macros/edition-macro-pats.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/macros/edition-macro-pats.rs)
And the feature gate test for `edition_macro_pat`:
- [src/test/ui/feature-gate-edition_macro_pats.rs](https://github.com/rust-lang/rust/blob/master/src/test/ui/feature-gate-edition_macro_pats.rs)
# Documentation
The RFC contains the precise [grammar changes][grammar].
PR to update the reference: https://github.com/rust-lang/reference/pull/957
# Other Relevant Info
petrochekov [raised a concern](https://github.com/rust-lang/rust/issues/54883#issuecomment-742802350) about simplifying the grammar for patterns to allow a leading vert (`|`) at nested levels, not just at the top level. There was [an FCP](https://github.com/rust-lang/rust/issues/81415), and there is team consensus for doing so. However, we do not implement it in this PR because it is a backwards-compatible change. It allows strictly more code to compile. The only place where such a grammar change could be visible is in macros in 2021+, which are still unstable.
# Resolved Unresolved Questions
> Should we allow top_pat or pat<allow_top_alt> in inferrable_param such that closures permit |Ok(x) | Err(x)| without first wrapping in parenthesis?
In the [2020-11-10 T-lang meeting][tlangcon], there was consensus this should not be allowed. Despite the consistency with other places where patterns are allowed, this syntax was deemed to be too confusing.
> Should the pat macro fragment specifier match top_pat in different Rust editions or should it match pat<no_top_alt> as currently specified? We defer such decisions to stabilization because it depends on the outcome of crater runs to see what the extent of the breakage would be.
Originally, it was thought that `:pat` could match `top_pat` in all editions, but two crater runs ([0][crater0], [1][crater1]) showed that even with a fallback plan, there was lots of complex breakage.
Instead, in the [2020-12-15 T-lang meeting][tlangcon2], there was consensus that in Rust 2015/18, `:pat` would continue to match `pat<no_top_alt>` (as it already does), while in Rust 2021 and onward, it would match `top_pat`. This means that in Rust 2015/18, `:pat` will _not_ match top-level or-patterns, but in subsequent editions it will.
Additionally, to allow cross-edition macro usage, the `:pat2018` and `:pat2021` matchers were introduced behind the `edition_macro_pat` feature, which is _not_ being stabilized in this stabilization report.
[grammar]: https://github.com/rust-lang/rfcs/blob/master/text/2535-or-patterns.md#reference-level-explanation
[tlangcon]: https://github.com/rust-lang/rust/issues/54883#issuecomment-724898641
[crater0]: https://github.com/rust-lang/rust/pull/78935#issuecomment-735050394
[crater1]: https://github.com/rust-lang/rust/pull/78935#issuecomment-740828151
[tlangcon2]: https://github.com/rust-lang/rust/issues/54883#issuecomment-745509090