Skip to content

Commit

Permalink
move const/static section to other promotion contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Aug 13, 2020
1 parent 9d36e9a commit 91e223c
Showing 1 changed file with 34 additions and 35 deletions.
69 changes: 34 additions & 35 deletions promotion.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,41 +44,7 @@ attribute, introduced in
specify these parameters and (aggressively, see below) try to promote the
corresponding arguments.

## Implicit and explicit promotion

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*.
Thus, if CTFE fails but the code would have worked fine at run-time, we broke the user's code for no good reason.
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].
We call this *implicit* promotion, and we have to be very conservative with what can and cannot be implicitly promoted.

CTFE of implicitly promoted code must never fail to evaluate except if the
run-time code also would have failed. This means we cannot permit calling
arbitrary `const fn`, as discussed in detail in
[rust-lang/const-eval#19](https://github.com/rust-lang/const-eval/issues/19).
Thus, only functions marked `#[rustc_promotable]` are implicitly promotable (see
below).

On the other hand, when a user passes an expression to a function with
`#[rustc_args_required_const]`, the only way for this code to compile is to
promote it. In that sense, the user is explicitly asking for that expression to
be evaluated at compile-time even though they have not written it in a `const`
declaration. We can thus be less conservative. This is called *explicit*
promotion.

Currently, the following are considered explicit promotion contexts:
* `#[rustc_args_required_const]` arguments
* the bodies of `const` and `static` items and array lengths

Everything else is an implicit promotion context, including `const fn` bodies and non-`Copy` array initializers.

In an explicit promotion context, we promote every closed expression (i.e.,
expressions that do not depend on other variables) of reference type, subject to
the usual restrictions of [consts](const.md). This means that interior
mutability and values that need dropping are not promoted.

[warn-rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1229-compile-time-asserts.md

## Promotion inside `const` and `static`
### Promotion inside `const` and `static`

Lifetime extension is also responsible for making code like this work:

Expand Down Expand Up @@ -108,6 +74,39 @@ the "enclosing scope", similar to how `let x = &mut x;` creates a reference
whose lifetime lasts for the enclosing scope. This is decided during MIR
building already, and does not involve lifetime extension.

## Implicit and explicit promotion

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*.
Thus, if CTFE fails but the code would have worked fine at run-time, we broke the user's code for no good reason.
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].
We call this *implicit* promotion, and we have to be very conservative with what can and cannot be implicitly promoted.

CTFE of implicitly promoted code must never fail to evaluate except if the
run-time code also would have failed. This means we cannot permit calling
arbitrary `const fn`, as discussed in detail in
[rust-lang/const-eval#19](https://github.com/rust-lang/const-eval/issues/19).
Thus, only functions marked `#[rustc_promotable]` are implicitly promotable (see
below).

On the other hand, when a user passes an expression to a function with
`#[rustc_args_required_const]`, the only way for this code to compile is to
promote it. In that sense, the user is explicitly asking for that expression to
be evaluated at compile-time even though they have not written it in a `const`
declaration. We can thus be less conservative. This is called *explicit*
promotion.

Currently, the following are considered explicit promotion contexts:
* `#[rustc_args_required_const]` arguments
* lifetime extension in the bodies of `const` and `static` items and array lengths

Everything else is an implicit promotion context, including `const fn` bodies and non-`Copy` array initializers.

In an explicit promotion context, we consider almost everything promotable,
subject to the usual restrictions of [consts](const.md). This means that
interior mutability and values that need dropping are not promoted.

[warn-rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1229-compile-time-asserts.md

## Promotability

We have described the circumstances where promotion is desirable, but what
Expand Down

0 comments on commit 91e223c

Please sign in to comment.