diff --git a/promotion.md b/promotion.md index d2a9ee8..230e303 100644 --- a/promotion.md +++ b/promotion.md @@ -69,22 +69,19 @@ 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 and inline assembly `const` operands everywhere +* `#[rustc_args_required_const]` arguments and inline assembly `const` operands everywhere. +* 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`. That is currently -the only difference. +In these contexts, we promote calls to arbitrary `const fn`. -[warn-rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1229-compile-time-asserts.md - -## Promotion in const contexts +There is one further special case for the bodies of `const` and `static` items; here we additionally promote union field accesses. +Both of these special cases can lead to promoting things that can fail to evaluate. +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. -When promoting inside a const context (`const` and `static` items and `const fn`), we relax almost all promotion restrictions, except for basic constness restrictions listed below. -We do this for all kinds of promotion. +[See below][static access] for another special case in promotion analysis: +accesses and references to statics are only promoted inside other statics. -For `const fn`, [this is a bug](https://github.com/rust-lang/rust/issues/75586). - -For `const` and `static` items, this can lead to promoting things that can fail to evaluate. -Currently, this works out because in the first case 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. +[warn-rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1229-compile-time-asserts.md ## "enclosing scope" rule @@ -228,6 +225,7 @@ or `const` item and refer to that. the result of computing a promoted is a value that does not need dropping. ### Access to a `const` or `static` +[access-static]: #access-to-a-const-or-static When accessing a `const` in a promotable context, its value gets computed at compile-time anyway, so we do not have to check the initializer. However, the @@ -248,8 +246,9 @@ const ANSWER: i32 = { let x: &'static i32 = &ANSWER; ``` -An access to a `static` is only promotable within the initializer of another -`static`. This is for the same reason that `const` initializers +An access to a `static`, including just taking references to a `static`, is only +promotable within the initializer of another `static`. This is for the same +reason that `const` initializers [cannot access statics](const.md#reading-statics). Crucially, however, the following is *not* legal: