about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src/interpret/intern.rs
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-08-02 15:34:59 +0200
committerRalf Jung <post@ralfj.de>2024-09-10 10:26:16 +0200
commitf76f128dc9dea86f52a40d465430a7feddca271a (patch)
tree8be34eea1342aa01c46609f55d78cb4fe64d2352 /compiler/rustc_const_eval/src/interpret/intern.rs
parent304b7f801bab31233680879ca4fb6eb294706a59 (diff)
downloadrust-f76f128dc9dea86f52a40d465430a7feddca271a.tar.gz
rust-f76f128dc9dea86f52a40d465430a7feddca271a.zip
const-eval interning: accpt interior mutable pointers in final value (but keep rejecting mutable references)
Diffstat (limited to 'compiler/rustc_const_eval/src/interpret/intern.rs')
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs18
1 files changed, 11 insertions, 7 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index 8b0a2afa4d6..e81431b45fb 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -223,16 +223,20 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval
             continue;
         }
 
-        // Crucially, we check this *before* checking whether the `alloc_id`
-        // has already been interned. The point of this check is to ensure that when
-        // there are multiple pointers to the same allocation, they are *all* immutable.
-        // Therefore it would be bad if we only checked the first pointer to any given
-        // allocation.
+        // Ensure that this is is derived from a shared reference. Crucially, we check this *before*
+        // checking whether the `alloc_id` has already been interned. The point of this check is to
+        // ensure that when there are multiple pointers to the same allocation, they are *all*
+        // derived from a shared reference. Therefore it would be bad if we only checked the first
+        // pointer to any given allocation.
         // (It is likely not possible to actually have multiple pointers to the same allocation,
         // so alternatively we could also check that and ICE if there are multiple such pointers.)
+        // See <https://github.com/rust-lang/rust/pull/128543> for why we are checking for
+        // "shared reference" and not "immutable", i.e., for why we are allowed interior-mutable
+        // shared references: they can actually be created in safe code while pointing to apparently
+        // "immutable" values, via promotion of `&None::<Cell<T>>`.
         if intern_kind != InternKind::Promoted
             && inner_mutability == Mutability::Not
-            && !prov.immutable()
+            && !prov.shared_ref()
         {
             if ecx.tcx.try_get_global_alloc(alloc_id).is_some()
                 && !just_interned.contains(&alloc_id)
@@ -245,7 +249,7 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval
                 // this to the todo list, since after all it is already interned.
                 continue;
             }
-            // Found a mutable pointer inside a const where inner allocations should be
+            // Found a mutable reference inside a const where inner allocations should be
             // immutable. We exclude promoteds from this, since things like `&mut []` and
             // `&None::<Cell<i32>>` lead to promotion that can produce mutable pointers. We rely
             // on the promotion analysis not screwing up to ensure that it is sound to intern