mirror of
https://github.com/rust-lang/rust.git
synced 2025-10-02 18:27:37 +00:00
don't extend non-extended super let
initializers' block tail temps
This commit is contained in:
parent
9fd57df639
commit
0976d6ccac
@ -467,8 +467,12 @@ fn resolve_local<'tcx>(
|
||||
// A, but the inner rvalues `a()` and `b()` have an extended lifetime
|
||||
// due to rule C.
|
||||
|
||||
if let_kind == LetKind::Super {
|
||||
if let Some(scope) = visitor.extended_super_lets.remove(&pat.unwrap().hir_id.local_id) {
|
||||
let extend_initializer = match let_kind {
|
||||
LetKind::Regular => true,
|
||||
LetKind::Super
|
||||
if let Some(scope) =
|
||||
visitor.extended_super_lets.remove(&pat.unwrap().hir_id.local_id) =>
|
||||
{
|
||||
// This expression was lifetime-extended by a parent let binding. E.g.
|
||||
//
|
||||
// let a = {
|
||||
@ -481,7 +485,10 @@ fn resolve_local<'tcx>(
|
||||
// Processing of `let a` will have already decided to extend the lifetime of this
|
||||
// `super let` to its own var_scope. We use that scope.
|
||||
visitor.cx.var_parent = scope;
|
||||
} else {
|
||||
// Extend temporaries to live in the same scope as the parent `let`'s bindings.
|
||||
true
|
||||
}
|
||||
LetKind::Super => {
|
||||
// This `super let` is not subject to lifetime extension from a parent let binding. E.g.
|
||||
//
|
||||
// identity({ super let x = temp(); &x }).method();
|
||||
@ -497,10 +504,17 @@ fn resolve_local<'tcx>(
|
||||
}
|
||||
visitor.cx.var_parent = parent;
|
||||
}
|
||||
// Don't lifetime-extend child `super let`s or block tail expressions' temporaries in
|
||||
// the initializer when this `super let` is not itself extended by a parent `let`
|
||||
// (#145784). Block tail expressions are temporary drop scopes in Editions 2024 and
|
||||
// later, their temps shouldn't outlive the block in e.g. `f(pin!({ &temp() }))`.
|
||||
false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(expr) = init {
|
||||
if let Some(expr) = init
|
||||
&& extend_initializer
|
||||
{
|
||||
record_rvalue_scope_if_borrow_expr(visitor, expr, visitor.cx.var_parent);
|
||||
|
||||
if let Some(pat) = pat {
|
||||
|
@ -10,6 +10,18 @@ LL | println!("{:?}", { &temp() });
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/format-args-temporary-scopes.rs:19:29
|
||||
|
|
||||
LL | println!("{:?}{:?}", { &temp() }, ());
|
||||
| ---^^^^^---
|
||||
| | | |
|
||||
| | | temporary value is freed at the end of this statement
|
||||
| | creates a temporary value which is freed while still in use
|
||||
| borrow later used here
|
||||
|
|
||||
= note: consider using a `let` binding to create a longer lived value
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0716`.
|
||||
|
@ -17,4 +17,5 @@ fn main() {
|
||||
// arguments when provided with two or more arguments. This caused the result of `temp()` to
|
||||
// outlive the result of the block, making this compile.
|
||||
println!("{:?}{:?}", { &temp() }, ());
|
||||
//[e2024]~^ ERROR: temporary value dropped while borrowed [E0716]
|
||||
}
|
||||
|
@ -45,10 +45,10 @@ fn main() {
|
||||
#[cfg(e2024)]
|
||||
(
|
||||
pin!((
|
||||
pin!({ &o.log(3) as *const LogDrop<'_> }),
|
||||
drop(o.log(1)),
|
||||
pin!({ &o.log(1) as *const LogDrop<'_> }),
|
||||
drop(o.log(2)),
|
||||
)),
|
||||
drop(o.log(2)),
|
||||
drop(o.log(3)),
|
||||
);
|
||||
});
|
||||
|
||||
@ -69,12 +69,12 @@ fn main() {
|
||||
(
|
||||
{
|
||||
super let _ = {
|
||||
super let _ = { &o.log(4) as *const LogDrop<'_> };
|
||||
drop(o.log(1))
|
||||
super let _ = { &o.log(1) as *const LogDrop<'_> };
|
||||
drop(o.log(2))
|
||||
};
|
||||
drop(o.log(2))
|
||||
drop(o.log(3))
|
||||
},
|
||||
drop(o.log(3)),
|
||||
drop(o.log(4)),
|
||||
);
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user