This is a tracking issue for the RFC "Or patterns, i.e `Foo(Bar(x) | Baz(x))`" (…rust-lang/rfcs#2535).
This issue also tracks the changes in rust-lang/rfcs#2175 and rust-lang/rfcs#2530 since RFC 2535 subsume those.
**Status:**
- the feature was stabilized in https://github.com/rust-lang/rust/pull/79278 though we are still working on implementing the edition migration (#83318)
**Steps:**
- [x] Implement the RFC (cc @rust-lang/compiler -- can anyone write up mentoring instructions?)
- [x] Polish the implementation
- [x] Dogfood or-patterns in the compiler and standard library (done in #71220, #71221, and #71231)
- [x] Accumulate good test coverage
- [x] Adjust documentation ([see instructions on forge][doc-guide])
- [x] Stabilization PR ([see instructions on forge][stabilization-guide])
[stabilization-guide]: https://forge.rust-lang.org/stabilization-guide.html
[doc-guide]: https://forge.rust-lang.org/stabilization-guide.html#updating-documentation
**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?
We defer this decision to stabilization as it may depend on experimentation. Our current inclination is to keep the RFC as-is because the ambiguity is not just for the compiler; for humans, it is likely also ambiguous and thus harder to read.
This also applies to functions which, although do not look as ambiguous, benefit from better consistency with closures. With respect to function arguments there's also the issue that not disambiguating with parenthesis makes it less clear whether the type ascription applies to the or-pattern as a whole or just the last alternative.
- [ ] 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.
The benefit of avoiding `pat<no_top_alt>` in as many places as possible would both be grammatical consistency and fewer surprises for uses. The drawbacks would be possible ambiguity or backtracking for closures and breakage for macros.
**Implementation history:**
- On 2019-08-18, basic parsing landed in https://github.com/rust-lang/rust/pull/61708 landed which was written by @dlrobertson and reviewed by @varkor, @Centril, @petrochenkov, @matthewjasper, and @alexreg.
- On 2019-08-27, full and polished parsing landed in https://github.com/rust-lang/rust/pull/63693 which was written by @Centril and reviewed by @estebank.
- On 2019-08-29, a typo in #63693 was fixed in https://github.com/rust-lang/rust/pull/63938 which was written by @tshepang and reviewed by @Centril.
- On 2019-09-05, https://github.com/rust-lang/rust/pull/64128, written by @Centril and reviewed by @davidtwco, landed. The PR fixed issue https://github.com/rust-lang/rust/issues/64106 where the compiler would spuriously emit `unused_parens` warnings on:
- `ref? mut? x @ (p_0 | ... | p_n)`
- `box (p_0 | ... | p_n)`
- `& mut? (p_0 | ... | p_n)`
- `|(p_0 | ... | p_n)| $expr`
- `fn foo((p_0 | ... | p_n): $type)`
- On 2019-09-06, https://github.com/rust-lang/rust/pull/64111, written by @Centril and reviewed by @petrochenkov, landed. The PR fixed the late-resolution behavior of or-patterns in nested positions including the already-bound check and binding-consistency check. Moreover, the AST now uniformly uses `ast::PatKind::Or` and has no special means of representing or-patterns at the top level.
- On 2019-09-25, https://github.com/rust-lang/rust/pull/64508, written by @Centril and reviewed by @matthewjasper, @varkor, and @nikomatsakis, landed. The PR adjusted the HIR and HAIR to consistently use or-patterns at the top & nested levels. Moreover, liveness, typeck, and dead_code analyses were adjusted also. Notably, The PR did however not adjust exhaustiveness checking. Tangentially, https://github.com/rust-lang/rust/pull/64271, landed 2019-09-12, written by @Centril and reviewed by @estebank, adjusted `check_match` diagnostics logic to be better prepared for or-patterns.
- On 2019-09-29, https://github.com/rust-lang/rust/pull/64887, written by @Centril and reviewed by @estebank, landed. The PR improved parser recovery for trailing `|` in pattern contexts.
- On 2019-10-27, https://github.com/rust-lang/rust/pull/65874, written by @Nadrieril and reviewed by @varkor, @arielb1, @nnethercote, and @Centril, landed. The PR refactored the usefulness/exhaustiveness algorithm in match checking. This laid the foundation upon which exhaustiveness checking for or-patterns was later initially implemented in https://github.com/rust-lang/rust/pull/66612.
- On 2019-11-23, https://github.com/rust-lang/rust/pull/66639, written by @Centril and reviewed by @petrochenkov, landed. In this follow-up to https://github.com/rust-lang/rust/pull/64111, the resolve logic for adding fresh bindings was simplified and re-written in a more declarative fashion.
- On 2019-12-01, https://github.com/rust-lang/rust/pull/66612, written by @Nadrieril and reviewed by @varkor, @Centril, and @matthewjasper, landed. In this follow-up to https://github.com/rust-lang/rust/pull/65874, an initial implementation of exhaustiveness / usefulness checking for or-patterns was implemented.
- On 2019-12-03, https://github.com/rust-lang/rust/pull/66967, written by @Nadrieril and reviewed by @varkor and @Centril, landed. In this follow-up to https://github.com/rust-lang/rust/pull/66612, the top-level hack for or-patterns in exhaustiveness checking was removed, making or-patterns truly first-class in match checking.
- On 2019-12-21, https://github.com/rust-lang/rust/pull/67428, written by @Centril and reviewed by @matthewjasper, landed. This PR adjusted regionck's `resolve_local::is_binding_pat` such that the `P&` grammar includes or-patterns.
- On 2019-12-22, https://github.com/rust-lang/rust/pull/67439, written by @Centril and reviewed by @matthewjasper, landed. Among other things, this PR simplified HAIR lowering of or-patterns a smidgen.
- On 2019-12-26, https://github.com/rust-lang/rust/pull/67592, written by @matthewjasper and reviewed by @Centril, landed. This PR did some preparatory cleanups in MIR lowering of `match` expressions before the MIR level support for or-patterns is added. Moreover, the PR gated or-patterns in const contexts under `const_if_match`.
- On 2020-02-04, https://github.com/rust-lang/rust/pull/67668, written by @matthewjasper and reviewed by @pnkfelix, @Centril, @nagisa, @varkor, and @eddyb, landed. The PR finally added the support for or-patterns in MIR building (dynamic semantics, borrow checking, ...). Now, nested or-patterns can actually be used on nightly with `#![feature(or_patterns)]`.
- On 2020-02-06, https://github.com/rust-lang/rust/pull/68842, written by @Centril and reviewed by @estebank landed. The PR added a regression test for an issue fixed by https://github.com/rust-lang/rust/pull/67668.
- On 2020-02-15, https://github.com/rust-lang/rust/pull/68856, written by @Centril and reviewed by @matthewjasper landed. The PR polished the type checking of patterns with respect to default binding modes. In relation to or-patterns, the PR declared that or-patterns are pass-through (`AdjustMode::Pass`) in terms of default binding modes. This was already the case in the implementation (and already stabilized for top level or-patterns) but the PR removed the FIXME that left the question open.
- On 2020-02-28, 2020-03-08, and 2020-03-08, PRs https://github.com/rust-lang/rust/pull/69452, https://github.com/rust-lang/rust/pull/69599, and https://github.com/rust-lang/rust/pull/69687 landed. These were written by @Centril and were reviewed by @estebank, @davidtwco, and @estebank respectively. All PRs tweaked and improved diagnostics wrt. or-patterns.
- On 2020-03-08, https://github.com/rust-lang/rust/pull/69690, written by @thekuom and reviewed by @Centril, landed. The relevant part of the PR added tests for the dynamic semantics of or-patterns combined with `x @ y` patterns, `box` patterns, and slice patterns.
- On 2020-03-10, https://github.com/rust-lang/rust/pull/69817, written by @thekuom and reviewed by @Centril, landed. The PR added borrow checker tests in combination with other pattern features.
- On 2020-03-11, https://github.com/rust-lang/rust/pull/69891, written by @Centril and reviewed by @varkor and @Nadrieril, landed. The PR fixed a bug (https://github.com/rust-lang/rust/issues/69875) in exhaustiveness checking where the patterns `0 | (1 | 2)` and `x @ 0 | x @ (1 | 2)` would result in an ICE.
- On 2020-03-27, https://github.com/rust-lang/rust/pull/70413, written by @AminArria and reviewed by @varkor, @Nadrieril, and @Centril, landed. The PR fixed https://github.com/rust-lang/rust/issues/70372, a false positive in the linting behavior of `unreachable_patterns` when combining or-patterns, bindings, and guards.
- On 2020-04-13, https://github.com/rust-lang/rust/pull/67766, written by @sapir and reviewed by @matthewjasper, landed. The PR fixed https://github.com/rust-lang/rust/issues/67691, a bug in the `unused_variables` lint pertaining to or-patterns.