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
41
-
42
-
Additionally, some platform intrinsics require certain parameters to be
43
-
immediates (known at compile-time). We use the `#[rustc_args_required_const]`
44
-
attribute, introduced in
45
-
[rust-lang/rust#48018](https://github.com/rust-lang/rust/pull/48018), to
46
-
specify these parameters and (aggressively, see below) try to promote the
47
-
corresponding arguments.
48
-
49
-
Similarly, inline assembly has `const` operands, which are treated the same way
50
-
as `rustc_args_required_const` arguments.
22
+
## Promotion and fallability of const-evaluation
51
23
52
-
## Implicit and explicit promotion
24
+
On top of what applies to [consts](const.md), promoteds suffer from the
25
+
additional issue that *the user did not ask for them to be evaluated at
26
+
compile-time*. Thus, if CTFE fails but the code would have worked fine at
27
+
run-time, we broke the user's code for no good reason. Even if we are sure we
28
+
found an error in the user's code, we are only allowed to
29
+
[emit a warning, not a hard error][warn-rfc].
53
30
54
-
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*.
55
-
Thus, if CTFE fails but the code would have worked fine at run-time, we broke the user's code for no good reason.
56
-
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].
57
-
We call this *implicit* promotion, and we have to be very conservative with what can and cannot be implicitly promoted.
58
-
59
-
CTFE of implicitly promoted code must never fail to evaluate except if the
60
-
run-time code also would have failed. This means we cannot permit calling
61
-
arbitrary `const fn`, as discussed in detail in
31
+
For example:
32
+
```rust
33
+
fnfoo() {
34
+
iffalse {
35
+
letx=&(1/0);
36
+
}
37
+
}
38
+
```
39
+
If we performed promotion here, this would turn into
40
+
```rust
41
+
fnfoo() {
42
+
iffalse {
43
+
const_PROMOTED=&(1/0);
44
+
letx=_PROMOTED;
45
+
}
46
+
}
47
+
```
48
+
When compiling this function, we have to evaluate all constants that occur
49
+
inside the function body, even if they might only be used in dead code. This
50
+
means we have to evaluate `_PROMOTED`, which will error -- and now what, should
51
+
we halt compilation? That would be wrong since there is no problem with this
52
+
code, the "bad" division never actually happens as it occurs in dead code.
53
+
(Note that the considerations would be the same even if `foo` were a `const
54
+
fn`.)
55
+
56
+
As a consequence, we only promote code that can never fail to evaluate (see
57
+
[RFC 3027]). This ensures that even if promotion happens inside dead code, this
58
+
will not turn a "runtime error in dead code" (which is not an error at all) into
59
+
a compile-time error. In particular, we cannot promote calls to arbitrary `const
Thus, only functions marked `#[rustc_promotable]` are implicitly promotable (see
64
-
below).
65
-
66
-
On the other hand, when a user passes an expression to a function with
67
-
`#[rustc_args_required_const]`, the only way for this code to compile is to
68
-
promote it. In that sense, the user is explicitly asking for that expression to
69
-
be evaluated at compile-time even though they have not written it in a `const`
70
-
declaration. We can thus be less conservative. This is called *explicit*
71
-
promotion.
62
+
Thus, only functions marked `#[rustc_promotable]` are promotable.
72
63
73
-
Currently, the following are considered explicit promotion contexts:
74
-
*`#[rustc_args_required_const]` arguments and inline assembly `const` operands everywhere.
75
-
* 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.
76
-
The arguments given above for justifying explicit promotion do not apply here. Currently, this works out because failing to evaluate one of these promoteds 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.)
0 commit comments