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
If a [borrow][borrow expression], [dereference][dereference expression],
402
-
[field][field expression], or [tuple indexing expression] has an extended
403
-
temporary scope then so does its operand. If an [indexing expression] has an
404
-
extended temporary scope then the indexed expression also has an extended
405
-
temporary scope.
401
+
If a [borrow], [dereference][dereference expression], [field][field expression], or [tuple indexing expression] has an extended temporary scope then so does its operand. If an [indexing expression] has an extended temporary scope then the indexed expression also has an extended temporary scope.
406
402
407
403
r[destructors.scope.lifetime-extension.patterns]
408
404
#### Extending based on patterns
@@ -474,11 +470,13 @@ let &ref x = &*&temp(); // OK
Copy file name to clipboardExpand all lines: src/expressions.md
+99Lines changed: 99 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -255,6 +255,92 @@ When using a value expression in most place expression contexts, a temporary unn
255
255
The expression evaluates to that location instead, except if [promoted] to a `static`.
256
256
The [drop scope] of the temporary is usually the end of the enclosing statement.
257
257
258
+
r[expr.super-macros]
259
+
### Super macros
260
+
261
+
r[expr.super-macros.intro]
262
+
Certain built-in macros may create [temporaries] whose [scopes][temporary scopes] may be [extended]. These temporaries are *super temporaries* and these macros are *super macros*. [Invocations][macro invocations] of these macros are *super macro call expressions*. Arguments to these macros may be *super operands*.
263
+
264
+
> [!NOTE]
265
+
> When a super macro call expression is an [extending expression], its super operands are [extending expressions] and the [scopes][temporary scopes] of the super temporaries are [extended]. See [destructors.scope.lifetime-extension.exprs].
266
+
267
+
r[expr.super-macros.format_args]
268
+
#### `format_args!`
269
+
270
+
r[expr.super-macros.format_args.super-operands]
271
+
Except for the format string argument, all arguments passed to [`format_args!`] are *super operands*.
272
+
273
+
<!-- FIXME: Remove after https://github.com/rust-lang/rust/pull/145882 lands. -->
274
+
> [!NOTE]
275
+
> When there is only one placeholder, `rustc` does not yet treat the corresponding argument as a super operand. This is a bug.
276
+
>
277
+
> For details, see Rust issue [#145880](https://github.com/rust-lang/rust/issues/145880).
278
+
279
+
<!-- FIXME: Simplify after https://github.com/rust-lang/rust/pull/145882 lands. -->
280
+
```rust,edition2024
281
+
# fn temp() -> String { String::from("") }
282
+
// Due to the call being an extending expression and the argument
283
+
// being a super operand, the inner block is an extending expression,
284
+
// so the scope of the temporary created in its trailing expression
285
+
// is extended.
286
+
let _ = format_args!("{:?}{}", (), { &temp() }); // OK
The super operands of [`format_args!`] are [implicitly borrowed] and are therefore [place expression contexts]. When a [value expression] is passed as an argument, it creates a *super temporary*.
291
+
292
+
<!-- FIXME: Simplify after https://github.com/rust-lang/rust/pull/145882 lands. -->
293
+
```rust
294
+
# fntemp() ->String { String::from("") }
295
+
letx=format_args!("{}{}", temp(), temp());
296
+
x; // <-- The temporaries are extended, allowing use here.
297
+
```
298
+
299
+
The expansion of a call to [`format_args!`] sometimes creates other internal *super temporaries*.
300
+
301
+
```rust,compile_fail,E0716
302
+
let x = {
303
+
// This call creates an internal temporary.
304
+
let x = format_args!("{:?}", 0);
305
+
x // <-- The temporary is extended, allowing its use here.
306
+
}; // <-- The temporary is dropped here.
307
+
x; // ERROR
308
+
```
309
+
310
+
```rust
311
+
// This call doesn't create an internal temporary.
312
+
letx= { letx=format_args!("{}", 0); x };
313
+
x; // OK
314
+
```
315
+
316
+
> [!NOTE]
317
+
> The details of when [`format_args!`] does or does not create internal temporaries are currently unspecified.
318
+
319
+
r[expr.super-macros.pin]
320
+
#### `pin!`
321
+
322
+
r[expr.super-macros.pin.super-operands]
323
+
The argument to [`pin!`] is a *super operand*.
324
+
325
+
```rust,edition2024
326
+
# use core::pin::pin;
327
+
# fn temp() {}
328
+
// As above for `format_args!`.
329
+
let _ = pin!({ &temp() }); // OK
330
+
```
331
+
332
+
r[expr.super-macros.pin.super-temporaries]
333
+
The argument to [`pin!`] is a [value expression context] and creates a *super temporary*.
334
+
335
+
```rust
336
+
# usecore::pin::pin;
337
+
# fntemp() {}
338
+
// The argument is evaluated into a super temporary.
339
+
letx=pin!(temp());
340
+
// The temporary is extended, allowing its use here.
341
+
x; // OK
342
+
```
343
+
258
344
r[expr.implicit-borrow]
259
345
### Implicit Borrows
260
346
@@ -285,6 +371,7 @@ Implicit borrows may be taken in the following expressions:
285
371
* Operand of the [dereference operator][deref] (`*`).
286
372
* Operands of [comparison].
287
373
* Left operands of the [compound assignment].
374
+
* Arguments to [`format_args!`] except the format string.
288
375
289
376
r[expr.overload]
290
377
## Overloading Traits
@@ -311,6 +398,8 @@ They are never allowed before:
0 commit comments