Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/expressions/closure-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
> &nbsp;&nbsp; _ClosureParam_ (`,` _ClosureParam_)<sup>\*</sup> `,`<sup>?</sup>
>
> _ClosureParam_ :\
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> [_Pattern_]&nbsp;( `:` [_Type_] )<sup>?</sup>
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> [_PatternNoTopAlt_]&nbsp;( `:` [_Type_] )<sup>?</sup>
A _closure expression_, also know as a lambda expression or a lambda, defines a
closure and denotes it as a value, in a single expression. A closure expression
Expand Down
2 changes: 1 addition & 1 deletion src/items/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
> )
>
> _FunctionParamPattern_ :\
> &nbsp;&nbsp; [_Pattern_] `:` ( [_Type_] | `...` )
> &nbsp;&nbsp; [_PatternNoTopAlt_] `:` ( [_Type_] | `...` )
>
> _FunctionReturnType_ :\
> &nbsp;&nbsp; `->` [_Type_]
Expand Down
56 changes: 56 additions & 0 deletions src/patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@

> **<sup>Syntax</sup>**\
> _Pattern_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; `|`<sup>?</sup> _PatternNoTopAlt_ `|` _PatternNoTopAlt_
> &nbsp;&nbsp; | _PatternNoTopAlt_
>
> _PatternNoTopAlt_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; _PatternWithoutRange_\
> &nbsp;&nbsp; | [_RangePattern_]
> &nbsp;&nbsp; | `(` _Pattern_ `)`
>
> _PatternWithoutRange_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; [_LiteralPattern_]\
Expand Down Expand Up @@ -756,6 +761,57 @@ Path patterns are irrefutable when they refer to structs or an enum variant when
has only one variant or a constant whose type is irrefutable. They are refutable when they
refer to refutable constants or enum variants for enums with multiple variants.

## Or-patterns

_Or-patterns_ are patterns that match on either of two sub-patterns (e.g. `A |
B`). They can nest arbitrarily. Syntactically, or-patterns are allowed in any
of the places where other patterns are allowed (represented by the _Pattern_
production), with the exceptions of function and closure arguments (represented
by the _PatternNoTopAlt_ production). Additionally, the macro `:pat` matchers
only match or-patterns in the 2021+ editions.

### Static semantics

1. Given a pattern `p | q` at some depth for some arbitrary patterns `p` and `q`,
the pattern is considered ill-formed if:

+ the type inferred for `p` does not unify with the type inferred for `q`, or
+ the same set of bindings are not introduced in `p` and `q`, or
+ the type of any two bindings with the same name in `p` and `q` do not unify
with respect to types or binding modes.

[type coercions]: https://doc.rust-lang.org/reference/type-coercions.html

Unification of types is in all instances aforementioned exact and
implicit [type coercions] do not apply.

2. When type checking an expression `match e_s { a_1 => e_1, ... a_n => e_n }`,
for each match arm `a_i` which contains a pattern of form `p_i | q_i`,
the pattern `p_i | q_i` is considered ill formed if,
at the depth `d` where it exists the fragment of `e_s` at depth `d`,
the type of the expression fragment does not unify with `p_i | q_i`.

3. With respect to exhaustiveness checking, a pattern `p | q` is
considered to cover `p` as well as `q`. For some constructor `c(x, ..)`
the distributive law applies such that `c(p | q, ..rest)` covers the same
set of value as `c(p, ..rest) | c(q, ..rest)` does. This can be applied
recursively until there are no more nested patterns of form `p | q` other
than those that exist at the top level.

Note that by *"constructor"* we do not refer to tuple struct patterns,
but rather we refer to a pattern for any product type.
This includes enum variants, tuple structs, structs with named fields,
arrays, tuples, and slices.

### Dynamic semantics

1. The dynamic semantics of pattern matching a scrutinee expression `e_s`
against a pattern `c(p | q, ..rest)` at depth `d` where `c` is some constructor,
`p` and `q` are arbitrary patterns, and `rest` is optionally any remaining
potential factors in `c`, is defined as being the same as that of
`c(p, ..rest) | c(q, ..rest)`.


[_GroupedPattern_]: #grouped-patterns
[_IdentifierPattern_]: #identifier-patterns
[_LiteralPattern_]: #literal-patterns
Expand Down
2 changes: 1 addition & 1 deletion src/statements.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ fn outer() {

> **<sup>Syntax</sup>**\
> _LetStatement_ :\
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> `let` [_Pattern_]
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> `let` [_PatternNoTopAlt_]
> ( `:` [_Type_] )<sup>?</sup> (`=` [_Expression_] )<sup>?</sup> `;`

A *`let` statement* introduces a new set of [variables], given by an
Expand Down