Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/destructors.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,24 @@ r[destructors.scope.const-promotion]

Promotion of a value expression to a `'static` slot occurs when the expression could be written in a constant and borrowed, and that borrow could be dereferenced where the expression was originally written, without changing the runtime behavior. That is, the promoted expression can be evaluated at compile-time and the resulting value does not contain [interior mutability] or [destructors] (these properties are determined based on the value where possible, e.g. `&None` always has the type `&'static Option<_>`, as it contains nothing disallowed).

r[destructors.scope.const-promotion.extern-static]
A borrow of an [`extern` static] cannot be promoted, even if the resulting reference is never read from.

```rust,compile_fail
unsafe extern "C" {
static X: i32;
}

// The array is a temporary, so it would have to be promoted to a
// `'static` slot in order to be used in a static initializer.
// However, since it borrows an `extern` static, it is not eligible
// for promotion.
static mut FOO: *const &i32 = [unsafe { &X }].as_ptr(); // ERROR
```

Comment on lines +381 to +395

@traviscross traviscross Jul 28, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If the error produced has an error code, we'll want to add that to the infostring line.

Probably we also want to add some comments to this example to help make clear what's going on. And maybe it's worth adding an admonition that mentions the theory behind why this is rejected (see, e.g., what I wrote in rust-lang/rust#157641 (comment)).

View changes since the review

@sjwang05 sjwang05 Aug 2, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Only a plain error: encountered dangling pointer in final value of mutable static gets shown, so there's no error code.

I added comments to the code example, along with an admonition that adds a little more detail.

> [!NOTE]
> Only expressions that cannot fail to evaluate can be promoted. The value of an `extern` static cannot be known at compile time, so any expression that uses an `extern` static is rejected, even if it never reads the static's value. To borrow an `extern` static in a const context, use a [const block] instead.

r[destructors.scope.lifetime-extension]
### Temporary lifetime extension

Expand Down Expand Up @@ -645,9 +663,11 @@ There is one additional case to be aware of: when a panic reaches a [non-unwindi
[Assignment]: expressions/operator-expr.md#assignment-expressions
[binding modes]: patterns.md#binding-modes
[closure]: types/closure.md
[const block]: expressions/block-expr.md#const-blocks
[destructors]: destructors.md
[destructuring assignment]: expr.assign.destructure
[expression]: expressions.md
[`extern` static]: items/external-blocks.md#statics
[guard condition operand]: expressions/match-expr.md#match-guard-chains
[identifier pattern]: patterns.md#identifier-patterns
[initialized]: glossary.md#initialized
Expand Down
Loading