@@ -10,8 +10,9 @@ The destructor of a type `T` consists of:
10
10
11
11
1 . If ` T: Drop ` , calling [ ` <T as std::ops::Drop>::drop ` ]
12
12
2 . Recursively running the destructor of all of its fields.
13
- * The fields of a [ struct] or [ tuple ] are dropped in declaration order.
13
+ * The fields of a [ struct] are dropped in declaration order.
14
14
* The fields of the active [ enum variant] are dropped in declaration order.
15
+ * The fields of a [ tuple] are dropped in order.
15
16
* The elements of an [ array] or owned [ slice] are dropped from the
16
17
first element to the last.
17
18
* The variables that a [ closure] captures by move are dropped in an
@@ -71,7 +72,8 @@ Given a function, or closure, there are drop scopes for:
71
72
* Each [ statement]
72
73
* Each [ expression]
73
74
* Each block, including the function body
74
- * [ Block expressions] the expression and block scopes are the same scope.
75
+ * In the case of a [ block expression] , the scope for the block and the
76
+ expression are the same scope.
75
77
* Each arm of a ` match ` expression
76
78
77
79
Drop scopes are nested within one another as follows. When multiple scopes are
@@ -82,13 +84,14 @@ from the inside outwards.
82
84
* The function body block is contained within the scope of the entire function.
83
85
* The parent of the expression in an expression statement is the scope of the
84
86
statement.
85
- * The parent of the initializer of a ` let ` statement is the ` let `
86
- statement's scope.
87
+ * The parent of the initializer of a [ ` let ` statement] is the ` let ` statement's
88
+ scope.
87
89
* The parent of a statement scope is the scope of the block that contains the
88
90
statement.
89
91
* The parent of the expression for a ` match ` guard is the scope of the arm that
90
92
the guard is for.
91
- * The parent of the expression for a given ` match ` arm is that arm's scope.
93
+ * The parent of the expression after the ` => ` in a ` match ` expression is the
94
+ scope of the arm that it's in.
92
95
* The parent of the arm scope is the scope of the ` match ` expression that it
93
96
belongs to.
94
97
* The parent of all other scopes is the scope of the immediately enclosing
@@ -97,8 +100,8 @@ from the inside outwards.
97
100
### Scopes of function parameters
98
101
99
102
All function parameters are in the scope of the entire function body, so are
100
- dropped last when evaluating the function. Actual function parameters are
101
- dropped after any named parameters that are bound to parts of it .
103
+ dropped last when evaluating the function. Each actual function parameter is
104
+ dropped after any bindings introduced in that parameter's pattern .
102
105
103
106
``` rust
104
107
# struct PrintOnDrop (& 'static str );
@@ -124,8 +127,8 @@ patterns_in_parameters(
124
127
125
128
Local variables declared in a ` let ` statement are associated to the scope of
126
129
the block that contains the ` let ` statement. Local variables declared in a
127
- ` match ` expression are associated to the arm scope of the ` match ` arm that they are declared
128
- in.
130
+ ` match ` expression are associated to the arm scope of the ` match ` arm that they
131
+ are declared in.
129
132
130
133
``` rust
131
134
# struct PrintOnDrop (& 'static str );
@@ -141,14 +144,14 @@ let declared_first = PrintOnDrop("Dropped last in outer scope");
141
144
let declared_last = PrintOnDrop (" Dropped first in outer scope" );
142
145
```
143
146
144
- If multiple patterns are used in the same arm for a ` match ` expression, then an unspecified
145
- pattern will be used to determine the drop order.
147
+ If multiple patterns are used in the same arm for a ` match ` expression, then an
148
+ unspecified pattern will be used to determine the drop order.
146
149
147
150
### Temporary scopes
148
151
149
152
The * temporary scope* of an expression is the scope that is used for the
150
153
temporary variable that holds the result of that expression when used in a
151
- [ place context] , unless it is promoted to a ` static ` .
154
+ [ place context] , unless it is [ promoted] .
152
155
153
156
Apart from lifetime extension, the temporary scope of an expression is the
154
157
smallest scope that contains the expression and is for one of the following:
@@ -162,9 +165,16 @@ smallest scope that contains the expression and is for one of the following:
162
165
* The expression for a match arm.
163
166
* The second operand of a [ lazy boolean expression] .
164
167
165
- > Note: Temporaries that are created in the final expression of a function body
166
- > are dropped * after* any named variables bound in the function body, as there
167
- > is no smaller enclosing temporary scope.
168
+ > ** Notes** :
169
+ >
170
+ > Temporaries that are created in the final expression of a function
171
+ > body are dropped * after* any named variables bound in the function body, as
172
+ > there is no smaller enclosing temporary scope.
173
+ >
174
+ > The [ scrutinee] of a ` match ` expression is not a temporary scope, so
175
+ > temporaries in the scrutinee can be dropped after the ` match ` expression. For
176
+ > example, the temporary for ` 1 ` in ` match 1 { ref mut z => z }; ` lives until
177
+ > the end of the statement.
168
178
169
179
Some examples:
170
180
@@ -245,6 +255,9 @@ always has the type `&'static Option<_>`, as it contains nothing disallowed).
245
255
246
256
### Temporary lifetime extension
247
257
258
+ > ** Note** : The exact rules for temporary lifetime extension are subject to
259
+ > change. This is describing the current behavior only.
260
+
248
261
The temporary scopes for expressions in ` let ` statements are sometimes
249
262
* extended* to the scope of the block containing the ` let ` statement. This is
250
263
done when the usual temporary scope would be too small, based on certain
@@ -287,11 +300,11 @@ expression which is one of the following:
287
300
* The operand(s) of an extending [ array] [ array expression ] , [ cast] [ cast
288
301
expression] , [ braced struct] [ struct expression ] , or [ tuple] [ tuple expression ]
289
302
expression.
290
- * The final expression of any extending [ block expression] [ block expressions ] .
303
+ * The final expression of any extending [ block expression] .
291
304
292
305
So the borrow expressions in ` &mut 0 ` , ` (&1, &mut 2) ` , and ` Some { 0: &mut 3 } `
293
- are all extending expressions, while the borrows in ` &0 + &1 ` and
294
- ` Some(&mut 0) ` are not .
306
+ are all extending expressions. The borrows in ` &0 + &1 ` and ` Some(&mut 0) ` are
307
+ not: the latter is syntactically a function call expression .
295
308
296
309
The operand of any extending borrow expression has its temporary scope
297
310
extended.
@@ -345,6 +358,8 @@ variable or field from being dropped automatically.
345
358
[ interior mutability ] : interior-mutability.md
346
359
[ lazy boolean expression ] : expressions/operator-expr.md#lazy-boolean-operators
347
360
[ place context ] : expressions.md#place-expressions-and-value-expressions
361
+ [ promoted ] : destructors.md#constant-promotion
362
+ [ scrutinee ] : glossary.md#scrutinee
348
363
[ statement ] : statements.md
349
364
[ temporary ] : expressions.md#temporaries
350
365
[ variable ] : variables.md
@@ -362,7 +377,7 @@ variable or field from being dropped automatically.
362
377
[ tuple struct pattern ] : patterns.md#tuple-struct-patterns
363
378
364
379
[ array expression ] : expressions/array-expr.md#array-expressions
365
- [ block expressions ] : expressions/block-expr.md
380
+ [ block expression ] : expressions/block-expr.md
366
381
[ borrow expression ] : expressions/operator-expr.md#borrow-operators
367
382
[ cast expression ] : expressions/operator-expr.md#type-cast-expressions
368
383
[ struct expression ] : expressions/struct-expr.md
0 commit comments