Skip to content

Commit 41b59f0

Browse files
committed
promotion tweaks
1 parent e1bd11d commit 41b59f0

File tree

1 file changed

+20
-12
lines changed

1 file changed

+20
-12
lines changed

promotion.md

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
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
5757
promotion context": the user did not ask for the value to be promoted.
5858

5959
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
6162
to 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

6669
The distinction between these two determines whether calls to arbitrary `const
6770
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
119122
const context, the user likely expects that `x` will live on the stack and be
120123
initialized at run-time. Although this is not (to my knowledge) guaranteed by
121124
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.)
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
147154
const BOOL: i32 = {
@@ -152,8 +159,9 @@ const BOOL: i32 = {
152159
let 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

Comments
 (0)