Skip to content

Commit 920bdb4

Browse files
committed
don't extend non-extended super let initializers' block tail temps
1 parent 9fd57df commit 920bdb4

File tree

4 files changed

+30
-9
lines changed

4 files changed

+30
-9
lines changed

compiler/rustc_hir_analysis/src/check/region.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,7 @@ fn resolve_local<'tcx>(
467467
// A, but the inner rvalues `a()` and `b()` have an extended lifetime
468468
// due to rule C.
469469

470+
let mut extend_initializer = true;
470471
if let_kind == LetKind::Super {
471472
if let Some(scope) = visitor.extended_super_lets.remove(&pat.unwrap().hir_id.local_id) {
472473
// This expression was lifetime-extended by a parent let binding. E.g.
@@ -497,10 +498,17 @@ fn resolve_local<'tcx>(
497498
}
498499
visitor.cx.var_parent = parent;
499500
}
501+
// Don't lifetime-extend child `super let`s or block tail expressions' temporaries in
502+
// the initializer when this `super let` is not itself extended by a parent `let`
503+
// (#145784). Block tail expressions are temporary drop scopes in Editions 2024 and
504+
// later, their temps shouldn't outlive the block in e.g. `f(pin!({ &temp() }))`.
505+
extend_initializer = false;
500506
}
501507
}
502508

503-
if let Some(expr) = init {
509+
if let Some(expr) = init
510+
&& extend_initializer
511+
{
504512
record_rvalue_scope_if_borrow_expr(visitor, expr, visitor.cx.var_parent);
505513

506514
if let Some(pat) = pat {

tests/ui/borrowck/format-args-temporary-scopes.e2024.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ LL | println!("{:?}", { &temp() });
1010
|
1111
= note: consider using a `let` binding to create a longer lived value
1212

13-
error: aborting due to 1 previous error
13+
error[E0716]: temporary value dropped while borrowed
14+
--> $DIR/format-args-temporary-scopes.rs:19:29
15+
|
16+
LL | println!("{:?}{:?}", { &temp() }, ());
17+
| ---^^^^^---
18+
| | | |
19+
| | | temporary value is freed at the end of this statement
20+
| | creates a temporary value which is freed while still in use
21+
| borrow later used here
22+
|
23+
= note: consider using a `let` binding to create a longer lived value
24+
25+
error: aborting due to 2 previous errors
1426

1527
For more information about this error, try `rustc --explain E0716`.

tests/ui/borrowck/format-args-temporary-scopes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ fn main() {
1717
// arguments when provided with two or more arguments. This caused the result of `temp()` to
1818
// outlive the result of the block, making this compile.
1919
println!("{:?}{:?}", { &temp() }, ());
20+
//[e2024]~^ ERROR: temporary value dropped while borrowed [E0716]
2021
}

tests/ui/drop/super-let-tail-expr-drop-order.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ fn main() {
4545
#[cfg(e2024)]
4646
(
4747
pin!((
48-
pin!({ &o.log(3) as *const LogDrop<'_> }),
49-
drop(o.log(1)),
48+
pin!({ &o.log(1) as *const LogDrop<'_> }),
49+
drop(o.log(2)),
5050
)),
51-
drop(o.log(2)),
51+
drop(o.log(3)),
5252
);
5353
});
5454

@@ -69,12 +69,12 @@ fn main() {
6969
(
7070
{
7171
super let _ = {
72-
super let _ = { &o.log(4) as *const LogDrop<'_> };
73-
drop(o.log(1))
72+
super let _ = { &o.log(1) as *const LogDrop<'_> };
73+
drop(o.log(2))
7474
};
75-
drop(o.log(2))
75+
drop(o.log(3))
7676
},
77-
drop(o.log(3)),
77+
drop(o.log(4)),
7878
);
7979
});
8080

0 commit comments

Comments
 (0)