diff --git a/src/items/constant-items.md b/src/items/constant-items.md index be94be6cb..10038c640 100644 --- a/src/items/constant-items.md +++ b/src/items/constant-items.md @@ -48,8 +48,36 @@ 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.no-mut-refs] +The final value of a `const` item cannot contain any mutable references. + +```rust +# #![allow(static_mut_refs)] +static mut S: u8 = 0; +const C: &u8 = unsafe { &mut S }; // OK +``` + +```rust +# use core::sync::atomic::AtomicU8; +static S: AtomicU8 = AtomicU8::new(0); +const C: &AtomicU8 = &S; // OK +``` + +```rust,compile_fail,E0080 +# #![allow(static_mut_refs)] +static mut S: u8 = 0; +const C: &mut u8 = unsafe { &mut S }; // ERROR not allowed +``` + +> [!NOTE] +> We also disallow, in the final value, shared references to mutable statics created in the initializer for a separate reason. Consider: +> +> ```rust,compile_fail,E0492 +> # use core::sync::atomic::AtomicU8; +> const C: &AtomicU8 = &AtomicU8::new(0); // ERROR +> ``` +> +> Here, the `AtomicU8` is a temporary that is lifetime extended to `'static` (see [destructors.scope.lifetime-extension.static]), and references to lifetime-extended temporaries with interior mutability are not allowed in the final value of a constant expression (see [const-eval.const-expr.borrows]). r[items.const.expr-omission] The constant expression may only be omitted in a [trait definition]. diff --git a/src/patterns.md b/src/patterns.md index 60cfb21c4..6bfe20a84 100644 --- a/src/patterns.md +++ b/src/patterns.md @@ -975,6 +975,9 @@ r[patterns.const.generic] In particular, the value of `C` must be known at pattern-building time (which is pre-monomorphization). This means that associated consts that involve generic parameters cannot be used as patterns. +r[patterns.const.immutable] +The value of `C` must not contain any references to mutable statics (`static mut` items or interior mutable `static` items) or `extern` statics. + r[patterns.const.translation] After ensuring all conditions are met, the constant value is translated into a pattern, and now behaves exactly as-if that pattern had been written directly. In particular, it fully participates in exhaustiveness checking.