|
2 | 2 |
|
3 | 3 | > **<sup>Syntax</sup>**\
|
4 | 4 | > _Pattern_ :\
|
| 5 | +> `|`<sup>?</sup> _PatternAllowTopAltInner_ |
| 6 | +> |
| 7 | +> _PatternNoTopAlt_ :\ |
| 8 | +> `(` _Pattern_ `)` |
| 9 | +> | _PatternInner_ |
| 10 | +> |
| 11 | +> _PatternAllowTopAltInner_ :\ |
| 12 | +> _PatternAllowTopAltInner_ `|` _PatternAllowTopAltInner_ |
| 13 | +> | _Pattern_ |
| 14 | +> |
| 15 | +> _PatternInner_ :\ |
5 | 16 | > _PatternWithoutRange_\
|
6 | 17 | > | [_RangePattern_]
|
7 | 18 | >
|
@@ -756,6 +767,57 @@ Path patterns are irrefutable when they refer to structs or an enum variant when
|
756 | 767 | has only one variant or a constant whose type is irrefutable. They are refutable when they
|
757 | 768 | refer to refutable constants or enum variants for enums with multiple variants.
|
758 | 769 |
|
| 770 | +## Or-patterns |
| 771 | + |
| 772 | +_Or-patterns_ are patterns that match on either of two sub-patterns (e.g. `A | |
| 773 | +B`). They can nest arbitrarily. Syntactically, or-patterns are allowed in any |
| 774 | +of the places where other patterns are allowed (represented by the _Pattern_ |
| 775 | +production), with the exceptions of function and closure arguments (represented |
| 776 | +by the _PatternNoTopAlt_ production). Additionally, the macro `:pat` matchers |
| 777 | +only match or-patterns in the 2021+ editions. |
| 778 | + |
| 779 | +### Static semantics |
| 780 | + |
| 781 | +1. Given a pattern `p | q` at some depth for some arbitrary patterns `p` and `q`, |
| 782 | + the pattern is considered ill-formed if: |
| 783 | + |
| 784 | + + the type inferred for `p` does not unify with the type inferred for `q`, or |
| 785 | + + the same set of bindings are not introduced in `p` and `q`, or |
| 786 | + + the type of any two bindings with the same name in `p` and `q` do not unify |
| 787 | + with respect to types or binding modes. |
| 788 | + |
| 789 | + [type coercions]: https://doc.rust-lang.org/reference/type-coercions.html |
| 790 | + |
| 791 | + Unification of types is in all instances aforementioned exact and |
| 792 | + implicit [type coercions] do not apply. |
| 793 | + |
| 794 | +2. When type checking an expression `match e_s { a_1 => e_1, ... a_n => e_n }`, |
| 795 | + for each match arm `a_i` which contains a pattern of form `p_i | q_i`, |
| 796 | + the pattern `p_i | q_i` is considered ill formed if, |
| 797 | + at the depth `d` where it exists the fragment of `e_s` at depth `d`, |
| 798 | + the type of the expression fragment does not unify with `p_i | q_i`. |
| 799 | + |
| 800 | +3. With respect to exhaustiveness checking, a pattern `p | q` is |
| 801 | + considered to cover `p` as well as `q`. For some constructor `c(x, ..)` |
| 802 | + the distributive law applies such that `c(p | q, ..rest)` covers the same |
| 803 | + set of value as `c(p, ..rest) | c(q, ..rest)` does. This can be applied |
| 804 | + recursively until there are no more nested patterns of form `p | q` other |
| 805 | + than those that exist at the top level. |
| 806 | + |
| 807 | + Note that by *"constructor"* we do not refer to tuple struct patterns, |
| 808 | + but rather we refer to a pattern for any product type. |
| 809 | + This includes enum variants, tuple structs, structs with named fields, |
| 810 | + arrays, tuples, and slices. |
| 811 | + |
| 812 | +### Dynamic semantics |
| 813 | + |
| 814 | +1. The dynamic semantics of pattern matching a scrutinee expression `e_s` |
| 815 | + against a pattern `c(p | q, ..rest)` at depth `d` where `c` is some constructor, |
| 816 | + `p` and `q` are arbitrary patterns, and `rest` is optionally any remaining |
| 817 | + potential factors in `c`, is defined as being the same as that of |
| 818 | + `c(p, ..rest) | c(q, ..rest)`. |
| 819 | + |
| 820 | + |
759 | 821 | [_GroupedPattern_]: #grouped-patterns
|
760 | 822 | [_IdentifierPattern_]: #identifier-patterns
|
761 | 823 | [_LiteralPattern_]: #literal-patterns
|
|
0 commit comments