Skip to content

Conversation

dianne
Copy link
Contributor

@dianne dianne commented Oct 8, 2025

This PR clarifies a point of confusion in the compiler: all bodies have an outer temporary drop scope, including static and const item bodies1. Whenever a temporary should be dropped in its enclosing temporary scope, it should have a temporary scope to be dropped in so that its drop can be scheduled2. As such, I've updated some relevant comments and made ScopeTree::default_temporary_scope and RvalueScopes::temporary_scope panic when an enclosing temporary scope isn't found instead of allowing potential bugs where potentially-drop-sensitive temporaries are effectively given static lifetimes.

Since non-extended super let bindings are dropped in their block's enclosing temporary scope, this applies to them as well: the enclosing temporary scope should exist.

Footnotes

  1. See https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir_analysis/src/check/region.rs#L773-L778 for non-fn/closure bodies. The this.cx.var_parent = None; enables lifetime extension to 'static lifetimes and the ScopeData::Destruction scope ensures non-extended temporaries are dropped in the body expression's scope.

  2. For certain borrowed temporaries, drops that don't require running destructors may later be removed by constant promotion. That is unrelated to this PR.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 8, 2025
@rustbot
Copy link
Collaborator

rustbot commented Oct 8, 2025

r? @nnethercote

rustbot has assigned @nnethercote.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Comment on lines 765 to 768
// Similarly, `const X: ... = &f();` would have the result of `f()`
// live for `'static`, implying (if Drop restrictions on constants
// ever get lifted) that the value *could* have a destructor, but
// it'd get leaked instead of the destructor running during the
// evaluation of `X` (if at all allowed by CTFE).
Copy link
Contributor Author

@dianne dianne Oct 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't tell if the remarks on on Drop restrictions are out of date or just worded a bit confusingly. I'm also not sure whether this PR is the right place to update that.

@dianne dianne force-pushed the assert-temporary-scope branch from af03a85 to 444eb4c Compare October 8, 2025 13:14
@theemathas
Copy link
Contributor

The only way a temporary should be extended to have a 'static lifetime is through lifetime extension

I'm not sure what this means. But I just wanted to note that constant-promotion in consts/statics can have a similar effect to lifetime extension, and has different behavior from constant-promotion outside of consts/statics. See #124328

@dianne
Copy link
Contributor Author

dianne commented Oct 8, 2025

I've clarified the PR description; thanks. Does it read better now? This is only about the temporary scopes assigned to expressions before PromoteTemps runs and is of most concern for non-promotable expressions (e.g. those that produce drop-sensitive temporaries).

Copy link
Contributor

@nnethercote nnethercote left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is stuff I know very little about, but the change is small enough and well explained so I'm happy with it.

View changes since this review

@nnethercote
Copy link
Contributor

@bors r+ rollup

@bors
Copy link
Collaborator

bors commented Oct 13, 2025

📌 Commit 444eb4c has been approved by nnethercote

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 13, 2025
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Oct 13, 2025
…nethercote

Assert that non-extended temporaries and `super let` bindings have scopes

This PR clarifies a point of confusion in the compiler: all bodies have an outer temporary drop scope, including `static` and `const` item bodies[^1]. Whenever a temporary should be dropped in its enclosing temporary scope, it should have a temporary scope to be dropped in so that its drop can be scheduled[^2]. As such, I've updated some relevant comments and made `ScopeTree::default_temporary_scope` and `RvalueScopes::temporary_scope` panic when an enclosing temporary scope isn't found instead of allowing potential bugs where potentially-drop-sensitive temporaries are effectively given static lifetimes.

Since non-extended `super let` bindings are dropped in their block's enclosing temporary scope, this applies to them as well: the enclosing temporary scope should exist.

[^1]: See https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir_analysis/src/check/region.rs#L773-L778 for non-`fn`/closure bodies. The `this.cx.var_parent = None;` enables [lifetime extension to `'static` lifetimes](https://doc.rust-lang.org/stable/reference/destructors.html#r-destructors.scope.lifetime-extension.static) and the `ScopeData::Destruction` scope ensures non-extended temporaries are dropped in the body expression's scope.

[^2]: For certain borrowed temporaries, drops that don't require running destructors may later be removed by constant promotion. That is unrelated to this PR.
bors added a commit that referenced this pull request Oct 13, 2025
Rollup of 7 pull requests

Successful merges:

 - #144266 (Supress swapping lhs and rhs in equality suggestion in extern macro )
 - #147471 (Assert that non-extended temporaries and `super let` bindings have scopes)
 - #147533 (Renumber return local after state transform)
 - #147566 (rewrite outlives placeholder constraints to outlives static when handling opaque types)
 - #147613 (Make logging filters work again by moving EnvFilter into its own layer)
 - #147615 (reduce calls to attr.span() in old doc attr parsing)
 - #147636 (miri subtree update)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 2a10082 into rust-lang:master Oct 13, 2025
10 checks passed
@rustbot rustbot added this to the 1.92.0 milestone Oct 13, 2025
rust-timer added a commit that referenced this pull request Oct 13, 2025
Rollup merge of #147471 - dianne:assert-temporary-scope, r=nnethercote

Assert that non-extended temporaries and `super let` bindings have scopes

This PR clarifies a point of confusion in the compiler: all bodies have an outer temporary drop scope, including `static` and `const` item bodies[^1]. Whenever a temporary should be dropped in its enclosing temporary scope, it should have a temporary scope to be dropped in so that its drop can be scheduled[^2]. As such, I've updated some relevant comments and made `ScopeTree::default_temporary_scope` and `RvalueScopes::temporary_scope` panic when an enclosing temporary scope isn't found instead of allowing potential bugs where potentially-drop-sensitive temporaries are effectively given static lifetimes.

Since non-extended `super let` bindings are dropped in their block's enclosing temporary scope, this applies to them as well: the enclosing temporary scope should exist.

[^1]: See https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir_analysis/src/check/region.rs#L773-L778 for non-`fn`/closure bodies. The `this.cx.var_parent = None;` enables [lifetime extension to `'static` lifetimes](https://doc.rust-lang.org/stable/reference/destructors.html#r-destructors.scope.lifetime-extension.static) and the `ScopeData::Destruction` scope ensures non-extended temporaries are dropped in the body expression's scope.

[^2]: For certain borrowed temporaries, drops that don't require running destructors may later be removed by constant promotion. That is unrelated to this PR.
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Oct 15, 2025
Rollup of 7 pull requests

Successful merges:

 - rust-lang/rust#144266 (Supress swapping lhs and rhs in equality suggestion in extern macro )
 - rust-lang/rust#147471 (Assert that non-extended temporaries and `super let` bindings have scopes)
 - rust-lang/rust#147533 (Renumber return local after state transform)
 - rust-lang/rust#147566 (rewrite outlives placeholder constraints to outlives static when handling opaque types)
 - rust-lang/rust#147613 (Make logging filters work again by moving EnvFilter into its own layer)
 - rust-lang/rust#147615 (reduce calls to attr.span() in old doc attr parsing)
 - rust-lang/rust#147636 (miri subtree update)

r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants