Skip to content

Commit 4436f9c

Browse files
Merge sections on lifetime extension in consts and statics
1 parent b265568 commit 4436f9c

File tree

1 file changed

+30
-54
lines changed

1 file changed

+30
-54
lines changed

promotion.md

+30-54
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,38 @@ implicit context are a superset of the ones in an explicit context.
7272

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

75-
### Promotion contexts in `const` and `static`
75+
### Promotion contexts inside `const` and `static`
76+
77+
Lifetime extension is also responsible for making code like this work:
78+
79+
```rust
80+
const FOO: &'static i32 = {
81+
let x = &13;
82+
x
83+
};
84+
```
7685

7786
We defined above that promotion guarantees that code in a non-const context
78-
will be executed at compile-time. However, lifetime extension and non-`Copy`
79-
array initialization are useful features *inside* `const`s and `static`s as
80-
well. Strictly speaking, the transformation used to enable these features
81-
inside a const-context is not promotion; no `promoted`s are created in the MIR.
82-
However the same rules for promotability are used with one modification:
83-
Because the user has already requested that this code run at compile time, all
84-
contexts are treated as explicit.
87+
will be executed at compile-time. The above example illustrates that lifetime
88+
extension and non-`Copy` array initialization are useful features *inside*
89+
`const`s and `static`s as well. Strictly speaking, the transformation used to
90+
enable these features inside a const-context is not promotion; no `promoted`s
91+
are created in the MIR. However the same rules for promotability are used with
92+
one modification: Because the user has already requested that this code run at
93+
compile time, all contexts are treated as explicit.
94+
95+
Notice that some code involving `&` *looks* like it relies on lifetime
96+
extension but actually does not:
97+
98+
```rust
99+
const EMPTY_BYTES: &Vec<u8> = &Vec::new(); // Ok without lifetime extension
100+
```
101+
102+
As we have seen above, `Vec::new()` does not get promoted. And yet this
103+
compiles. Why that? The reason is that the reference obtains the lifetime of
104+
the "enclosing scope", similar to how `let x = &mut x;` creates a reference
105+
whose lifetime lasts for the enclosing scope. This is decided during MIR
106+
building already, and does not involve lifetime extension.
85107

86108
## Promotability
87109

@@ -237,52 +259,6 @@ or `const` item and refer to that.
237259
*Dynamic check.* The Miri engine could dynamically check this by ensuring that
238260
the result of computing a promoted is a value that does not need dropping.
239261

240-
## `&` in `const` and `static`
241-
242-
Promotion is also responsible for making code like this work:
243-
244-
```rust
245-
const FOO: &'static i32 = {
246-
let x = &13;
247-
x
248-
};
249-
```
250-
251-
However, since this is in explicit const context, we are less strict about
252-
promotion in this situation: all function calls are promoted, not just
253-
`#[rustc_promotable]` functions:
254-
255-
```rust
256-
const fn bar() -> i32 { 42 }
257-
258-
const FOO: &'static i32 = {
259-
let x = &bar(); // this gets promoted
260-
x
261-
};
262-
```
263-
264-
However, we still do not promote *everything*; e.g., drop-checking still applies:
265-
266-
```rust
267-
const DROP: &'static Vec<u8> = {
268-
let x = &Vec::new(); //~ ERROR: temporary value dropped while borrowed
269-
x
270-
};
271-
```
272-
273-
Notice that some code involving `&` *looks* like it relies on promotion but
274-
actually does not:
275-
276-
```rust
277-
const EMPTY_BYTES: &Vec<u8> = &Vec::new(); // Ok without promotion
278-
```
279-
280-
As we have seen above, `Vec::new()` does not get promoted. And yet this
281-
compiles. Why that? The reason is that the reference obtains the lifetime of
282-
the "enclosing scope", similar to how `let x = &mut x;` creates a reference
283-
whose lifetime lasts for the enclosing scope. This is decided during MIR
284-
building already, and does not involve promotion.
285-
286262
## Open questions
287263

288264
* There is a fourth kind of CTFE failure -- resource exhaustion. What do we do

0 commit comments

Comments
 (0)