-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)Area: Constant evaluation, covers all const contexts (static, const fn, ...)C-bugCategory: This is a bug.Category: This is a bug.F-const_heap`#[feature(const_heap)]``#[feature(const_heap)]`WG-const-evalWorking group: Const evaluationWorking group: Const evaluation
Description
See the following snippet: (currently ICEs)
#![feature(core_intrinsics)]
#![feature(const_heap)]
use std::mem::{align_of, size_of};
use std::intrinsics;
struct SelfReferential {
me: *const SelfReferential,
}
const Y: &'static SelfReferential = unsafe {
let size = size_of::<SelfReferential>();
let align = align_of::<SelfReferential>();
let ptr_raw = intrinsics::const_allocate(size, align);
let ptr = ptr_raw as *mut SelfReferential;
let me_addr = &raw mut (*ptr).me;
*me_addr = ptr;
intrinsics::const_make_global(ptr_raw, size, align);
&*ptr
};
fn main() {}
me
's provenance says it wasn't derived from an immutable reference. We can't really change that because it can't be mutated after we callconst_make_global
.- The fact above hits "accepted a mutable pointer that should not have accepted" at
rust/compiler/rustc_const_eval/src/interpret/intern.rs
Lines 247 to 265 in 040e2f8
// Ensure that this 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 allowing interior-mutable shared // references: they can actually be created in safe code while pointing to apparently // "immutable" values, via promotion or tail expression lifetime extension of // `&None::<Cell<T>>`. // We also exclude promoteds from this as `&mut []` can be promoted, which is a mutable // reference pointing to an immutable (zero-sized) allocation. We rely on the promotion // analysis not screwing up to ensure that it is sound to intern promoteds as immutable. if intern_kind != InternKind::Promoted && inner_mutability == Mutability::Not && !prov.shared_ref() { - We can check if
alloc_id
has kindHeap { was_made_immut: true }
and skip the error that way. intern_shallow
will keep returning alloc2 adding to our todo list being weird left and right. I added a.filter
inrust/compiler/rustc_const_eval/src/interpret/intern.rs
Lines 311 to 312 in 040e2f8
match intern_shallow(ecx, alloc_id, inner_mutability, Some(&mut disambiguator)) { Ok(nested) => todo.extend(nested), just_interned
.- Apparently that wasn't enough and rustc hits an infinite loop at some point. The stack trace isn't helpful enough and I didn't have enough time to find a way to debug the stack overflow.
Originally posted by @fee1-dead in #143595 (comment)
Metadata
Metadata
Assignees
Labels
A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)Area: Constant evaluation, covers all const contexts (static, const fn, ...)C-bugCategory: This is a bug.Category: This is a bug.F-const_heap`#[feature(const_heap)]``#[feature(const_heap)]`WG-const-evalWorking group: Const evaluationWorking group: Const evaluation