Skip to content

Commit 61b55a0

Browse files
committed
move const/static section to other promotion contexts
1 parent 9d36e9a commit 61b55a0

File tree

1 file changed

+30
-30
lines changed

1 file changed

+30
-30
lines changed

promotion.md

+30-30
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,36 @@ attribute, introduced in
4444
specify these parameters and (aggressively, see below) try to promote the
4545
corresponding arguments.
4646

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

4979
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*.
@@ -78,36 +108,6 @@ mutability and values that need dropping are not promoted.
78108

79109
[warn-rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1229-compile-time-asserts.md
80110

81-
## Promotion inside `const` and `static`
82-
83-
Lifetime extension is also responsible for making code like this work:
84-
85-
```rust
86-
const FOO: &'static i32 = {
87-
let x = &13;
88-
x
89-
};
90-
```
91-
92-
Like in run-time code, a part of the MIR (the one computing `13`) is spliced
93-
into a separate MIR body, and evaluated like a separate constant. In the case
94-
of `const` and `static` initializers, this does not affect how the code is
95-
evaluated (everything happens at compile-time), but it still affects the
96-
lifetimes.
97-
98-
Notice that some code involving `&` *looks* like it relies on lifetime
99-
extension but actually does not:
100-
101-
```rust
102-
const EMPTY_BYTES: &Vec<u8> = &Vec::new(); // Ok without lifetime extension
103-
```
104-
105-
`Vec::new()` cannot get promoted because it needs dropping. And yet this
106-
compiles. Why that? The reason is that the reference obtains the lifetime of
107-
the "enclosing scope", similar to how `let x = &mut x;` creates a reference
108-
whose lifetime lasts for the enclosing scope. This is decided during MIR
109-
building already, and does not involve lifetime extension.
110-
111111
## Promotability
112112

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

0 commit comments

Comments
 (0)