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
* The parent of the expression after the `=>` in a `match` expression is the
128
128
scope of the arm that it's in.
129
129
130
-
r[destructors.scope.nesting.match-guard-pattern]
131
-
* The parent of an `if let` guard pattern is the scope of the guard expression.
132
-
133
-
r[destructors.scope.nesting.match-guard-bindings]
134
-
* Variables bound by `if let` guard patterns have their drop scope determined by
135
-
guard success:
136
-
- On guard failure: dropped immediately after guard evaluation
137
-
- On guard success: scope extends to the end of the match arm body
138
-
139
130
r[destructors.scope.nesting.match]
140
131
* The parent of the arm scope is the scope of the `match` expression that it
141
132
belongs to.
@@ -174,11 +165,8 @@ patterns_in_parameters(
174
165
r[destructors.scope.bindings]
175
166
### Scopes of local variables
176
167
177
-
r[destructors.scope.bindings.intro]
178
-
Local variables declared in a `let` statement are associated to the scope of
179
-
the block that contains the `let` statement. Local variables declared in a
180
-
`match` expression are associated to the arm scope of the `match` arm that they
181
-
are declared in.
168
+
r[destructors.scope.bindings.let]
169
+
Local variables declared in a `let` statement are associated to the scope of the block that contains the `let` statement.
182
170
183
171
```rust
184
172
# structPrintOnDrop(&'staticstr);
@@ -194,6 +182,43 @@ let declared_first = PrintOnDrop("Dropped last in outer scope");
194
182
letdeclared_last=PrintOnDrop("Dropped first in outer scope");
195
183
```
196
184
185
+
r[destructors.scope.bindings.match-arm]
186
+
Local variables declared in a `match` expression or pattern-matching `match` guard are associated to the arm scope of the `match` arm that they are declared in.
187
+
188
+
```rust
189
+
# #![allow(irrefutable_let_patterns)]
190
+
matchPrintOnDrop("Dropped last in the first arm's scope") {
191
+
// When guard evaluation succeeds, control-flow stays in the arm and
192
+
// values may be moved from the scrutinee into the arm's bindings,
193
+
// causing them to be dropped in the arm's scope.
194
+
xiflety=PrintOnDrop("Dropped second in the first arm's scope")
195
+
&&letz=PrintOnDrop("Dropped first in the first arm's scope") =>
196
+
{
197
+
letdeclared_in_block=PrintOnDrop("Dropped in inner scope");
198
+
// Pattern-matching guards' bindings and temporaries are dropped in
199
+
// reverse order, dropping each guard condition operand's bindings
200
+
// before its temporaries. Lastly, variables bound by the arm's
201
+
// pattern are dropped.
202
+
}
203
+
_=>unreachable!(),
204
+
}
205
+
206
+
matchPrintOnDrop("Dropped in the enclosing temporary scope") {
207
+
// When guard evaluation fails, control-flow leaves the arm scope,
208
+
// causing bindings and temporaries from earlier pattern-matching
209
+
// guard condition operands to be dropped. This occurs before evaluating
210
+
// the next arm's guard or body.
211
+
_iflety=PrintOnDrop("Dropped in the first arm's scope")
212
+
&&false=>unreachable!(),
213
+
// When a guard is executed multiple times due to self-overlapping
214
+
// or-patterns, control-flow leaves the arm scope when the guard fails
215
+
// and re-enters the arm scope before executing the guard again.
216
+
_|_iflety=PrintOnDrop("Dropped in the second arm's scope twice")
217
+
&&false=>unreachable!(),
218
+
_=> {},
219
+
}
220
+
```
221
+
197
222
r[destructors.scope.bindings.patterns]
198
223
Variables in patterns are dropped in reverse order of declaration within the pattern.
199
224
@@ -264,9 +289,8 @@ smallest scope that contains the expression and is one of the following:
264
289
* A statement.
265
290
* The body of an [`if`], [`while`] or [`loop`] expression.
266
291
* The `else` block of an `if` expression.
267
-
* The condition expression of an `if` or `while` expression.
268
-
* A `match` guard expression, including `if let` guard patterns.
269
-
* The body expression for a match arm.
292
+
* The non-pattern matching condition expression of an `if` or `while` expression or a non-pattern-matching `match` guard condition operand.
293
+
* The pattern-matching guard, if present, and body expression for a `match` arm.
270
294
* Each operand of a [lazy boolean expression].
271
295
* The pattern-matching condition(s) and consequent body of [`if`] ([destructors.scope.temporary.edition2024]).
272
296
* The pattern-matching condition and loop body of [`while`].
@@ -326,8 +350,16 @@ while let x = PrintOnDrop("while let scrutinee").0 {
326
350
// Scrutinee is dropped at the end of the function, before local variables
327
351
// (because this is the tail expression of the function body block).
328
352
matchPrintOnDrop("Matched value in final expression") {
329
-
// Dropped once the condition has been evaluated
353
+
// Non-pattern-matching guards' temporaries are dropped once the
354
+
// condition has been evaluated
330
355
_ifPrintOnDrop("guard condition").0==""=> (),
356
+
// Pattern-matching guards' temporaries are dropped when leaving the
0 commit comments