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
Revise text on temporaries and destructuring assignment
Among other things, within the admonitions, let's pull more of the
explanation out of code comments and into the main narrative; let's
break up this one admonition into two admonitions, as there are
separate ideas here; let's add rule identifiers for these admonitions;
and let's reference these admonitions from the relevant places in the
destructors chapter.
Copy file name to clipboardExpand all lines: src/destructors.md
+7Lines changed: 7 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -266,6 +266,9 @@ smallest scope that contains the expression and is one of the following:
266
266
> [!NOTE]
267
267
> The [scrutinee] of a `match` expression is not a temporary scope, so temporaries in the scrutinee can be dropped after the `match` expression. For example, the temporary for `1` in `match 1 { ref mut z => z };` lives until the end of the statement.
268
268
269
+
> [!NOTE]
270
+
> The desugaring of a [destructuring assignment] restricts the temporary scope of its assigned value operand (the RHS). For details, see [expr.assign.destructure.tmp-scopes].
271
+
269
272
r[destructors.scope.temporary.edition2024]
270
273
> [!EDITION-2024]
271
274
> The 2024 edition added two new temporary scope narrowing rules: `if let` temporaries are dropped before the `else` block, and temporaries of tail expressions of blocks are dropped immediately after the tail expression is evaluated.
@@ -485,6 +488,9 @@ expression which is one of the following:
485
488
* The final expression of an extending [`if`] expression's consequent, `else if`, or `else` block.
486
489
* An arm expression of an extending [`match`] expression.
487
490
491
+
> [!NOTE]
492
+
> 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
+
488
494
So the borrow expressions in `&mut 0`, `(&1, &mut 2)`, and `Some(&mut 3)`
489
495
are all extending expressions. The borrows in `&0 + &1` and `f(&mut 0)` are not.
490
496
@@ -640,6 +646,7 @@ There is one additional case to be aware of: when a panic reaches a [non-unwindi
Note that default binding modes do not apply for the desugared expression.
864
864
865
+
r[expr.assign.destructure.tmp-scopes]
865
866
> [!NOTE]
866
-
> Although basic assignment expressions are not [temporary scopes], the desugaring of destructuring assignments restricts the temporary scope of its assigned value operand.
867
-
> For example:
867
+
> The desugaring restricts the [temporary scope] of the assigned value operand (the RHS) of a destructuring assignment.
868
+
>
869
+
> In a basic assignment, the [temporary] is dropped at the end of the enclosing temporary scope. Below, that's the statement. Therefore, the assignment and use is allowed.
868
870
>
869
871
> ```rust
870
872
> # fntemp() {}
871
-
> usestd::convert::identity;
872
-
>
873
+
> fnf<T>(x:T) ->T { x }
873
874
> letx;
874
-
> // In a basic assignment, `temp()` is dropped at the end of the
875
-
> // enclosing temporary scope, so `x` can be assigned and used
> // The temporary scope of `temp()` is extended to the end of the
896
-
> // block in the desugaring, so `x` may be assigned, but it may not
897
-
> // be used.
898
-
> [x] = [&temp()];
909
+
> # letx;
910
+
> [x] = [&temp()]; // OK
899
911
> ```
900
912
>
913
+
> Thisdesugarsto:
914
+
>
915
+
> ```rust
916
+
> # fntemp() {}
917
+
> # letx;
918
+
> { let [_x] = [&temp()]; x=_x; } // OK
919
+
> ```
920
+
>
921
+
> However, ifwetrytouse `x`, even within the same statement, we'll get an error because the [temporary] is dropped at the end of this introduced block.
922
+
>
901
923
> ```rust,compile_fail,E0716
902
924
> # fn temp() {}
903
-
> # usestd::convert::identity;
904
-
> letx;
925
+
> # let x;
905
926
> ([x] = [&temp()], x); // ERROR
906
927
> ```
928
+
>
929
+
> Thisdesugarsto:
930
+
>
931
+
> ```rust,compile_fail,E0716
932
+
> # fntemp() {}
933
+
> # letx;
934
+
> (
935
+
> {
936
+
> let [_x] = [&temp()];
937
+
> x=_x;
938
+
> }, // <-- The temporary is dropped here.
939
+
> x, // ERROR
940
+
> );
941
+
> ```
907
942
908
943
r[expr.compound-assign]
909
944
## Compoundassignmentexpressions
@@ -1054,6 +1089,7 @@ As with normal assignment expressions, compound assignment expressions always pr
0 commit comments