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,49 @@ 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
+
# structPrintOnDrop(&'staticstr);
191
+
# implDropforPrintOnDrop {
192
+
# fndrop(&mutself) {
193
+
# println!("drop({})", self.0);
194
+
# }
195
+
# }
196
+
matchPrintOnDrop("Dropped last in the first arm's scope") {
197
+
// When guard evaluation succeeds, control-flow stays in the arm and
198
+
// values may be moved from the scrutinee into the arm's bindings,
199
+
// causing them to be dropped in the arm's scope.
200
+
xiflety=PrintOnDrop("Dropped second in the first arm's scope")
201
+
&&letz=PrintOnDrop("Dropped first in the first arm's scope") =>
202
+
{
203
+
letdeclared_in_block=PrintOnDrop("Dropped in inner scope");
204
+
// Pattern-matching guards' bindings and temporaries are dropped in
205
+
// reverse order, dropping each guard condition operand's bindings
206
+
// before its temporaries. Lastly, variables bound by the arm's
207
+
// pattern are dropped.
208
+
}
209
+
_=>unreachable!(),
210
+
}
211
+
212
+
matchPrintOnDrop("Dropped in the enclosing temporary scope") {
213
+
// When guard evaluation fails, control-flow leaves the arm scope,
214
+
// causing bindings and temporaries from earlier pattern-matching
215
+
// guard condition operands to be dropped. This occurs before evaluating
216
+
// the next arm's guard or body.
217
+
_iflety=PrintOnDrop("Dropped in the first arm's scope")
218
+
&&false=>unreachable!(),
219
+
// When a guard is executed multiple times due to self-overlapping
220
+
// or-patterns, control-flow leaves the arm scope when the guard fails
221
+
// and re-enters the arm scope before executing the guard again.
222
+
_|_iflety=PrintOnDrop("Dropped in the second arm's scope twice")
223
+
&&false=>unreachable!(),
224
+
_=> {},
225
+
}
226
+
```
227
+
197
228
r[destructors.scope.bindings.patterns]
198
229
Variables in patterns are dropped in reverse order of declaration within the pattern.
199
230
@@ -264,9 +295,8 @@ smallest scope that contains the expression and is one of the following:
264
295
* A statement.
265
296
* The body of an [`if`], [`while`] or [`loop`] expression.
266
297
* 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.
298
+
* The non-pattern matching condition expression of an `if` or `while` expression or a non-pattern-matching `match`[guard condition operand].
299
+
* The pattern-matching guard, if present, and body expression for a `match` arm.
270
300
* Each operand of a [lazy boolean expression].
271
301
* The pattern-matching condition(s) and consequent body of [`if`] ([destructors.scope.temporary.edition2024]).
272
302
* The pattern-matching condition and loop body of [`while`].
@@ -326,8 +356,16 @@ while let x = PrintOnDrop("while let scrutinee").0 {
326
356
// Scrutinee is dropped at the end of the function, before local variables
327
357
// (because this is the tail expression of the function body block).
328
358
matchPrintOnDrop("Matched value in final expression") {
329
-
// Dropped once the condition has been evaluated
359
+
// Non-pattern-matching guards' temporaries are dropped once the
360
+
// condition has been evaluated
330
361
_ifPrintOnDrop("guard condition").0==""=> (),
362
+
// Pattern-matching guards' temporaries are dropped when leaving the
0 commit comments