Skip to content

Commit 0eef542

Browse files
committed
fixed few reviews
1 parent e704b43 commit 0eef542

File tree

1 file changed

+30
-12
lines changed

1 file changed

+30
-12
lines changed

src/expressions/match-expr.md

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,36 @@ MatchExpression ->
99
MatchArms?
1010
`}`
1111
12-
Scrutinee -> Expression _except [StructExpression]_
12+
Scrutinee ->
13+
Expression _except_ [StructExpression]
1314
1415
MatchArms ->
1516
( MatchArm `=>` ( ExpressionWithoutBlock `,` | ExpressionWithBlock `,`? ) )*
1617
MatchArm `=>` Expression `,`?
1718
18-
MatchArm -> OuterAttribute* Pattern MatchArmGuard?
19-
20-
MatchArmGuard -> `if` Expression
21-
| `if` `let` Pattern Expression
19+
MatchArm ->
20+
OuterAttribute* Pattern MatchArmGuard?
21+
22+
MatchArmGuard ->
23+
`if` Expression
24+
| `if` LetChain
25+
26+
LetChain ->
27+
LetChainCondition ( `&&` LetChainCondition )*
28+
29+
LetChainCondition ->
30+
Expression _except_ [ExcludedConditions]
31+
| OuterAttribute* `let` Pattern `=` Expression _except_ [ExcludedConditions]
32+
33+
ExcludedConditions ->
34+
IfExpression
35+
| MatchExpression
36+
| WhileExpression
37+
| ForExpression
38+
| LoopExpression
39+
| AsyncExpression
40+
| TryExpression
41+
| AwaitExpression
2242
```
2343
<!-- TODO: The exception above isn't accurate, see https://github.com/rust-lang/reference/issues/569 -->
2444

@@ -153,7 +173,7 @@ Moreover, by holding a shared reference while evaluating the guard, mutation ins
153173
154174
r[expr.match.if.let.guard]
155175
## If Let Guards
156-
Match arms can include `if let` guards to allow conditional pattern matching within the guard clause. This feature is currently unstable and requires the attribute. It is tracked in issue [#51114](https://github.com/rust-lang/rust/issues/51114).
176+
Match arms can include `if let` guards to allow conditional pattern matching within the guard clause.
157177
158178
r[expr.match.if.let.guard.syntax]
159179
```rust,ignore
@@ -162,11 +182,11 @@ match expression {
162182
...
163183
}
164184
```
165-
Here, `guard_expr` is evaluated and matched against `subpattern`. If the match succeeds, the guard evaluates to `true` and the arm is selected. Otherwise, pattern matching continues to the next arm.
185+
Here, `guard_expr` is evaluated and matched against `subpattern`. If the `if let` expression in the guard matches successfully and the arm’s body is executed. Otherwise, pattern matching continues to the next arm.
166186

167187
r[expr.match.if.let.guard.behavior]
168188
When the pattern matches successfully, the `if let` expression in the guard is evaluated:
169-
* If the inner pattern (`subpattern`) matches the result of `guard_expr`, the guard evaluates to `true`.
189+
* The guard proceeds if the inner pattern (`subpattern`) matches the result of `guard_expr`.
170190
* Otherwise, the next arm is tested.
171191

172192
```rust,ignore
@@ -176,7 +196,6 @@ let msg = match value {
176196
Some(x) if let Some(y) = Some(x - 1) => format!("Matched inner value: {}", y),
177197
_ => "No match".to_string(),
178198
};
179-
180199
```
181200

182201
r[expr.match.if.let.guard.scope]
@@ -225,14 +244,13 @@ Before a guard (including an `if let` guard) is evaluated:
225244
Some(v) if let Some(_) = take(v) => "ok", // ERROR: cannot move out of `v`
226245
_ => "nope",
227246
};
228-
229247
```
230248
In the above example, `v` is already bound in the outer pattern, and the guard attempts to move it --- this is not allowed. You can fix it by cloning or borrowing:
231249
```rust,ignore
232250
Some(v) if let Some(_) = take(v.clone()) => "ok",
233251
```
234252
> [!NOTE]
235-
> Unlike regular if guards, `if let` guards execute only once per match arm, even if the pattern uses the `|` operator to match multiple patterns. This avoids repeated evaluation and potential side effects.
253+
> Multiple matches using the `|` operator can cause the pattern guard and the side effects it has to execute multiple times. For example:
236254
> ```rust,ignore
237255
> use std::cell::Cell;
238256
>
@@ -241,7 +259,7 @@ Before a guard (including an `if let` guard) is evaluated:
241259
> 1 | _ if let Some(_) = { i.set(i.get() + 1); Some(1) } => {}
242260
> _ => {}
243261
> }
244-
> assert_eq!(i.get(), 1); // Guard not executed twice
262+
> assert_eq!(i.get(), 2); // Guard is executed twice
245263
> ```
246264
247265
r[expr.match.attributes]

0 commit comments

Comments
 (0)