@@ -46,13 +46,12 @@ pub trait CompileTimeMachine<'tcx, T> = Machine<
46
46
pub trait HasStaticRootDefId {
47
47
/// Returns the `DefId` of the static item that is currently being evaluated.
48
48
/// Used for interning to be able to handle nested allocations.
49
- fn static_parent_and_disambiguator(&mut self) -> Option<( LocalDefId, &mut DisambiguatorState) >;
49
+ fn static_def_id(& self) -> Option<LocalDefId>;
50
50
}
51
51
52
52
impl HasStaticRootDefId for const_eval::CompileTimeMachine<'_> {
53
- fn static_parent_and_disambiguator(&mut self) -> Option<(LocalDefId, &mut DisambiguatorState)> {
54
- let (_, static_id, d) = self.static_root_ids.as_mut()?;
55
- Some((*static_id, d))
53
+ fn static_def_id(&self) -> Option<LocalDefId> {
54
+ Some(self.static_root_ids?.1)
56
55
}
57
56
}
58
57
@@ -67,6 +66,7 @@ fn intern_shallow<'tcx, T, M: CompileTimeMachine<'tcx, T>>(
67
66
ecx: &mut InterpCx<'tcx, M>,
68
67
alloc_id: AllocId,
69
68
mutability: Mutability,
69
+ disambiguator: Option<&mut DisambiguatorState>,
70
70
) -> Result<impl Iterator<Item = CtfeProvenance> + 'tcx, ()> {
71
71
trace!("intern_shallow {:?}", alloc_id);
72
72
// remove allocation
@@ -88,8 +88,14 @@ fn intern_shallow<'tcx, T, M: CompileTimeMachine<'tcx, T>>(
88
88
}
89
89
// link the alloc id to the actual allocation
90
90
let alloc = ecx.tcx.mk_const_alloc(alloc);
91
- if let Some((static_id, disambiguator)) = ecx.machine.static_parent_and_disambiguator() {
92
- intern_as_new_static(ecx.tcx, static_id, alloc_id, alloc, disambiguator);
91
+ if let Some(static_id) = ecx.machine.static_def_id() {
92
+ intern_as_new_static(
93
+ ecx.tcx,
94
+ static_id,
95
+ alloc_id,
96
+ alloc,
97
+ disambiguator.expect("disambiguator needed"),
98
+ );
93
99
} else {
94
100
ecx.tcx.set_alloc_id_memory(alloc_id, alloc);
95
101
}
@@ -105,6 +111,10 @@ fn intern_as_new_static<'tcx>(
105
111
alloc: ConstAllocation<'tcx>,
106
112
disambiguator: &mut DisambiguatorState,
107
113
) {
114
+ // `intern_const_alloc_recursive` is called once per static and it contains the `DisambiguatorState`.
115
+ // The `<static_id>::{{nested}}` path is thus unique to `intern_const_alloc_recursive` and the
116
+ // `DisambiguatorState` ensures the generated path is unique for this call as we generate
117
+ // `<static_id>::{{nested#n}}` where `n` is the `n`th `intern_as_new_static` call.
108
118
let feed = tcx.create_def(
109
119
static_id,
110
120
None,
@@ -158,6 +168,8 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval
158
168
intern_kind: InternKind,
159
169
ret: &MPlaceTy<'tcx>,
160
170
) -> Result<(), InternResult> {
171
+ let mut disambiguator = DisambiguatorState::new();
172
+
161
173
// We are interning recursively, and for mutability we are distinguishing the "root" allocation
162
174
// that we are starting in, and all other allocations that we are encountering recursively.
163
175
let (base_mutability, inner_mutability, is_static) = match intern_kind {
@@ -201,7 +213,9 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval
201
213
alloc.1.mutability = base_mutability;
202
214
alloc.1.provenance().ptrs().iter().map(|&(_, prov)| prov).collect()
203
215
} else {
204
- intern_shallow(ecx, base_alloc_id, base_mutability).unwrap().collect()
216
+ intern_shallow(ecx, base_alloc_id, base_mutability, Some(&mut disambiguator))
217
+ .unwrap()
218
+ .collect()
205
219
};
206
220
// We need to distinguish "has just been interned" from "was already in `tcx`",
207
221
// so we track this in a separate set.
@@ -295,7 +309,7 @@ pub fn intern_const_alloc_recursive<'tcx, M: CompileTimeMachine<'tcx, const_eval
295
309
// okay with losing some potential for immutability here. This can anyway only affect
296
310
// `static mut`.
297
311
just_interned.insert(alloc_id);
298
- match intern_shallow(ecx, alloc_id, inner_mutability) {
312
+ match intern_shallow(ecx, alloc_id, inner_mutability, Some(&mut disambiguator) ) {
299
313
Ok(nested) => todo.extend(nested),
300
314
Err(()) => {
301
315
ecx.tcx.dcx().delayed_bug("found dangling pointer during const interning");
@@ -317,8 +331,9 @@ pub fn intern_const_alloc_for_constprop<'tcx, T, M: CompileTimeMachine<'tcx, T>>
317
331
return interp_ok(());
318
332
}
319
333
// Move allocation to `tcx`.
320
- if let Some(_) =
321
- (intern_shallow(ecx, alloc_id, Mutability::Not).map_err(|()| err_ub!(DeadLocal))?).next()
334
+ if let Some(_) = intern_shallow(ecx, alloc_id, Mutability::Not, None)
335
+ .map_err(|()| err_ub!(DeadLocal))?
336
+ .next()
322
337
{
323
338
// We are not doing recursive interning, so we don't currently support provenance.
324
339
// (If this assertion ever triggers, we should just implement a
@@ -344,7 +359,7 @@ impl<'tcx> InterpCx<'tcx, DummyMachine> {
344
359
let dest = self.allocate(layout, MemoryKind::Stack)?;
345
360
f(self, &dest.clone().into())?;
346
361
let alloc_id = dest.ptr().provenance.unwrap().alloc_id(); // this was just allocated, it must have provenance
347
- for prov in intern_shallow(self, alloc_id, Mutability::Not).unwrap() {
362
+ for prov in intern_shallow(self, alloc_id, Mutability::Not, None ).unwrap() {
348
363
// We are not doing recursive interning, so we don't currently support provenance.
349
364
// (If this assertion ever triggers, we should just implement a
350
365
// proper recursive interning loop -- or just call `intern_const_alloc_recursive`.
0 commit comments