-
Notifications
You must be signed in to change notification settings - Fork 548
specify lifetime extension of pin!
and format_args!
arguments
#1980
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -425,6 +425,7 @@ scope of the initializer expression is extended. | |
r[destructors.scope.lifetime-extension.exprs] | ||
#### Extending based on expressions | ||
|
||
r[destructors.scope.lifetime-extension.exprs.extending] | ||
For a let statement with an initializer, an *extending expression* is an | ||
expression which is one of the following: | ||
|
||
|
@@ -434,29 +435,41 @@ expression which is one of the following: | |
expression], [braced struct][struct expression], or [tuple][tuple expression] | ||
expression. | ||
* The arguments to an extending [tuple struct] or [tuple variant] constructor expression. | ||
* The argument(s) to an extending [`pin!`] or [`format_args!`] [macro invocation] expression. | ||
* The final expression of any extending [block expression]. | ||
|
||
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. | ||
|
||
r[destructors.scope.lifetime-extension.exprs.borrow] | ||
The operand of any extending borrow expression has its temporary scope | ||
extended. | ||
|
||
r[destructors.scope.lifetime-extension.exprs.macros] | ||
The built-in macros [`pin!`] and [`format_args!`] create temporaries. | ||
Any extending [`pin!`] or [`format_args!`] [macro invocation] expression has an extended temporary scope. | ||
Comment on lines
+444
to
+450
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fourth pass: I've broken up I'm doing a bit of conflation here. The "temporaries" here are both:
Let me know if it needs further clarification. My hope is that it's a suitable level of detail for how these macros behave, to avoid specifying their exact expansion. |
||
|
||
#### Examples | ||
|
||
Here are some examples where expressions have extended temporary scopes: | ||
|
||
```rust | ||
# use std::pin::pin; | ||
# fn temp() {} | ||
# trait Use { fn use_temp(&self) -> &Self { self } } | ||
# impl Use for () {} | ||
// The temporary that stores the result of `temp()` lives in the same scope | ||
// as x in these cases. | ||
let x = &temp(); | ||
# x; | ||
let x = &temp() as &dyn Send; | ||
# x; | ||
let x = (&*&temp(),); | ||
# x; | ||
let x = pin!(temp()); | ||
# x; | ||
let x = { [Some(&temp()) ] }; | ||
# x; | ||
let ref x = temp(); | ||
# x; | ||
let ref x = *&temp(); | ||
# x; | ||
``` | ||
|
@@ -471,6 +484,7 @@ Here are some examples where expressions don't have extended temporary scopes: | |
// end of the let statement in these cases. | ||
|
||
let x = std::convert::identity(&temp()); // ERROR | ||
# x; | ||
let x = (&temp()).use_temp(); // ERROR | ||
# x; | ||
``` | ||
|
@@ -506,6 +520,7 @@ There is one additional case to be aware of: when a panic reaches a [non-unwindi | |
[initialized]: glossary.md#initialized | ||
[interior mutability]: interior-mutability.md | ||
[lazy boolean expression]: expressions/operator-expr.md#lazy-boolean-operators | ||
[macro invocation]: macros.md#macro-invocation | ||
[non-unwinding ABI boundary]: items/functions.md#unwinding | ||
[panic]: panic.md | ||
[place context]: expressions.md#place-expressions-and-value-expressions | ||
|
@@ -550,3 +565,6 @@ There is one additional case to be aware of: when a panic reaches a [non-unwindi | |
[`match`]: expressions/match-expr.md | ||
[`while let`]: expressions/loop-expr.md#while-let-patterns | ||
[`while`]: expressions/loop-expr.md#predicate-loops | ||
|
||
[`pin!`]: std::pin::pin | ||
[`format_args!`]: core::format_args |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally this should be clearer about the format arguments being extended, not the format string (which doesn't need extension), but I've had trouble including that detail without breaking the flow/clarity of the section