You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
### `#[rustc_args_required_const(...)]` and inline assembly `const` operands
39
39
40
40
Additionally, some platform intrinsics require certain parameters to be
41
41
immediates (known at compile-time). We use the `#[rustc_args_required_const]`
@@ -44,59 +44,46 @@ attribute, introduced in
44
44
specify these parameters and (aggressively, see below) try to promote the
45
45
corresponding arguments.
46
46
47
-
### Implicit and explicit contexts
47
+
Similarly, inline assembly has `const` operands, which are treated the same way
48
+
as `rustc_args_required_const` arguments.
49
+
50
+
## Implicit and explicit promotion
48
51
49
52
On top of what applies to [consts](const.md), promoteds suffer from the additional issue that *the user did not ask for them to be evaluated at compile-time*.
50
53
Thus, if CTFE fails but the code would have worked fine at run-time, we broke the user's code for no good reason.
51
54
Even if we are sure we found an error in the user's code, we are only allowed to [emit a warning, not a hard error][warn-rfc].
52
-
That's why we have to be very conservative with what can and cannot be promoted.
55
+
We call this *implicit* promotion, and we have to be very conservative with what can and cannot be implicitly promoted.
53
56
54
-
For example, users might be surprised to learn that whenever they take a
55
-
reference to a temporary, that temporary may be promoted away and never
56
-
actually put on the stack. In this way, lifetime extension is an "implicit
57
-
promotion context": the user did not ask for the value to be promoted.
57
+
CTFE of implicitly promoted code must never fail to evaluate except if the
58
+
run-time code also would have failed. This means we cannot permit calling
Thus, only functions marked `#[rustc_promotable]` are implicitly promotable (see
62
+
below).
58
63
59
64
On the other hand, when a user passes an expression to a function with
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
62
-
to be evaluated at compile-time even though they have not written it in a
63
-
`const` declaration. We call this an "explicit promotion context".
64
-
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
+
`#[rustc_args_required_const]`, the only way for this code to compile is to
66
+
promote it. In that sense, the user is explicitly asking for that expression to
67
+
be evaluated at compile-time even though they have not written it in a `const`
68
+
declaration. We can thus be less conservative. This is called *explicit*
69
+
promotion.
68
70
69
-
CTFE of implicitly promoted code must never fail to evaluate except if the
70
-
run-time code also would have failed. This means we cannot permit calling
71
-
arbitrary `const fn`, as we cannot predict if they are going to perform an
72
-
["unconst" operation](const_safety.md). Thus, only functions marked
73
-
`#[rustc_promotable]` are implicitly promotable (see below). See
74
-
[rust-lang/const-eval#19](https://github.com/rust-lang/const-eval/issues/19) for
75
-
a thorough discussion of this. At present, this is the only difference between
76
-
implicit and explicit contexts. The requirements for promotion in an implicit
77
-
context are a superset of the ones in an explicit context.
71
+
Currently, the following are considered explicit promotion contexts:
72
+
*`#[rustc_args_required_const]` arguments and inline assembly `const` operands everywhere.
73
+
* Everything inside the bodies of `const` and `static` items. (Note: this is handled separately from "explicit contexts" in promotion analysis, but the effect is the same.)
In these contexts, we promote calls to arbitrary `const fn`.
80
76
81
-
### Promotion contexts inside `const` and `static`
77
+
There is one further special case for the bodies of `const` and `static` items; here we additionally promote union field accesses.
78
+
Both of these special cases can lead to promoting things that can fail to evaluate.
79
+
Currently, this works out because it just leads to a warning, but longer-term it would be desirable to turn evaluation failures into hard errors, which for these promoteds means we have to guarantee that we only evaluate them on-demand.
82
80
83
-
Lifetime extension is also responsible for making code like this work:
81
+
[See below][static access] for another special case in promotion analysis:
82
+
accesses and references to statics are only promoted inside other statics.
0 commit comments