@@ -246,7 +246,14 @@ pub fn intern_const_alloc_recursive<
246
246
// that we are starting in, and all other allocations that we are encountering recursively.
247
247
let ( base_mutability, inner_mutability ) = match intern_kind {
248
248
InternKind :: Constant | InternKind :: Promoted => {
249
- // Completely immutable.
249
+ // Completely immutable. Interning anything mutably here can only lead to unsoundness,
250
+ // since all consts are conceptually independent values but share the same underlying
251
+ // memory.
252
+ // This means we do intern allocations caused by the "tail expression" / "outer scope"
253
+ // rule as immutable. We rely on const-checking ensuring that no mutable memory can
254
+ // occur there: mutable references and interior mutability must be rejected even when
255
+ // the corresponding feature gates are enabled, so only `&Freeze` references remain, and
256
+ // hence interning immutably is sound.
250
257
( Mutability :: Not , Mutability :: Not )
251
258
}
252
259
InternKind :: Static ( Mutability :: Not ) => {
@@ -257,13 +264,14 @@ pub fn intern_const_alloc_recursive<
257
264
} else {
258
265
Mutability :: Mut
259
266
} ,
260
- // Inner allocations are never mutable.
267
+ // Inner allocations are never mutable. They can only arise via the "tail
268
+ // expression" / "outer scope" rule, and we treat them consistently with `const`.
261
269
Mutability :: Not ,
262
270
)
263
271
}
264
272
InternKind :: Static ( Mutability :: Mut ) => {
265
273
// Just make everything mutable. We accept code like
266
- // `static mut X = &mut 42 `, so even inner allocations need to be mutable.
274
+ // `static mut X = &mut [42] `, so even inner allocations need to be mutable.
267
275
( Mutability :: Mut , Mutability :: Mut )
268
276
}
269
277
} ;
@@ -326,7 +334,7 @@ pub fn intern_const_alloc_recursive<
326
334
while let Some ( alloc_id) = todo. pop ( ) {
327
335
if let Some ( ( _, mut alloc) ) = ecx. memory . alloc_map . remove ( & alloc_id) {
328
336
// This still needs to be interned. We keep the old logic around here to avoid changing
329
- // rustc behavior; eventually this should all be removed in favor of ignroing all types
337
+ // rustc behavior; eventually this should all be removed in favor of ignoring all types
330
338
// and interning everything with a simple `intern_shallow` loop.
331
339
match intern_kind {
332
340
// Statics may point to mutable allocations.
0 commit comments