Skip to content

Commit 4854f41

Browse files
committed
move 'enclosing scope' discussion
1 parent 9d16e3a commit 4854f41

File tree

1 file changed

+17
-30
lines changed

1 file changed

+17
-30
lines changed

promotion.md

+17-30
Original file line numberDiff line numberDiff line change
@@ -47,36 +47,6 @@ corresponding arguments.
4747
Similarly, inline assembly has `const` operands, which are treated the same way
4848
as `rustc_args_required_const` arguments.
4949

50-
### Promotion inside `const` and `static`
51-
52-
Lifetime extension is also responsible for making code like this work:
53-
54-
```rust
55-
const FOO: &'static i32 = {
56-
let x = &13;
57-
x
58-
};
59-
```
60-
61-
Like in run-time code, a part of the MIR (the one computing `13`) is spliced
62-
into a separate MIR body, and evaluated like a separate constant. In the case
63-
of `const` and `static` initializers, this does not affect how the code is
64-
evaluated (everything happens at compile-time), but it still affects the
65-
lifetimes.
66-
67-
Notice that some code involving `&` *looks* like it relies on lifetime
68-
extension but actually does not:
69-
70-
```rust
71-
const EMPTY_BYTES: &Vec<u8> = &Vec::new(); // Ok without lifetime extension
72-
```
73-
74-
`Vec::new()` cannot get promoted because it needs dropping. And yet this
75-
compiles. Why that? The reason is that the reference obtains the lifetime of
76-
the "enclosing scope", similar to how `let x = &mut x;` creates a reference
77-
whose lifetime lasts for the enclosing scope. This is decided during MIR
78-
building already, and does not involve lifetime extension.
79-
8050
## Implicit and explicit promotion
8151

8252
On top of what applies to [consts](const.md), promoteds suffer from the additional issue that *the user did not ask for them to be evaluated at compile-time*.
@@ -116,6 +86,23 @@ For `const fn`, [this is a bug](https://github.com/rust-lang/rust/issues/75586).
11686
For `const` and `static` items, this can lead to promoting things that can fail to evaluate.
11787
Currently, this works out because in the first case it just leads to a warning, but longer-term it would be desirable to turn evaluation failures into hard errors, which for these promoteds means we have to guarantee that we only evaluate them on-demand.
11888

89+
## "enclosing scope" rule
90+
91+
Notice that some code involving `&` *looks* like it relies on lifetime
92+
extension but actually does not:
93+
94+
```rust
95+
const EMPTY_BYTES: &Vec<u8> = &Vec::new(); // Ok without lifetime extension
96+
```
97+
98+
`Vec::new()` cannot get promoted because it needs dropping. And yet this
99+
compiles. Why that? The reason is that the reference obtains the lifetime of
100+
the "enclosing scope", similar to how `let x = &mut x;` creates a reference
101+
whose lifetime lasts for the enclosing scope. This is decided during MIR
102+
building already, and does not involve lifetime extension.
103+
104+
This is also sometimes called "outermost scope" rule.
105+
119106
## Promotability
120107

121108
We have described the circumstances where promotion is desirable, but what

0 commit comments

Comments
 (0)