You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here, `guard_expr` is evaluated and matched against `subpattern`. If the match succeeds, the guard evaluates to `true`and the armis 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.
166
186
167
187
r[expr.match.if.let.guard.behavior]
168
188
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`.
170
190
* Otherwise, the next arm is tested.
171
191
172
192
```rust,ignore
@@ -176,7 +196,6 @@ let msg = match value {
176
196
Some(x) if let Some(y) = Some(x - 1) => format!("Matched inner value: {}", y),
177
197
_ => "No match".to_string(),
178
198
};
179
-
180
199
```
181
200
182
201
r[expr.match.if.let.guard.scope]
@@ -225,14 +244,13 @@ Before a guard (including an `if let` guard) is evaluated:
225
244
Some(v) if let Some(_) = take(v) => "ok", // ERROR: cannot move out of `v`
226
245
_ => "nope",
227
246
};
228
-
229
247
```
230
248
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:
231
249
```rust,ignore
232
250
Some(v) if let Some(_) = take(v.clone()) => "ok",
233
251
```
234
252
> [!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:
236
254
> ```rust,ignore
237
255
> use std::cell::Cell;
238
256
>
@@ -241,7 +259,7 @@ Before a guard (including an `if let` guard) is evaluated:
241
259
> 1 | _ if let Some(_) = { i.set(i.get() + 1); Some(1) } => {}
242
260
> _ => {}
243
261
> }
244
-
> assert_eq!(i.get(), 1); // Guard not executed twice
262
+
> assert_eq!(i.get(), 2); // Guard is executed twice
0 commit comments