@@ -246,7 +246,14 @@ pub fn intern_const_alloc_recursive<
246246 // that we are starting in, and all other allocations that we are encountering recursively.
247247 let ( base_mutability, inner_mutability ) = match intern_kind {
248248 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.
250257 ( Mutability :: Not , Mutability :: Not )
251258 }
252259 InternKind :: Static ( Mutability :: Not ) => {
@@ -257,13 +264,14 @@ pub fn intern_const_alloc_recursive<
257264 } else {
258265 Mutability :: Mut
259266 } ,
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`.
261269 Mutability :: Not ,
262270 )
263271 }
264272 InternKind :: Static ( Mutability :: Mut ) => {
265273 // 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.
267275 ( Mutability :: Mut , Mutability :: Mut )
268276 }
269277 } ;
@@ -326,7 +334,7 @@ pub fn intern_const_alloc_recursive<
326334 while let Some ( alloc_id) = todo. pop ( ) {
327335 if let Some ( ( _, mut alloc) ) = ecx. memory . alloc_map . remove ( & alloc_id) {
328336 // 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
330338 // and interning everything with a simple `intern_shallow` loop.
331339 match intern_kind {
332340 // Statics may point to mutable allocations.
0 commit comments