From 2bc43960a834675cf05d55d1c5849e1545f4c2f9 Mon Sep 17 00:00:00 2001 From: Ding Xiang Fei Date: Wed, 11 Sep 2024 21:02:18 +0800 Subject: [PATCH] Const expression can borrow static items Co-authored-by: Eric Huss --- src/const_eval.md | 8 +++++++- src/items/constant-items.md | 3 +++ src/items/static-items.md | 7 ++----- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/const_eval.md b/src/const_eval.md index c7a3bca6d..66efed2a8 100644 --- a/src/const_eval.md +++ b/src/const_eval.md @@ -42,7 +42,12 @@ r[const-eval.const-expr.path-item] Recursively defining constants is not allowed. r[const-eval.const-expr.path-static] -* Paths to [statics]. These are only allowed within the initializer of a static. +* Paths to [statics] with these restrictions: + * Writes to `static` items are not allowed in any constant evaluation context. + * Reads from `extern` statics are not allowed in any constant evaluation context. + * If the evaluation is *not* carried out in an initializer of a `static` item, then reads from any mutable `static` are not allowed. A mutable `static` is a `static mut` item, or a `static` item with an interior-mutable type. + +These requirements are checked only when the constant is evaluated. In other words, having such accesses syntactically occur in const contexts is allowed as long as they never get executed. r[const-eval.const-expr.tuple] * [Tuple expressions]. @@ -177,6 +182,7 @@ of whether you are building on a `64` bit or a `32` bit system. [enum discriminants]: items/enumerations.md#discriminants [expression statements]: statements.md#expression-statements [expressions]: expressions.md +[`extern` statics]: items/external-blocks.md#statics [field]: expressions/field-expr.md [functions]: items/functions.md [grouped]: expressions/grouped-expr.md diff --git a/src/items/constant-items.md b/src/items/constant-items.md index b80b145e7..bb8a43827 100644 --- a/src/items/constant-items.md +++ b/src/items/constant-items.md @@ -48,6 +48,9 @@ const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings { }; ``` +r[items.const.final-value-immutable] +The final value of a `const` item cannot contain references to anything mutable. + r[items.const.expr-omission] The constant expression may only be omitted in a [trait definition]. diff --git a/src/items/static-items.md b/src/items/static-items.md index f7e47736c..d9e61e648 100644 --- a/src/items/static-items.md +++ b/src/items/static-items.md @@ -37,10 +37,7 @@ All access to a static is safe, but there are a number of restrictions on statics: r[items.static.sync] -* The type must have the `Sync` trait bound to allow thread-safe access. - -r[items.static.const] -* Constants cannot refer to statics. +* The type must have the [`Sync`](std::marker::Sync) trait bound to allow thread-safe access. r[items.static.init.omission] The initializer expression must be omitted in an [external block], and must be @@ -159,7 +156,7 @@ It can be confusing whether or not you should use a constant item or a static item. Constants should, in general, be preferred over statics unless one of the following are true: -* Large amounts of data are being stored +* Large amounts of data are being stored. * The single-address property of statics is required. * Interior mutability is required.