11# Const promotion
22
3+ "Promotion" is a mechanism that affects code like ` &3 ` : Instead of putting it on
4+ the stack, the ` 3 ` is allocated in global static memory and a reference with
5+ lifetime ` 'static ` is provided. This is essentially an automatic transformation
6+ turning ` &EXPR ` into ` { const _PROMOTED = &EXPR; EXPR } ` , but only if ` EXPR `
7+ qualifies.
8+
39Note that promotion happens on the MIR, not on surface-level syntax. This is
410relevant when discussing e.g. handling of panics caused by overflowing
511arithmetic.
@@ -8,11 +14,12 @@ arithmetic.
814
915### 1. Panics
1016
11- Promotion is not allowed to throw away side effects. This includes
12- panicking. Let us look at what happens when we promote ` &(0_usize - 1) ` in a
13- debug build: We have to avoid erroring at compile-time (because that would be
14- promotion breaking compilation), but we must be sure to error correctly at
15- run-time. In the MIR, this looks roughly like
17+ Promotion is not allowed to throw away side effects. This includes panicking.
18+ Let us look at what happens when we promote ` &(0_usize - 1) ` in a debug build:
19+ We have to avoid erroring at compile-time, because that would be promotion
20+ breaking compilation (the code would have compiled just fine if we hadn't
21+ promoted), but we must be sure to error correctly at run-time. In the MIR, this
22+ looks roughly like
1623
1724```
1825_tmp1 = CheckedSub (const 0usize) (const 1usize)
@@ -23,10 +30,10 @@ _tmp2 = tmp1.0
2330_res = &_tmp2
2431```
2532
26- Both ` _tmp1 ` and ` _tmp2 ` are promoted to statics . ` _tmp1 ` evaluates to `(~ 0,
27- true) ` , so the assertion will always fail at run-time. Computing ` _ tmp2` fails
28- with a panic, which is thrown away -- so we have no result. In principle, we
29- could generate any code for this because we know the code is unreachable (the
33+ Both ` _tmp1 ` and ` _tmp2 ` are promoted. ` _tmp1 ` evaluates to ` (~0, true) ` , so
34+ the assertion will always fail at run-time. Computing ` _tmp2 ` fails with a
35+ panic, which is thrown away -- so we have no result. In principle, we could
36+ generate any code for this because we know the code is unreachable (the
3037assertion is going to fail). Just to be safe, we generate a call to
3138` llvm.trap ` .
3239
@@ -91,6 +98,13 @@ TODO: Fill this with information.
9198[ Constant references] ( const_refs.md ) impose some restrictions on the data they
9299point to; the same restrictions apply to promoteds.
93100
101+ ### 5. Accessing statics
102+
103+ Since the promoted code is evaluated at compile-time, we must make sure that it
104+ does not access any mutable statics (including safe ` static ` with interior
105+ mutability), not even read from them. Their value could have changed at
106+ run-time, so we wouldn't be producing the correct result.
107+
94108## Open questions
95109
96110* There is a fourth kind of CTFE failure -- and endless loop being detected.
0 commit comments