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
Copy file name to clipboardExpand all lines: src/destructors.md
+30-83Lines changed: 30 additions & 83 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,11 +2,7 @@ r[destructors]
2
2
# Destructors
3
3
4
4
r[destructors.intro]
5
-
When an [initialized] [variable] or [temporary] goes out of
6
-
[scope](#drop-scopes), its *destructor* is run or it is *dropped*. [Assignment]
7
-
also runs the destructor of its left-hand operand, if it's initialized. If a
8
-
variable has been partially initialized, only its initialized fields are
9
-
dropped.
5
+
When an [initialized] [variable] or [temporary] goes out of [scope](#drop-scopes), its *destructor* is run or it is *dropped*. [Assignment] also runs the destructor of its left-hand operand, if it's initialized. If a variable has been partially initialized, only its initialized fields are dropped.
10
6
11
7
r[destructors.operation]
12
8
The destructor of a type `T` consists of:
@@ -16,16 +12,13 @@ The destructor of a type `T` consists of:
16
12
* The fields of a [struct] are dropped in declaration order.
17
13
* The fields of the active [enum variant] are dropped in declaration order.
18
14
* The fields of a [tuple] are dropped in order.
19
-
* The elements of an [array] or owned [slice] are dropped from the
20
-
first element to the last.
21
-
* The variables that a [closure] captures by move are dropped in an
22
-
unspecified order.
15
+
* The elements of an [array] or owned [slice] are dropped from the first element to the last.
16
+
* The variables that a [closure] captures by move are dropped in an unspecified order.
23
17
*[Trait objects] run the destructor of the underlying type.
24
18
* Other types don't result in any further drops.
25
19
26
20
r[destructors.drop_in_place]
27
-
If a destructor must be run manually, such as when implementing your own smart
28
-
pointer, [`core::ptr::drop_in_place`] can be used.
21
+
If a destructor must be run manually, such as when implementing your own smart pointer, [`core::ptr::drop_in_place`] can be used.
29
22
30
23
Some examples:
31
24
@@ -63,18 +56,13 @@ r[destructors.scope]
63
56
## Drop scopes
64
57
65
58
r[destructors.scope.intro]
66
-
Each variable or temporary is associated to a *drop scope*. When control flow
67
-
leaves a drop scope all variables associated to that scope are dropped in
68
-
reverse order of declaration (for variables) or creation (for temporaries).
59
+
Each variable or temporary is associated to a *drop scope*. When control flow leaves a drop scope all variables associated to that scope are dropped in reverse order of declaration (for variables) or creation (for temporaries).
69
60
70
61
r[destructors.scope.desugaring]
71
-
Drop scopes can be determined by replacing [`for`], [`if`], and [`while`]
72
-
expressions with equivalent expressions using [`match`], [`loop`] and
73
-
`break`.
62
+
Drop scopes can be determined by replacing [`for`], [`if`], and [`while`] expressions with equivalent expressions using [`match`], [`loop`] and `break`.
74
63
75
64
r[destructors.scope.operators]
76
-
Overloaded operators are not distinguished from built-in operators and [binding
77
-
modes] are not considered.
65
+
Overloaded operators are not distinguished from built-in operators and [binding modes] are not considered.
78
66
79
67
r[destructors.scope.list]
80
68
Given a function, or closure, there are drop scopes for:
* In the case of a [block expression], the scope for the block and the
94
-
expression are the same scope.
81
+
* In the case of a [block expression], the scope for the block and the expression are the same scope.
95
82
96
83
r[destructors.scope.match-arm]
97
84
* Each arm of a `match` expression
98
85
99
86
r[destructors.scope.nesting]
100
-
Drop scopes are nested within one another as follows. When multiple scopes are
101
-
left at once, such as when returning from a function, variables are dropped
102
-
from the inside outwards.
87
+
Drop scopes are nested within one another as follows. When multiple scopes are left at once, such as when returning from a function, variables are dropped from the inside outwards.
103
88
104
89
r[destructors.scope.nesting.function]
105
90
* The entire function scope is the outer most scope.
* The function body block is contained within the scope of the entire function.
109
94
110
95
r[destructors.scope.nesting.expr-statement]
111
-
* The parent of the expression in an expression statement is the scope of the
112
-
statement.
96
+
* The parent of the expression in an expression statement is the scope of the statement.
113
97
114
98
r[destructors.scope.nesting.let-initializer]
115
-
* The parent of the initializer of a [`let` statement] is the `let` statement's
116
-
scope.
99
+
* The parent of the initializer of a [`let` statement] is the `let` statement's scope.
117
100
118
101
r[destructors.scope.nesting.statement]
119
-
* The parent of a statement scope is the scope of the block that contains the
120
-
statement.
102
+
* The parent of a statement scope is the scope of the block that contains the statement.
121
103
122
104
r[destructors.scope.nesting.match-guard]
123
-
* The parent of the expression for a `match` guard is the scope of the arm that
124
-
the guard is for.
105
+
* The parent of the expression for a `match` guard is the scope of the arm that the guard is for.
125
106
126
107
r[destructors.scope.nesting.match-arm]
127
-
* The parent of the expression after the `=>` in a `match` expression is the
128
-
scope of the arm that it's in.
108
+
* The parent of the expression after the `=>` in a `match` expression is the scope of the arm that it's in.
129
109
130
110
r[destructors.scope.nesting.match]
131
-
* The parent of the arm scope is the scope of the `match` expression that it
132
-
belongs to.
111
+
* The parent of the arm scope is the scope of the `match` expression that it belongs to.
133
112
134
113
r[destructors.scope.nesting.other]
135
-
* The parent of all other scopes is the scope of the immediately enclosing
136
-
expression.
114
+
* The parent of all other scopes is the scope of the immediately enclosing expression.
137
115
138
116
r[destructors.scope.params]
139
117
### Scopes of function parameters
140
118
141
-
All function parameters are in the scope of the entire function body, so are
142
-
dropped last when evaluating the function. Each actual function parameter is
143
-
dropped after any bindings introduced in that parameter's pattern.
119
+
All function parameters are in the scope of the entire function body, so are dropped last when evaluating the function. Each actual function parameter is dropped after any bindings introduced in that parameter's pattern.
Local variables declared in a `let` statement are associated to the scope of
170
-
the block that contains the `let` statement. Local variables declared in a
171
-
`match` expression are associated to the arm scope of the `match` arm that they
172
-
are declared in.
145
+
Local variables declared in a `let` statement are associated to the scope of the block that contains the `let` statement. Local variables declared in a `match` expression are associated to the arm scope of the `match` arm that they are declared in.
The *temporary scope* of an expression is the scope that is used for the
247
-
temporary variable that holds the result of that expression when used in a
248
-
[place context], unless it is [promoted].
219
+
The *temporary scope* of an expression is the scope that is used for the temporary variable that holds the result of that expression when used in a [place context], unless it is [promoted].
249
220
250
221
r[destructors.scope.temporary.enclosing]
251
-
Apart from lifetime extension, the temporary scope of an expression is the
252
-
smallest scope that contains the expression and is one of the following:
222
+
Apart from lifetime extension, the temporary scope of an expression is the smallest scope that contains the expression and is one of the following:
253
223
254
224
* The entire function.
255
225
* A statement.
256
226
* The body of an [`if`], [`while`] or [`loop`] expression.
257
227
* The `else` block of an `if` expression.
258
-
* The non-pattern matching condition expression of an `if` or `while` expression,
259
-
or a `match` guard.
228
+
* The non-pattern matching condition expression of an `if` or `while` expression, or a `match` guard.
260
229
* The body expression for a match arm.
261
230
* Each operand of a [lazy boolean expression].
262
231
* The pattern-matching condition(s) and consequent body of [`if`] ([destructors.scope.temporary.edition2024]).
@@ -329,11 +298,7 @@ match PrintOnDrop("Matched value in final expression") {
329
298
r[destructors.scope.operands]
330
299
### Operands
331
300
332
-
Temporaries are also created to hold the result of operands to an expression
333
-
while the other operands are evaluated. The temporaries are associated to the
334
-
scope of the expression with that operand. Since the temporaries are moved from
335
-
once the expression is evaluated, dropping them has no effect unless one of the
336
-
operands to an expression breaks out of the expression, returns, or [panics][panic].
301
+
Temporaries are also created to hold the result of operands to an expression while the other operands are evaluated. The temporaries are associated to the scope of the expression with that operand. Since the temporaries are moved from once the expression is evaluated, dropping them has no effect unless one of the operands to an expression breaks out of the expression, returns, or [panics][panic].
337
302
338
303
```rust
339
304
# structPrintOnDrop(&'staticstr);
@@ -360,14 +325,7 @@ loop {
360
325
r[destructors.scope.const-promotion]
361
326
### Constant promotion
362
327
363
-
Promotion of a value expression to a `'static` slot occurs when the expression
364
-
could be written in a constant and borrowed, and that borrow could be dereferenced
365
-
where
366
-
the expression was originally written, without changing the runtime behavior.
367
-
That is, the promoted expression can be evaluated at compile-time and the
368
-
resulting value does not contain [interior mutability] or [destructors] (these
369
-
properties are determined based on the value where possible, e.g. `&None`
370
-
always has the type `&'static Option<_>`, as it contains nothing disallowed).
328
+
Promotion of a value expression to a `'static` slot occurs when the expression could be written in a constant and borrowed, and that borrow could be dereferenced where the expression was originally written, without changing the runtime behavior. That is, the promoted expression can be evaluated at compile-time and the resulting value does not contain [interior mutability] or [destructors] (these properties are determined based on the value where possible, e.g. `&None` always has the type `&'static Option<_>`, as it contains nothing disallowed).
> The exact rules for temporary lifetime extension are subject to change. This is describing the current behavior only.
377
335
378
336
r[destructors.scope.lifetime-extension.let]
379
-
The temporary scopes for expressions in `let` statements are sometimes
380
-
*extended* to the scope of the block containing the `let` statement. This is
381
-
done when the usual temporary scope would be too small, based on certain
382
-
syntactic rules. For example:
337
+
The temporary scopes for expressions in `let` statements are sometimes *extended* to the scope of the block containing the `let` statement. This is done when the usual temporary scope would be too small, based on certain syntactic rules. For example:
383
338
384
339
```rust
385
340
letx=&mut0;
@@ -389,8 +344,7 @@ println!("{}", x);
389
344
```
390
345
391
346
r[destructors.scope.lifetime-extension.static]
392
-
Lifetime extension also applies to `static` and `const` items, where it
393
-
makes temporaries live until the end of the program. For example:
347
+
Lifetime extension also applies to `static` and `const` items, where it makes temporaries live until the end of the program. For example:
394
348
395
349
```rust
396
350
constC:&Vec<i32> =&Vec::new();
@@ -444,8 +398,7 @@ An *extending pattern* is either:
444
398
So `ref x`, `V(ref x)` and `[ref x, y]` are all extending patterns, but `x`, `&ref x` and `&(ref x,)` are not.
For a let statement with an initializer, an *extending expression* is an
478
-
expression which is one of the following:
430
+
For a let statement with an initializer, an *extending expression* is an expression which is one of the following:
479
431
480
432
* The initializer expression.
481
433
* The operand of an extending [borrow] expression.
482
434
* The [super operands] of an extending [super macro call] expression.
483
-
* The operand(s) of an extending [array][array expression], [cast][cast
484
-
expression], [braced struct][struct expression], or [tuple][tuple expression]
485
-
expression.
435
+
* The operand(s) of an extending [array][array expression], [cast][cast expression], [braced struct][struct expression], or [tuple][tuple expression] expression.
486
436
* The arguments to an extending [tuple struct] or [tuple enum variant] constructor expression.
487
437
* The final expression of an extending [block expression] except for an [async block expression].
488
438
* The final expression of an extending [`if`] expression's consequent, `else if`, or `else` block.
@@ -491,8 +441,7 @@ expression which is one of the following:
491
441
> [!NOTE]
492
442
> The desugaring of a [destructuring assignment] makes its assigned value operand (the RHS) an extending expression within a newly-introduced block. For details, see [expr.assign.destructure.tmp-ext].
493
443
494
-
So the borrow expressions in `&mut 0`, `(&1, &mut 2)`, and `Some(&mut 3)`
495
-
are all extending expressions. The borrows in `&0 + &1` and `f(&mut 0)` are not.
444
+
So the borrow expressions in `&mut 0`, `(&1, &mut 2)`, and `Some(&mut 3)` are all extending expressions. The borrows in `&0 + &1` and `f(&mut 0)` are not.
The operand of an extending [borrow] expression has its [temporary scope][extended].
@@ -628,9 +577,7 @@ r[destructors.forget]
628
577
r[destructors.manually-suppressing]
629
578
### Manually suppressing destructors
630
579
631
-
[`core::mem::forget`] can be used to prevent the destructor of a variable from being run,
632
-
and [`core::mem::ManuallyDrop`] provides a wrapper to prevent a
633
-
variable or field from being dropped automatically.
580
+
[`core::mem::forget`] can be used to prevent the destructor of a variable from being run, and [`core::mem::ManuallyDrop`] provides a wrapper to prevent a variable or field from being dropped automatically.
634
581
635
582
> [!NOTE]
636
583
> Preventing a destructor from being run via [`core::mem::forget`] or other means is safe even if it has a type that isn't `'static`. Besides the places where destructors are guaranteed to run as defined by this document, types may *not* safely rely on a destructor being run for soundness.
Copy file name to clipboardExpand all lines: src/dynamically-sized-types.md
+4-11Lines changed: 4 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,26 +8,19 @@ r[dynamic-sized.restriction]
8
8
Such types can only be used in certain cases:
9
9
10
10
r[dynamic-sized.pointer-types]
11
-
*[Pointer types] to <abbrtitle="dynamically sized types">DSTs</abbr> are
12
-
sized but have twice the size of pointers to sized types
11
+
*[Pointer types] to <abbrtitle="dynamically sized types">DSTs</abbr> are sized but have twice the size of pointers to sized types
13
12
* Pointers to slices and `str` also store the number of elements.
14
13
* Pointers to trait objects also store a pointer to a vtable.
15
14
16
15
r[dynamic-sized.question-sized]
17
-
* <abbrtitle="dynamically sized types">DSTs</abbr> can be provided as
18
-
type arguments to generic type parameters having the special `?Sized` bound.
19
-
They can also be used for associated type definitions when the corresponding associated type declaration has a `?Sized` bound.
20
-
By default, any type parameter or associated type has a `Sized` bound, unless it is relaxed using `?Sized`.
16
+
* <abbrtitle="dynamically sized types">DSTs</abbr> can be provided as type arguments to generic type parameters having the special `?Sized` bound. They can also be used for associated type definitions when the corresponding associated type declaration has a `?Sized` bound. By default, any type parameter or associated type has a `Sized` bound, unless it is relaxed using `?Sized`.
21
17
22
18
r[dynamic-sized.trait-impl]
23
19
* Traits may be implemented for <abbr title="dynamically sized
24
-
types">DSTs</abbr>.
25
-
Unlike with generic type parameters, `Self: ?Sized` is the default in trait definitions.
20
+
types">DSTs</abbr>. Unlike with generic type parameters, `Self: ?Sized` is the default in trait definitions.
26
21
27
22
r[dynamic-sized.struct-field]
28
-
* Structs may contain a <abbrtitle="dynamically sized type">DST</abbr> as the
29
-
last field; this makes the struct itself a
30
-
<abbrtitle="dynamically sized type">DST</abbr>.
23
+
* Structs may contain a <abbrtitle="dynamically sized type">DST</abbr> as the last field; this makes the struct itself a <abbrtitle="dynamically sized type">DST</abbr>.
31
24
32
25
> [!NOTE]
33
26
> [Variables], function parameters, [const] items, and [static] items must be `Sized`.
0 commit comments