1
1
# Const promotion
2
2
3
- "Promotion" is the act of guaranteeing that code not written in a const context
4
- (e.g. initalizer of a ` const ` or ` static ` , or an array length expression) will
5
- be run at compile-time .
3
+ "Promotion" is the act of guaranteeing that code * not* written in an (explicit)
4
+ const context will be run at compile-time. Explicit const contexts include the
5
+ initializer of a ` const ` or ` static ` , or an array length expression .
6
6
7
7
## Promotion contexts
8
8
@@ -57,11 +57,14 @@ actually put on the stack. In this way, lifetime extension is an "implicit
57
57
promotion context": the user did not ask for the value to be promoted.
58
58
59
59
On the other hand, when a user passes an expression to a function with
60
- ` #[rustc_args_required_const] ` , they are explicitly asking for that expression
60
+ ` #[rustc_args_required_const] ` , the only way for this code to compile is to promote it.
61
+ In that sense, the user is explicitly asking for that expression
61
62
to be evaluated at compile-time even though they have not written it in a
62
63
` const ` declaration. We call this an "explicit promotion context".
63
64
64
- Currently, non-` Copy ` array initialization is treated as an implicit context.
65
+ Currently, non-` Copy ` array initialization is treated as an implicit context,
66
+ because the code could compile even without promotion (namely, if the result
67
+ type is ` Copy ` ).
65
68
66
69
The distinction between these two determines whether calls to arbitrary `const
67
70
fn` s (those without ` #[ rustc_promotable] `) are promotable (see below). See
@@ -119,6 +122,10 @@ limitation with the CTFE engine. While writing `let x = {expr}` outside of a
119
122
const context, the user likely expects that ` x ` will live on the stack and be
120
123
initialized at run-time. Although this is not (to my knowledge) guaranteed by
121
124
the language, we do not wish to violate the user's expectations here.
125
+ (Constant-folding still applies: the optimizer may compute ` x ` at compile-time
126
+ and even inline it everywhere if it can show that this does not observably alter
127
+ program behavior. Promotion is very different from constant-folding as
128
+ promotion can introduce observable differences in behavior.)
122
129
123
130
### Single assignment
124
131
@@ -137,11 +144,11 @@ resources for little benefit.
137
144
138
145
### Access to a ` const ` or ` static `
139
146
140
- When accessing a ` const ` in a promotable context, the restrictions on single
141
- assignment and named locals do not apply to the body of the ` const ` . All other
142
- restrictions, notably that the result of the ` const ` cannot be ` Drop ` or mutable
143
- through a reference still apply. For instance, while the previous example was
144
- not legal, the following would be:
147
+ When accessing a ` const ` in a promotable context, the initializer of that body
148
+ is not subject to any restrictions. However, the usual restrictions on the
149
+ * result * of that computation still apply: it cannot be ` Drop ` .
150
+
151
+ For instance, while the previous example was not legal, the following would be:
145
152
146
153
``` rust
147
154
const BOOL : i32 = {
@@ -152,8 +159,9 @@ const BOOL: i32 = {
152
159
let x : & 'static i32 = & BOOL ;
153
160
```
154
161
155
- An access to a ` static ` is only promotable within the initializer of
156
- another ` static ` .
162
+ An access to a ` static ` is only promotable within the initializer of another
163
+ ` static ` . This is for the same reason that ` const ` initializers
164
+ [ cannot access statics] ( const.md#reading-statics ) .
157
165
158
166
### Panics
159
167
0 commit comments