diff --git a/src/expressions/if-expr.md b/src/expressions/if-expr.md
index 25d3e5aec..5501dc86f 100644
--- a/src/expressions/if-expr.md
+++ b/src/expressions/if-expr.md
@@ -44,7 +44,7 @@ assert_eq!(y, "Bigger");
> **Syntax**\
> _IfLetExpression_ :\
-> `if` `let` [_Pattern_] `=` [_Expression_]_except struct or lazy boolean operator expression_
+> `if` `let` [_MatchArmPatterns_] `=` [_Expression_]_except struct or lazy boolean operator expression_
> [_BlockExpression_]\
> (`else` (
> [_BlockExpression_]
@@ -95,10 +95,10 @@ let a = if let Some(1) = x {
assert_eq!(a, 3);
```
-An `if let` expression is equivalent to a `match` expression as follows:
+An `if let` expression is equivalent to a [`match` expression] as follows:
```rust,ignore
-if let PAT = EXPR {
+if let PATS = EXPR {
/* body */
} else {
/*else */
@@ -109,11 +109,26 @@ is equivalent to
```rust,ignore
match EXPR {
- PAT => { /* body */ },
+ PATS => { /* body */ },
_ => { /* else */ }, // () if there is no else
}
```
+Multiple patterns may be specified with the `|` operator. This has the same semantics
+as with `|` in `match` expressions:
+
+```rust
+enum E {
+ X(u8),
+ Y(u8),
+ Z(u8),
+}
+let v = E::Y(12);
+if let E::X(n) | E::Y(n) = v {
+ assert_eq!(n, 12);
+}
+```
+
The expression cannot be a [lazy boolean operator expression][_LazyBooleanOperatorExpression_].
Use of a lazy boolean operator is ambiguous with a planned feature change
of the language (the implementation of if-let chains - see [eRFC 2947][_eRFCIfLetChain_]).
@@ -134,9 +149,10 @@ if let PAT = EXPR || EXPR { .. }
if let PAT = ( EXPR || EXPR ) { .. }
```
-[_Expression_]: expressions.html
[_BlockExpression_]: expressions/block-expr.html
-[_Pattern_]: patterns.html
+[_Expression_]: expressions.html
[_LazyBooleanOperatorExpression_]: expressions/operator-expr.html#lazy-boolean-operators
+[_MatchArmPatterns_]: expressions/match-expr.html
[_eRFCIfLetChain_]: https://github.com/rust-lang/rfcs/blob/master/text/2497-if-let-chains.md#rollout-plan-and-transitioning-to-rust-2018
+[`match` expression]: expressions/match-expr.html
[scrutinee]: glossary.html#scrutinee
diff --git a/src/expressions/loop-expr.md b/src/expressions/loop-expr.md
index 07eacc502..7a2ae1863 100644
--- a/src/expressions/loop-expr.md
+++ b/src/expressions/loop-expr.md
@@ -67,7 +67,7 @@ while i < 10 {
> **Syntax**\
> [_PredicatePatternLoopExpression_] :\
-> `while` `let` [_Pattern_] `=` [_Expression_]except struct expression
+> `while` `let` [_MatchArmPatterns_] `=` [_Expression_]except struct expression
> [_BlockExpression_]
A `while let` loop is semantically similar to a `while` loop but in place of a
@@ -90,11 +90,11 @@ while let _ = 5 {
}
```
-A `while let` loop is equivalent to a `loop` expression containing a `match`
-expression as follows.
+A `while let` loop is equivalent to a `loop` expression containing a [`match`
+expression] as follows.
```rust,ignore
-'label: while let PAT = EXPR {
+'label: while let PATS = EXPR {
/* loop body */
}
```
@@ -104,12 +104,23 @@ is equivalent to
```rust,ignore
'label: loop {
match EXPR {
- PAT => { /* loop body */ },
+ PATS => { /* loop body */ },
_ => break,
}
}
```
+Multiple patterns may be specified with the `|` operator. This has the same semantics
+as with `|` in `match` expressions:
+
+```rust
+let mut vals = vec![2, 3, 1, 2, 2];
+while let Some(v @ 1) | Some(v @ 2) = vals.pop() {
+ // Prints 2, 2, then 1
+ println!("{}", v);
+}
+```
+
## Iterator loops
> **Syntax**\
@@ -272,12 +283,11 @@ and the `loop` must have a type compatible with each `break` expression.
expression `()`.
[IDENTIFIER]: identifiers.html
-[temporary values]: expressions.html#temporary-lifetimes
-
-[_Expression_]: expressions.html
+[LIFETIME_OR_LABEL]: tokens.html#lifetimes-and-loop-labels
[_BlockExpression_]: expressions/block-expr.html
+[_Expression_]: expressions.html
+[_MatchArmPatterns_]: expressions/match-expr.html
[_Pattern_]: patterns.html
-
-[LIFETIME_OR_LABEL]: tokens.html#lifetimes-and-loop-labels
-
+[`match` expression]: expressions/match-expr.html
[scrutinee]: glossary.html#scrutinee
+[temporary values]: expressions.html#temporary-lifetimes
diff --git a/src/expressions/match-expr.md b/src/expressions/match-expr.md
index 3dd85e2f1..d032a3fcc 100644
--- a/src/expressions/match-expr.md
+++ b/src/expressions/match-expr.md
@@ -62,7 +62,8 @@ match x {
Variables bound within the pattern are scoped to the match guard and the arm's
expression. The [binding mode] (move, copy, or reference) depends on the pattern.
-Multiple match patterns may be joined with the `|` operator:
+Multiple match patterns may be joined with the `|` operator. Each pattern will be
+tested in left-to-right sequence until a successful match is found.
```rust
# let x = 9;
@@ -73,11 +74,22 @@ let message = match x {
};
assert_eq!(message, "a few");
+
+// Demonstration of pattern match order.
+struct S(i32, i32);
+
+match S(1, 2) {
+ S(z @ 1, _) | S(_, z @ 2) => assert_eq!(z, 1),
+ _ => panic!(),
+}
```
-Please notice that the `2..=9` is a [Range Pattern], not a [Range Expression]
-and, thus, only those types of ranges supported by range patterns can be used
-in match arms.
+> Note: The `2..=9` is a [Range Pattern], not a [Range Expression]. Thus, only
+> those types of ranges supported by range patterns can be used in match arms.
+
+Every binding in each `|` separated pattern must appear in all of the patterns
+in the arm. Every binding of the same name must have the same type, and have
+the same binding mode.
Match arms can accept _match guards_ to further refine the
criteria for matching a case. Pattern guards appear after the pattern and
@@ -85,7 +97,7 @@ consist of a bool-typed expression following the `if` keyword. A pattern guard
may refer to the variables bound within the pattern they follow.
When the pattern matches successfully, the pattern guard expression is executed.
-If the expression is truthy, the pattern is successfully matched against.
+If the expression evaluates to true, the pattern is successfully matched against.
Otherwise, the next pattern, including other matches with the `|` operator in
the same arm, is tested.
@@ -104,15 +116,13 @@ let message = match maybe_digit {
> and side effects it has to execute multiple times. For example:
>
> ```rust
-> use std::cell::Cell;
-> fn main() {
-> let i : Cell = Cell::new(0);
-> match 1 {
-> 1 | _ if { i.set(i.get() + 1); false } => {}
-> _ => {}
-> }
-> assert_eq!(i.get(), 2);
+> # use std::cell::Cell;
+> let i : Cell = Cell::new(0);
+> match 1 {
+> 1 | _ if { i.set(i.get() + 1); false } => {}
+> _ => {}
> }
+> assert_eq!(i.get(), 2);
> ```
## Attributes on match arms