From 91e223c9de4b1c3c297bf3372c61e50b426d6457 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 13 Aug 2020 12:31:13 +0200 Subject: [PATCH] move const/static section to other promotion contexts --- promotion.md | 69 ++++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/promotion.md b/promotion.md index df26bff..a2a3793 100644 --- a/promotion.md +++ b/promotion.md @@ -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: @@ -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