11# Const promotion
22
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 .
66
77## Promotion contexts
88
@@ -57,11 +57,14 @@ actually put on the stack. In this way, lifetime extension is an "implicit
5757promotion context": the user did not ask for the value to be promoted.
5858
5959On 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
6162to be evaluated at compile-time even though they have not written it in a
6263` const ` declaration. We call this an "explicit promotion context".
6364
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 ` ).
6568
6669The distinction between these two determines whether calls to arbitrary `const
6770fn` 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
119122const context, the user likely expects that ` x ` will live on the stack and be
120123initialized at run-time. Although this is not (to my knowledge) guaranteed by
121124the 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.)
122129
123130### Single assignment
124131
@@ -137,11 +144,11 @@ resources for little benefit.
137144
138145### Access to a ` const ` or ` static `
139146
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:
145152
146153``` rust
147154const BOOL : i32 = {
@@ -152,8 +159,9 @@ const BOOL: i32 = {
152159let x : & 'static i32 = & BOOL ;
153160```
154161
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 ) .
157165
158166### Panics
159167
0 commit comments