Skip to content

Commit b14b4e4

Browse files
authored
Merge pull request #2080 from RalfJung/no-mut-refs
get rid of const.no-mut-refs
2 parents ef09587 + b666677 commit b14b4e4

File tree

1 file changed

+0
-136
lines changed

1 file changed

+0
-136
lines changed

src/items/constant-items.md

Lines changed: 0 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -48,137 +48,6 @@ const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings {
4848
};
4949
```
5050

51-
r[items.const.no-mut-refs]
52-
The final value of a `const` item, after the initializer is evaluated to a value that has the declared type of the constant, cannot contain any mutable references except as described below.
53-
54-
```rust
55-
# #![allow(static_mut_refs)]
56-
static mut S: u8 = 0;
57-
const _: &u8 = unsafe { &mut S }; // OK.
58-
// ^^^^^^
59-
// Allowed since this is coerced to `&S`.
60-
```
61-
62-
```rust
63-
# use core::sync::atomic::AtomicU8;
64-
static S: AtomicU8 = AtomicU8::new(0);
65-
const _: &AtomicU8 = &S; // OK.
66-
// ^^
67-
// Allowed even though the shared reference is to an interior
68-
// mutable value.
69-
```
70-
71-
```rust,compile_fail,E0080
72-
# #![allow(static_mut_refs)]
73-
static mut S: u8 = 0;
74-
const _: &mut u8 = unsafe { &mut S }; // ERROR.
75-
// ^^^^^^
76-
// Not allowed as the mutable reference appears in the final value.
77-
```
78-
79-
> [!NOTE]
80-
> Constant initializers can be thought of, in most cases, as being inlined wherever the constant appears. If a constant whose value contains a mutable reference to a mutable static were to appear twice, and this were to be allowed, that would create two mutable references, each having `'static` lifetime, to the same place. This could produce undefined behavior.
81-
>
82-
> Constants that contain mutable references to temporaries whose scopes have been extended to the end of the program have that same problem and an additional one.
83-
>
84-
> ```rust,compile_fail,E0764
85-
> const _: &mut u8 = &mut 0; // ERROR.
86-
> // ^^^^^^
87-
> // Not allowed as the mutable reference appears in the final value and
88-
> // because the constant expression contains a mutable borrow of an
89-
> // expression whose temporary scope would be extended to the end of
90-
> // the program.
91-
> ```
92-
>
93-
> Here, the value `0` is a temporary whose scope is extended to the end of the program (see [destructors.scope.lifetime-extension.static]). Such temporaries cannot be mutably borrowed in constant expressions (see [const-eval.const-expr.borrows]).
94-
>
95-
> To allow this, we'd have to decide whether each use of the constant creates a new `u8` value or whether each use shares the same lifetime-extended temporary. The latter choice, though closer to how `rustc` thinks about this today, would break the conceptual model that, in most cases, the constant initializer can be thought of as being inlined wherever the constant is used. Since we haven't decided, and due to the other problem mentioned, this is not allowed.
96-
97-
```rust,compile_fail,E0080
98-
# #![allow(static_mut_refs)]
99-
static mut S: u8 = 0;
100-
const _: &dyn Send = &unsafe { &mut S }; // ERROR.
101-
// ^^^^^^
102-
// Not allowed as the mutable reference appears in the final value,
103-
// even though type erasure occurs.
104-
```
105-
106-
Mutable references where the referent is a value of a [zero-sized type] are allowed.
107-
108-
```rust
109-
# #![allow(static_mut_refs)]
110-
static mut S: () = ();
111-
const _: &mut () = unsafe { &mut S }; // OK.
112-
// ^^ This is a zero-sized type.
113-
```
114-
115-
```rust
116-
# #![allow(static_mut_refs)]
117-
static mut S: [u8; 0] = [0; 0];
118-
const _: &mut [u8; 0] = unsafe { &mut S }; // OK.
119-
// ^^^^^^^ This is a zero-sized type.
120-
```
121-
122-
> [!NOTE]
123-
> This is allowed as, for a value of a zero-sized type, no bytes can actually be mutated. We must accept this as `&mut []` is [promoted].
124-
125-
Values of [union type] are not considered to contain any references; for this purpose, a value of union type is treated as a sequence of untyped bytes.
126-
127-
```rust
128-
# #![allow(static_mut_refs)]
129-
union U { f: &'static mut u8 }
130-
static mut S: u8 = 0;
131-
const _: U = unsafe { U { f: &mut S }}; // OK.
132-
// ^^^^^^^^^^^^^^^
133-
// This is treated as a sequence of untyped bytes.
134-
```
135-
136-
Mutable references contained within a [mutable static] may be referenced in the final value of a constant.
137-
138-
```rust
139-
# #![allow(static_mut_refs)]
140-
static mut S: &mut u8 = unsafe { static mut I: u8 = 0; &mut I };
141-
const _: &&mut u8 = unsafe { &S }; // OK.
142-
// ^^^^^^^
143-
// This mutable reference comes from a `static mut`.
144-
```
145-
146-
> [!NOTE]
147-
> 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].
148-
149-
Mutable references contained within an [external static] may be referenced in the final value of a constant.
150-
151-
```rust
152-
# #![allow(static_mut_refs)]
153-
unsafe extern "C" { static S: &'static mut u8; }
154-
const _: &&mut u8 = unsafe { &S }; // OK.
155-
// ^^^^^^^
156-
// This mutable references comes from an extern static.
157-
```
158-
159-
> [!NOTE]
160-
> This is allowed as it's separately not allowed to read from an external static during constant evaluation. See [const-eval.const-expr.path-static].
161-
162-
> [!NOTE]
163-
> As described above, we accept, in the final value of constant items, shared references to static items whose values have interior mutability.
164-
>
165-
> ```rust
166-
> # use core::sync::atomic::AtomicU8;
167-
> static S: AtomicU8 = AtomicU8::new(0);
168-
> const _: &AtomicU8 = &S; // OK.
169-
> ```
170-
>
171-
> However, we disallow similar code when the interior mutable value is created in the initializer.
172-
>
173-
> ```rust,compile_fail,E0492
174-
> # use core::sync::atomic::AtomicU8;
175-
> const _: &AtomicU8 = &AtomicU8::new(0); // ERROR.
176-
> ```
177-
>
178-
> Here, the `AtomicU8` is a temporary whose scope is extended to the end of the program (see [destructors.scope.lifetime-extension.static]). Such temporaries with interior mutability cannot be borrowed in constant expressions (see [const-eval.const-expr.borrows]).
179-
>
180-
> To allow this, we'd have to decide whether each use of the constant creates a new `AtomicU8` or whether each use shares the same lifetime-extended temporary. The latter choice, though closer to how `rustc` thinks about this today, would break the conceptual model that, in most cases, the constant initializer can be thought of as being inlined wherever the constant is used. Since we haven't decided, this is not allowed.
181-
18251
r[items.const.expr-omission]
18352
The constant expression may only be omitted in a [trait definition].
18453

@@ -254,15 +123,10 @@ fn unused_generic_function<T>() {
254123
[const_eval]: ../const_eval.md
255124
[associated constant]: ../items/associated-items.md#associated-constants
256125
[constant value]: ../const_eval.md#constant-expressions
257-
[external static]: items.extern.static
258126
[free]: ../glossary.md#free-item
259127
[static lifetime elision]: ../lifetime-elision.md#const-and-static-elision
260128
[trait definition]: traits.md
261129
[underscore imports]: use-declarations.md#underscore-imports
262130
[`Copy`]: ../special-types-and-traits.md#copy
263131
[value namespace]: ../names/namespaces.md
264-
[mutable static]: items.static.mut
265-
[promoted]: destructors.scope.const-promotion
266132
[promotion]: destructors.scope.const-promotion
267-
[union type]: type.union
268-
[zero-sized type]: layout.properties.size

0 commit comments

Comments
 (0)