diff options
| author | Ralf Jung <post@ralfj.de> | 2024-08-02 15:34:59 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2024-09-10 10:26:16 +0200 |
| commit | f76f128dc9dea86f52a40d465430a7feddca271a (patch) | |
| tree | 8be34eea1342aa01c46609f55d78cb4fe64d2352 /compiler/rustc_const_eval/src/interpret/intern.rs | |
| parent | 304b7f801bab31233680879ca4fb6eb294706a59 (diff) | |
| download | rust-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.rs | 18 |
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 |
