Skip to content

Commit 940de70

Browse files
committed
document or-patterns
1 parent 152f877 commit 940de70

File tree

3 files changed

+64
-2
lines changed

3 files changed

+64
-2
lines changed

src/expressions/closure-expr.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
> &nbsp;&nbsp; _ClosureParam_ (`,` _ClosureParam_)<sup>\*</sup> `,`<sup>?</sup>
1111
>
1212
> _ClosureParam_ :\
13-
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> [_Pattern_]&nbsp;( `:` [_Type_] )<sup>?</sup>
13+
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> [_PatternNoTopAlt_]&nbsp;( `:` [_Type_] )<sup>?</sup>
1414
1515
A _closure expression_, also know as a lambda expression or a lambda, defines a
1616
closure and denotes it as a value, in a single expression. A closure expression

src/items/functions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
> )
3333
>
3434
> _FunctionParamPattern_ :\
35-
> &nbsp;&nbsp; [_Pattern_] `:` ( [_Type_] | `...` )
35+
> &nbsp;&nbsp; [_PatternNoTopAlt_] `:` ( [_Type_] | `...` )
3636
>
3737
> _FunctionReturnType_ :\
3838
> &nbsp;&nbsp; `->` [_Type_]

src/patterns.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
> **<sup>Syntax</sup>**\
44
> _Pattern_ :\
5+
> &nbsp;&nbsp; &nbsp;&nbsp; `|`<sup>?</sup> _PatternAllowTopAltInner_
6+
>
7+
> _PatternNoTopAlt_ :\
8+
> &nbsp;&nbsp; &nbsp;&nbsp; `(` _Pattern_ `)`
9+
> &nbsp;&nbsp; | _PatternInner_
10+
>
11+
> _PatternAllowTopAltInner_ :\
12+
> &nbsp;&nbsp; &nbsp;&nbsp; _PatternAllowTopAltInner_ `|` _PatternAllowTopAltInner_
13+
> &nbsp;&nbsp; | _Pattern_
14+
>
15+
> _PatternInner_ :\
516
> &nbsp;&nbsp; &nbsp;&nbsp; _PatternWithoutRange_\
617
> &nbsp;&nbsp; | [_RangePattern_]
718
>
@@ -756,6 +767,57 @@ Path patterns are irrefutable when they refer to structs or an enum variant when
756767
has only one variant or a constant whose type is irrefutable. They are refutable when they
757768
refer to refutable constants or enum variants for enums with multiple variants.
758769

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+
759821
[_GroupedPattern_]: #grouped-patterns
760822
[_IdentifierPattern_]: #identifier-patterns
761823
[_LiteralPattern_]: #literal-patterns

0 commit comments

Comments
 (0)