1
1
# Const promotion
2
2
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
+
3
9
Note that promotion happens on the MIR, not on surface-level syntax. This is
4
10
relevant when discussing e.g. handling of panics caused by overflowing
5
11
arithmetic.
@@ -8,11 +14,12 @@ arithmetic.
8
14
9
15
### 1. Panics
10
16
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
16
23
17
24
```
18
25
_tmp1 = CheckedSub (const 0usize) (const 1usize)
@@ -23,10 +30,10 @@ _tmp2 = tmp1.0
23
30
_res = &_tmp2
24
31
```
25
32
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
30
37
assertion is going to fail). Just to be safe, we generate a call to
31
38
` llvm.trap ` .
32
39
@@ -91,6 +98,13 @@ TODO: Fill this with information.
91
98
[ Constant references] ( const_refs.md ) impose some restrictions on the data they
92
99
point to; the same restrictions apply to promoteds.
93
100
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
+
94
108
## Open questions
95
109
96
110
* There is a fourth kind of CTFE failure -- and endless loop being detected.
0 commit comments