Skip to content

Commit 1694750

Browse files
committed
Revise text on built-in macro lifetime extension
In particular, let's break apart the items for `pin!` and `format_args!` so we can be specific about which argument positions are extending expressions. Let's drop the section that talks about these macros creating temporaries. They do, but that's an internal detail. The important part as it pertains to this rule is that these argument positions are extending expressions, which means that a borrow in this position is extending, which means that "the operand of any extending borrow expression has its temporary scope extended".
1 parent 64f24fb commit 1694750

File tree

1 file changed

+11
-12
lines changed

1 file changed

+11
-12
lines changed

src/destructors.md

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -487,19 +487,16 @@ expression which is one of the following:
487487
* The final expression of an extending [block expression] except for an [async block expression].
488488
* The final expression of an extending [`if`] expression's consequent, `else if`, or `else` block.
489489
* An arm expression of an extending [`match`] expression.
490-
* The argument(s) to an extending [`pin!`] or [`format_args!`] [macro invocation] expression.
490+
* The argument to an extending [`pin!`] [macro invocation] expression.
491+
* Any arguments following the format string to the [`format_args!`] [macro invocation] expression.
491492

492493
So the borrow expressions in `&mut 0`, `(&1, &mut 2)`, and `Some(&mut 3)`
493494
are all extending expressions. The borrows in `&0 + &1` and `f(&mut 0)` are not.
494495

495-
r[destructors.scope.lifetime-extension.exprs.borrow]
496+
r[destructors.scope.lifetime-extension.exprs.borrows]
496497
The operand of any extending borrow expression has its temporary scope
497498
extended.
498499

499-
r[destructors.scope.lifetime-extension.exprs.macros]
500-
The built-in macros [`pin!`] and [`format_args!`] create temporaries.
501-
Any extending [`pin!`] or [`format_args!`] [macro invocation] expression has an extended temporary scope.
502-
503500
> [!NOTE]
504501
> `rustc` does not treat [array repeat operands] of extending [array] expressions as extending expressions. Whether it should is an open question.
505502
>
@@ -510,10 +507,10 @@ Any extending [`pin!`] or [`format_args!`] [macro invocation] expression has an
510507
Here are some examples where expressions have extended temporary scopes:
511508

512509
```rust,edition2024
510+
# use core::pin::pin;
513511
# use core::sync::atomic::{AtomicU64, Ordering::Relaxed};
514-
# use std::pin::pin;
515512
# static X: AtomicU64 = AtomicU64::new(0);
516-
# struct S;
513+
# #[derive(Debug)] struct S;
517514
# impl Drop for S { fn drop(&mut self) { X.fetch_add(1, Relaxed); } }
518515
# const fn temp() -> S { S }
519516
let x = &temp(); // Operand of borrow.
@@ -538,6 +535,9 @@ let x = match () { _ => &temp() }; // `match` arm expression.
538535
# x;
539536
let x = pin!(&temp()); // Argument to `pin!`.
540537
# x;
538+
# // TODO: This needs <https://github.com/rust-lang/rust/pull/145882>.
539+
let x = format_args!("{:?}", &temp()); // Argument to `format_args!`.
540+
# x;
541541
//
542542
// All of the temporaries above are still live here.
543543
# assert_eq!(0, X.load(Relaxed));
@@ -628,7 +628,7 @@ There is one additional case to be aware of: when a panic reaches a [non-unwindi
628628
[initialized]: glossary.md#initialized
629629
[interior mutability]: interior-mutability.md
630630
[lazy boolean expression]: expressions/operator-expr.md#lazy-boolean-operators
631-
[macro invocation]: macros.md#macro-invocation
631+
[macro invocation]: macro.invocation
632632
[non-unwinding ABI boundary]: items/functions.md#unwinding
633633
[panic]: panic.md
634634
[place context]: expressions.md#place-expressions-and-value-expressions
@@ -668,13 +668,12 @@ There is one additional case to be aware of: when a panic reaches a [non-unwindi
668668
[tuple indexing expression]: expressions/tuple-expr.md#tuple-indexing-expressions
669669

670670
[`for`]: expressions/loop-expr.md#iterator-loops
671+
[`format_args!`]: core::format_args
671672
[`if let`]: expressions/if-expr.md#if-let-patterns
672673
[`if`]: expressions/if-expr.md#if-expressions
673674
[`let` statement]: statements.md#let-statements
674675
[`loop`]: expressions/loop-expr.md#infinite-loops
675676
[`match`]: expressions/match-expr.md
677+
[`pin!`]: std::pin::pin
676678
[`while let`]: expressions/loop-expr.md#while-let-patterns
677679
[`while`]: expressions/loop-expr.md#predicate-loops
678-
679-
[`pin!`]: std::pin::pin
680-
[`format_args!`]: core::format_args

0 commit comments

Comments
 (0)