Skip to content

Commit a87322d

Browse files
committed
Clarify const item text WRT mutable statics
The rule is that "mutable references contained within a mutable static may be referenced in the final value of a constant." However, the key here is that "mutable static" means either a `static mut` item or a `static` item with an interior mutable type. We had made that clear over in `const-eval.const-expr.path-static` but not in our rules about const item validity, and our link for "mutable static" had implied it may mean `static mut`. Let's fix that and add an example to demonstrate the point.
1 parent ef09587 commit a87322d

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

src/items/constant-items.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,31 @@ const _: U = unsafe { U { f: &mut S }}; // OK.
133133
// This is treated as a sequence of untyped bytes.
134134
```
135135

136-
Mutable references contained within a [mutable static] may be referenced in the final value of a constant.
136+
Mutable references contained within a mutable `static` may be referenced in the final value of a constant. A mutable `static` is a [`static mut`] item or a [`static`] item with an [interior mutable] type.
137137

138-
```rust
138+
```rust,no_run
139139
# #![allow(static_mut_refs)]
140140
static mut S: &mut u8 = unsafe { static mut I: u8 = 0; &mut I };
141141
const _: &&mut u8 = unsafe { &S }; // OK.
142142
// ^^^^^^^
143143
// This mutable reference comes from a `static mut`.
144144
```
145145

146+
```rust,no_run
147+
# #![allow(static_mut_refs)]
148+
# use core::cell::UnsafeCell;
149+
struct PhantomCell { _m: UnsafeCell<()> }
150+
unsafe impl Sync for PhantomCell {}
151+
static S: (&mut u8, Option<PhantomCell>) = {
152+
static mut I: u8 = 0;
153+
(unsafe { &mut I }, None)
154+
};
155+
const _: &&mut u8 = &S.0;
156+
// ^^^^^^^
157+
// This mutable reference comes from a `static` with an
158+
// interior mutable type.
159+
```
160+
146161
> [!NOTE]
147162
> This is allowed as it's separately not allowed to read from a mutable static during constant evaluation. See [const-eval.const-expr.path-static].
148163
@@ -251,17 +266,19 @@ fn unused_generic_function<T>() {
251266
}
252267
```
253268

269+
[`static mut`]: items.static.mut
270+
[`static`]: items.static
254271
[const_eval]: ../const_eval.md
255272
[associated constant]: ../items/associated-items.md#associated-constants
256273
[constant value]: ../const_eval.md#constant-expressions
257274
[external static]: items.extern.static
258275
[free]: ../glossary.md#free-item
276+
[interior mutable]: interior-mut
259277
[static lifetime elision]: ../lifetime-elision.md#const-and-static-elision
260278
[trait definition]: traits.md
261279
[underscore imports]: use-declarations.md#underscore-imports
262280
[`Copy`]: ../special-types-and-traits.md#copy
263281
[value namespace]: ../names/namespaces.md
264-
[mutable static]: items.static.mut
265282
[promoted]: destructors.scope.const-promotion
266283
[promotion]: destructors.scope.const-promotion
267284
[union type]: type.union

0 commit comments

Comments
 (0)