Skip to content

Commit f31162e

Browse files
committed
Document if_while_or_patterns
1 parent dafc0ba commit f31162e

File tree

3 files changed

+55
-24
lines changed

3 files changed

+55
-24
lines changed

src/expressions/if-expr.md

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ assert_eq!(y, "Bigger");
4444

4545
> **<sup>Syntax</sup>**\
4646
> _IfLetExpression_ :\
47-
> &nbsp;&nbsp; `if` `let` [_Pattern_] `=` [_Expression_]<sub>_except struct or lazy boolean operator expression_</sub>
47+
> &nbsp;&nbsp; `if` `let` [_Patterns_] `=` [_Expression_]<sub>_except struct or lazy boolean operator expression_</sub>
4848
> [_BlockExpression_]\
4949
> &nbsp;&nbsp; (`else` (
5050
> [_BlockExpression_]
@@ -92,10 +92,10 @@ let a = if let Some(1) = x {
9292
assert_eq!(a, 3);
9393
```
9494

95-
An `if let` expression is equivalent to a `match` expression as follows:
95+
An `if let` expression is equivalent to a [`match` expression] as follows:
9696

9797
```rust,ignore
98-
if let PAT = EXPR {
98+
if let PATS = EXPR {
9999
/* body */
100100
} else {
101101
/*else */
@@ -106,11 +106,26 @@ is equivalent to
106106

107107
```rust,ignore
108108
match EXPR {
109-
PAT => { /* body */ },
109+
PATS => { /* body */ },
110110
_ => { /* else */ }, // () if there is no else
111111
}
112112
```
113113

114+
Multiple patterns may be specified with the `|` operator. This has the same semantics
115+
as with `|` in `match` expressions:
116+
117+
```rust
118+
enum E {
119+
X(u8),
120+
Y(u8),
121+
Z(u8),
122+
}
123+
let v = E::Y(12);
124+
if let E::X(n) | E::Y(n) = v {
125+
assert_eq!(n, 12);
126+
}
127+
```
128+
114129
The expression cannot be a [lazy boolean operator expression][_LazyBooleanOperatorExpression_].
115130
Use of a lazy boolean operator is ambiguous with a planned feature change
116131
of the language (the implementation of if-let chains - see [eRFC 2947][_eRFCIfLetChain_]).
@@ -131,8 +146,9 @@ if let PAT = EXPR || EXPR { .. }
131146
if let PAT = ( EXPR || EXPR ) { .. }
132147
```
133148

134-
[_Expression_]: expressions.html
135149
[_BlockExpression_]: expressions/block-expr.html
136-
[_Pattern_]: patterns.html
150+
[_Expression_]: expressions.html
137151
[_LazyBooleanOperatorExpression_]: expressions/operator-expr.html#lazy-boolean-operators
152+
[_Patterns_]: expressions/match-expr.html
138153
[_eRFCIfLetChain_]: https://github.com/rust-lang/rfcs/blob/master/text/2497-if-let-chains.md#rollout-plan-and-transitioning-to-rust-2018
154+
[`match` expression]: expressions/match-expr.html

src/expressions/loop-expr.md

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ while i < 10 {
6767

6868
> **<sup>Syntax</sup>**\
6969
> [_PredicatePatternLoopExpression_] :\
70-
> &nbsp;&nbsp; `while` `let` [_Pattern_] `=` [_Expression_]<sub>except struct expression</sub>
70+
> &nbsp;&nbsp; `while` `let` [_Patterns_] `=` [_Expression_]<sub>except struct expression</sub>
7171
> [_BlockExpression_]
7272
7373
A `while let` loop is semantically similar to a `while` loop but in place of a
@@ -85,11 +85,11 @@ while let Some(y) = x.pop() {
8585
}
8686
```
8787

88-
A `while let` loop is equivalent to a `loop` expression containing a `match`
89-
expression as follows.
88+
A `while let` loop is equivalent to a `loop` expression containing a [`match`
89+
expression] as follows.
9090

9191
```rust,ignore
92-
'label: while let PAT = EXPR {
92+
'label: while let PATS = EXPR {
9393
/* loop body */
9494
}
9595
```
@@ -99,12 +99,23 @@ is equivalent to
9999
```rust,ignore
100100
'label: loop {
101101
match EXPR {
102-
PAT => { /* loop body */ },
102+
PATS => { /* loop body */ },
103103
_ => break,
104104
}
105105
}
106106
```
107107

108+
Multiple patterns may be specified with the `|` operator. This has the same semantics
109+
as with `|` in `match` expressions:
110+
111+
```rust
112+
let mut vals = vec![2, 3, 1, 2, 2];
113+
while let Some(v @ 1) | Some(v @ 2) = vals.pop() {
114+
// Prints 2, 2, then 1
115+
println!("{}", v);
116+
}
117+
```
118+
108119
## Iterator loops
109120

110121
> **<sup>Syntax</sup>**\
@@ -267,12 +278,11 @@ and the `loop` must have a type compatible with each `break` expression.
267278
expression `()`.
268279

269280
[IDENTIFIER]: identifiers.html
270-
[temporary values]: expressions.html#temporary-lifetimes
271-
272-
[_Expression_]: expressions.html
281+
[LIFETIME_OR_LABEL]: tokens.html#lifetimes-and-loop-labels
273282
[_BlockExpression_]: expressions/block-expr.html
283+
[_Expression_]: expressions.html
274284
[_Pattern_]: patterns.html
275-
276-
[LIFETIME_OR_LABEL]: tokens.html#lifetimes-and-loop-labels
277-
285+
[_Patterns_]: expressions/match-expr.html
286+
[`match` expression]: expressions/match-expr.html
278287
[scrutinee]: glossary.html#scrutinee
288+
[temporary values]: expressions.html#temporary-lifetimes

src/expressions/match-expr.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
> &nbsp;&nbsp; _MatchArm_ `=>` ( [_BlockExpression_] | [_Expression_] ) `,`<sup>?</sup>
1616
>
1717
> _MatchArm_ :\
18-
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> _MatchArmPatterns_ _MatchArmGuard_<sup>?</sup>
18+
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> _Patterns_ _MatchArmGuard_<sup>?</sup>
1919
>
20-
> _MatchArmPatterns_ :\
20+
> _Patterns_ :\
2121
> &nbsp;&nbsp; `|`<sup>?</sup> [_Pattern_] ( `|` [_Pattern_] )<sup>\*</sup>
2222
>
2323
> _MatchArmGuard_ :\
@@ -62,7 +62,8 @@ match x {
6262
Variables bound within the pattern are scoped to the match guard and the arm's
6363
expression. The [binding mode] (move, copy, or reference) depends on the pattern.
6464

65-
Multiple match patterns may be joined with the `|` operator:
65+
Multiple match patterns may be joined with the `|` operator. Each pattern will be
66+
tested in left-to-right sequence until a successful match is found.
6667

6768
```rust
6869
# let x = 9;
@@ -75,17 +76,21 @@ let message = match x {
7576
assert_eq!(message, "a few");
7677
```
7778

78-
Please notice that the `2..=9` is a [Range Pattern], not a [Range Expression]
79-
and, thus, only those types of ranges supported by range patterns can be used
80-
in match arms.
79+
> Note: The `2..=9` is a [Range Pattern], not a [Range Expression] and, thus,
80+
> only those types of ranges supported by range patterns can be used in match
81+
> arms.
82+
83+
Every binding in each `|` separated pattern must appear in all of the patterns
84+
in the arm. Every binding of the same name must have the same type, and have
85+
the same binding mode.
8186

8287
Match arms can accept _match guards_ to further refine the
8388
criteria for matching a case. Pattern guards appear after the pattern and
8489
consist of a bool-typed expression following the `if` keyword. A pattern guard
8590
may refer to the variables bound within the pattern they follow.
8691

8792
When the pattern matches successfully, the pattern guard expression is executed.
88-
If the expression is truthy, the pattern is successfully matched against.
93+
If the expression evaluates to true, the pattern is successfully matched against.
8994
Otherwise, the next pattern, including other matches with the `|` operator in
9095
the same arm, is tested.
9196

0 commit comments

Comments
 (0)