@@ -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
7786We 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
238260the 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