Skip to content

Commit 141b1af

Browse files
authored
Merge pull request #2141 from ehuss/unwrap-items-expr-other
Unwrap items, expressions, patterns, and types
2 parents 16f73ed + 49115e0 commit 141b1af

63 files changed

Lines changed: 701 additions & 1885 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/destructors.md

Lines changed: 30 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ r[destructors]
22
# Destructors
33

44
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.
106

117
r[destructors.operation]
128
The destructor of a type `T` consists of:
@@ -16,16 +12,13 @@ The destructor of a type `T` consists of:
1612
* The fields of a [struct] are dropped in declaration order.
1713
* The fields of the active [enum variant] are dropped in declaration order.
1814
* 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.
2317
* [Trait objects] run the destructor of the underlying type.
2418
* Other types don't result in any further drops.
2519

2620
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.
2922

3023
Some examples:
3124

@@ -63,18 +56,13 @@ r[destructors.scope]
6356
## Drop scopes
6457

6558
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).
6960

7061
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`.
7463

7564
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.
7866

7967
r[destructors.scope.list]
8068
Given a function, or closure, there are drop scopes for:
@@ -90,16 +78,13 @@ r[destructors.scope.expression]
9078

9179
r[destructors.scope.block]
9280
* Each block, including the function body
93-
* 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.
9582

9683
r[destructors.scope.match-arm]
9784
* Each arm of a `match` expression
9885

9986
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.
10388

10489
r[destructors.scope.nesting.function]
10590
* The entire function scope is the outer most scope.
@@ -108,39 +93,30 @@ r[destructors.scope.nesting.function-body]
10893
* The function body block is contained within the scope of the entire function.
10994

11095
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.
11397

11498
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.
117100

118101
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.
121103

122104
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.
125106

126107
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.
129109

130110
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.
133112

134113
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.
137115

138116
r[destructors.scope.params]
139117
### Scopes of function parameters
140118

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.
144120

145121
```rust
146122
# struct PrintOnDrop(&'static str);
@@ -166,10 +142,7 @@ r[destructors.scope.bindings]
166142
### Scopes of local variables
167143

168144
r[destructors.scope.bindings.intro]
169-
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.
173146

174147
```rust
175148
# struct PrintOnDrop(&'static str);
@@ -243,20 +216,16 @@ r[destructors.scope.temporary]
243216
### Temporary scopes
244217

245218
r[destructors.scope.temporary.intro]
246-
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].
249220

250221
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:
253223

254224
* The entire function.
255225
* A statement.
256226
* The body of an [`if`], [`while`] or [`loop`] expression.
257227
* 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.
260229
* The body expression for a match arm.
261230
* Each operand of a [lazy boolean expression].
262231
* 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") {
329298
r[destructors.scope.operands]
330299
### Operands
331300

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].
337302

338303
```rust
339304
# struct PrintOnDrop(&'static str);
@@ -360,14 +325,7 @@ loop {
360325
r[destructors.scope.const-promotion]
361326
### Constant promotion
362327

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).
371329

372330
r[destructors.scope.lifetime-extension]
373331
### Temporary lifetime extension
@@ -376,10 +334,7 @@ r[destructors.scope.lifetime-extension]
376334
> The exact rules for temporary lifetime extension are subject to change. This is describing the current behavior only.
377335
378336
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:
383338

384339
```rust
385340
let x = &mut 0;
@@ -389,8 +344,7 @@ println!("{}", x);
389344
```
390345

391346
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:
394348

395349
```rust
396350
const C: &Vec<i32> = &Vec::new();
@@ -444,8 +398,7 @@ An *extending pattern* is either:
444398
So `ref x`, `V(ref x)` and `[ref x, y]` are all extending patterns, but `x`, `&ref x` and `&(ref x,)` are not.
445399

446400
r[destructors.scope.lifetime-extension.patterns.let]
447-
If the pattern in a `let` statement is an extending pattern then the temporary
448-
scope of the initializer expression is extended.
401+
If the pattern in a `let` statement is an extending pattern then the temporary scope of the initializer expression is extended.
449402

450403
```rust
451404
# fn temp() {}
@@ -474,15 +427,12 @@ r[destructors.scope.lifetime-extension.exprs]
474427
#### Extending based on expressions
475428

476429
r[destructors.scope.lifetime-extension.exprs.extending]
477-
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:
479431

480432
* The initializer expression.
481433
* The operand of an extending [borrow] expression.
482434
* 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.
486436
* The arguments to an extending [tuple struct] or [tuple enum variant] constructor expression.
487437
* The final expression of an extending [block expression] except for an [async block expression].
488438
* 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:
491441
> [!NOTE]
492442
> 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].
493443
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.
496445

497446
r[destructors.scope.lifetime-extension.exprs.borrows]
498447
The operand of an extending [borrow] expression has its [temporary scope] [extended].
@@ -628,9 +577,7 @@ r[destructors.forget]
628577
r[destructors.manually-suppressing]
629578
### Manually suppressing destructors
630579

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.
634581

635582
> [!NOTE]
636583
> 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.

src/dynamically-sized-types.md

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,19 @@ r[dynamic-sized.restriction]
88
Such types can only be used in certain cases:
99

1010
r[dynamic-sized.pointer-types]
11-
* [Pointer types] to <abbr title="dynamically sized types">DSTs</abbr> are
12-
sized but have twice the size of pointers to sized types
11+
* [Pointer types] to <abbr title="dynamically sized types">DSTs</abbr> are sized but have twice the size of pointers to sized types
1312
* Pointers to slices and `str` also store the number of elements.
1413
* Pointers to trait objects also store a pointer to a vtable.
1514

1615
r[dynamic-sized.question-sized]
17-
* <abbr title="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+
* <abbr title="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`.
2117

2218
r[dynamic-sized.trait-impl]
2319
* 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.
2621

2722
r[dynamic-sized.struct-field]
28-
* Structs may contain a <abbr title="dynamically sized type">DST</abbr> as the
29-
last field; this makes the struct itself a
30-
<abbr title="dynamically sized type">DST</abbr>.
23+
* Structs may contain a <abbr title="dynamically sized type">DST</abbr> as the last field; this makes the struct itself a <abbr title="dynamically sized type">DST</abbr>.
3124

3225
> [!NOTE]
3326
> [Variables], function parameters, [const] items, and [static] items must be `Sized`.

0 commit comments

Comments
 (0)