1
Fork 0

separately intern the outermost alloc from the rest

This commit is contained in:
Oli Scherer 2024-01-24 11:46:57 +00:00
parent a73c44889a
commit a57a00ebf6

View file

@ -125,10 +125,11 @@ pub fn intern_const_alloc_recursive<
// Intern the base allocation, and initialize todo list for recursive interning. // Intern the base allocation, and initialize todo list for recursive interning.
let base_alloc_id = ret.ptr().provenance.unwrap().alloc_id(); let base_alloc_id = ret.ptr().provenance.unwrap().alloc_id();
let mut todo = vec![(base_alloc_id, base_mutability)]; let mut todo: Vec<_> =
intern_shallow(ecx, base_alloc_id, base_mutability).unwrap().map(|prov| prov).collect();
// We need to distinguish "has just been interned" from "was already in `tcx`", // We need to distinguish "has just been interned" from "was already in `tcx`",
// so we track this in a separate set. // so we track this in a separate set.
let mut just_interned = FxHashSet::default(); let mut just_interned: FxHashSet<_> = std::iter::once(base_alloc_id).collect();
// Whether we encountered a bad mutable pointer. // Whether we encountered a bad mutable pointer.
// We want to first report "dangling" and then "mutable", so we need to delay reporting these // We want to first report "dangling" and then "mutable", so we need to delay reporting these
// errors. // errors.
@ -142,17 +143,7 @@ pub fn intern_const_alloc_recursive<
// raw pointers, so we cannot rely on validation to catch them -- and since interning runs // raw pointers, so we cannot rely on validation to catch them -- and since interning runs
// before validation, and interning doesn't know the type of anything, this means we can't show // before validation, and interning doesn't know the type of anything, this means we can't show
// better errors. Maybe we should consider doing validation before interning in the future. // better errors. Maybe we should consider doing validation before interning in the future.
while let Some((alloc_id, mutability)) = todo.pop() { while let Some(prov) = todo.pop() {
if ecx.tcx.try_get_global_alloc(alloc_id).is_some() {
// Already interned.
debug_assert!(!ecx.memory.alloc_map.contains_key(&alloc_id));
continue;
}
just_interned.insert(alloc_id);
let provs = intern_shallow(ecx, alloc_id, mutability).map_err(|()| {
ecx.tcx.dcx().emit_err(DanglingPtrInFinal { span: ecx.tcx.span, kind: intern_kind })
})?;
for prov in provs {
let alloc_id = prov.alloc_id(); let alloc_id = prov.alloc_id();
if intern_kind != InternKind::Promoted if intern_kind != InternKind::Promoted
&& inner_mutability == Mutability::Not && inner_mutability == Mutability::Not
@ -176,6 +167,12 @@ pub fn intern_const_alloc_recursive<
// promoteds as immutable. // promoteds as immutable.
found_bad_mutable_pointer = true; found_bad_mutable_pointer = true;
} }
if ecx.tcx.try_get_global_alloc(alloc_id).is_some() {
// Already interned.
debug_assert!(!ecx.memory.alloc_map.contains_key(&alloc_id));
continue;
}
just_interned.insert(alloc_id);
// We always intern with `inner_mutability`, and furthermore we ensured above that if // We always intern with `inner_mutability`, and furthermore we ensured above that if
// that is "immutable", then there are *no* mutable pointers anywhere in the newly // that is "immutable", then there are *no* mutable pointers anywhere in the newly
// interned memory -- justifying that we can indeed intern immutably. However this also // interned memory -- justifying that we can indeed intern immutably. However this also
@ -186,8 +183,9 @@ pub fn intern_const_alloc_recursive<
// pointers before deciding which allocations can be made immutable; but for now we are // pointers before deciding which allocations can be made immutable; but for now we are
// okay with losing some potential for immutability here. This can anyway only affect // okay with losing some potential for immutability here. This can anyway only affect
// `static mut`. // `static mut`.
todo.push((alloc_id, inner_mutability)); todo.extend(intern_shallow(ecx, alloc_id, inner_mutability).map_err(|()| {
} ecx.tcx.dcx().emit_err(DanglingPtrInFinal { span: ecx.tcx.span, kind: intern_kind })
})?);
} }
if found_bad_mutable_pointer { if found_bad_mutable_pointer {
return Err(ecx return Err(ecx