@@ -115,56 +115,10 @@ expressions are actually eligible for promotion? We refer to eligible
115
115
expressions as "promotable" and describe the restrictions on such expressions
116
116
below.
117
117
118
- ### Named locals
119
-
120
- Promotable expressions cannot refer to named locals. This is not a technical
121
- limitation with the CTFE engine. While writing ` let x = {expr} ` outside of a
122
- const context, the user likely expects that ` x ` will live on the stack and be
123
- initialized at run-time. Although this is not (to my knowledge) guaranteed by
124
- the language, we do not wish to violate the user's expectations here.
125
-
126
- However, constant-folding still applies: the optimizer may compute ` x ` at
127
- compile-time and even inline it everywhere if it can show that this does not
128
- observably alter program behavior. Promotion is very different from
129
- constant-folding as promotion can introduce observable differences in behavior
130
- (if const-evaluation fails) and as it is * guaranteed* to happen in some cases
131
- (and thus exploited by the borrow checker).
132
-
133
- ### Single assignment
134
-
135
- We only promote temporaries that are assigned to exactly once. For example, the
136
- lifetime of the temporary whose reference is assigned to ` x ` below will not be
137
- extended.
138
-
139
- ``` rust
140
- let x : & 'static i32 = & if cfg! (windows ) { 0 } else { 1 };
141
- ```
142
-
143
- Once again, this is not a fundamental limitation in the CTFE engine; we are
144
- perfectly capable of evaluating such expressions at compile time. However,
145
- determining the promotability of complex expressions would require more
146
- resources for little benefit.
147
-
148
- ### Access to a ` const ` or ` static `
149
-
150
- When accessing a ` const ` in a promotable context, the initializer of that body
151
- is not subject to any restrictions. However, the usual restrictions on the
152
- * result* of that computation still apply: it [ cannot be ` Drop ` ] ( #drop ) .
153
-
154
- For instance, while the previous example was not legal, the following would be:
155
-
156
- ``` rust
157
- const BOOL : i32 = {
158
- let ret = if cfg! (windows ) { 0 } else { 1 };
159
- ret
160
- };
161
-
162
- let x : & 'static i32 = & BOOL ;
163
- ```
164
-
165
- An access to a ` static ` is only promotable within the initializer of another
166
- ` static ` . This is for the same reason that ` const ` initializers
167
- [ cannot access statics] ( const.md#reading-statics ) .
118
+ First of all, expressions have to be [ allowed in constants] ( const.md ) . The
119
+ restrictions described there are needed because we want ` const ` to behave the
120
+ same as copying the ` const ` initializer everywhere the constant is used; we need
121
+ the same property when promoting expressions. But we need more.
168
122
169
123
### Panics
170
124
@@ -270,6 +224,59 @@ or `const` item and refer to that.
270
224
* Dynamic check.* The Miri engine could dynamically check this by ensuring that
271
225
the result of computing a promoted is a value that does not need dropping.
272
226
227
+ ### Access to a ` const ` or ` static `
228
+
229
+ When accessing a ` const ` in a promotable context, its value anyway gets computed
230
+ at compile-time, so we do not have to check the initializer. However, the
231
+ restrictions described above still apply for the * result* of the promoted
232
+ computation: in particular, it must be a valid ` const ` (i.e., it cannot
233
+ introduce interior mutability) and it must not require dropping.
234
+
235
+ For instance, while the previous example was not legal, the following would be:
236
+
237
+ ``` rust
238
+ const BOOL : i32 = {
239
+ let ret = if cfg! (windows ) { 0 } else { 1 };
240
+ ret
241
+ };
242
+
243
+ let x : & 'static i32 = & BOOL ;
244
+ ```
245
+
246
+ An access to a ` static ` is only promotable within the initializer of another
247
+ ` static ` . This is for the same reason that ` const ` initializers
248
+ [ cannot access statics] ( const.md#reading-statics ) .
249
+
250
+ ### Named locals
251
+
252
+ Promotable expressions cannot refer to named locals. This is not a technical
253
+ limitation with the CTFE engine. While writing ` let x = {expr} ` outside of a
254
+ const context, the user likely expects that ` x ` will live on the stack and be
255
+ initialized at run-time. Although this is not (to my knowledge) guaranteed by
256
+ the language, we do not wish to violate the user's expectations here.
257
+
258
+ However, constant-folding still applies: the optimizer may compute ` x ` at
259
+ compile-time and even inline it everywhere if it can show that this does not
260
+ observably alter program behavior. Promotion is very different from
261
+ constant-folding as promotion can introduce observable differences in behavior
262
+ (if const-evaluation fails) and as it is * guaranteed* to happen in some cases
263
+ (and thus exploited by the borrow checker).
264
+
265
+ ### Single assignment
266
+
267
+ We only promote temporaries that are assigned to exactly once. For example, the
268
+ lifetime of the temporary whose reference is assigned to ` x ` below will not be
269
+ extended.
270
+
271
+ ``` rust
272
+ let x : & 'static i32 = & if cfg! (windows ) { 0 } else { 1 };
273
+ ```
274
+
275
+ Once again, this is not a fundamental limitation in the CTFE engine; we are
276
+ perfectly capable of evaluating such expressions at compile time. However,
277
+ determining the promotability of complex expressions would require more
278
+ resources for little benefit.
279
+
273
280
## Open questions
274
281
275
282
* There is a fourth kind of CTFE failure -- resource exhaustion. What do we do
0 commit comments