Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit fdc4bd2

Browse files
Do not treat vtable supertraits as distinct when bound with different bound vars
1 parent 37a430e commit fdc4bd2

File tree

18 files changed

+146
-115
lines changed

18 files changed

+146
-115
lines changed

compiler/rustc_codegen_cranelift/src/constant.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,10 @@ pub(crate) fn data_id_for_vtable<'tcx>(
245245
ty: Ty<'tcx>,
246246
trait_ref: Option<Binder<'tcx, ExistentialTraitRef<'tcx>>>,
247247
) -> DataId {
248-
let alloc_id = tcx.vtable_allocation((ty, trait_ref));
248+
let alloc_id = tcx.vtable_allocation((
249+
ty,
250+
trait_ref.map(|principal| tcx.instantiate_bound_regions_with_erased(principal)),
251+
));
249252
data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not)
250253
}
251254

compiler/rustc_codegen_gcc/src/common.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,12 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
234234
GlobalAlloc::VTable(ty, dyn_ty) => {
235235
let alloc = self
236236
.tcx
237-
.global_alloc(self.tcx.vtable_allocation((ty, dyn_ty.principal())))
237+
.global_alloc(self.tcx.vtable_allocation((
238+
ty,
239+
dyn_ty.principal().map(|principal| {
240+
self.tcx.instantiate_bound_regions_with_erased(principal)
241+
}),
242+
)))
238243
.unwrap_memory();
239244
let init = const_alloc_to_gcc(self, alloc);
240245
self.static_addr_of(init, alloc.inner().align, None)

compiler/rustc_codegen_llvm/src/common.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,12 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
312312
GlobalAlloc::VTable(ty, dyn_ty) => {
313313
let alloc = self
314314
.tcx
315-
.global_alloc(self.tcx.vtable_allocation((ty, dyn_ty.principal())))
315+
.global_alloc(self.tcx.vtable_allocation((
316+
ty,
317+
dyn_ty.principal().map(|principal| {
318+
self.tcx.instantiate_bound_regions_with_erased(principal)
319+
}),
320+
)))
316321
.unwrap_memory();
317322
let init = const_alloc_to_llvm(self, alloc, /*static*/ false);
318323
let value = self.static_addr_of(init, alloc.inner().align, None);

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1406,7 +1406,7 @@ fn build_vtable_type_di_node<'ll, 'tcx>(
14061406

14071407
let vtable_entries = if let Some(poly_trait_ref) = poly_trait_ref {
14081408
let trait_ref = poly_trait_ref.with_self_ty(tcx, ty);
1409-
let trait_ref = tcx.erase_regions(trait_ref);
1409+
let trait_ref = tcx.erase_regions(tcx.instantiate_bound_regions_with_erased(trait_ref));
14101410

14111411
tcx.vtable_entries(trait_ref)
14121412
} else {

compiler/rustc_codegen_ssa/src/meth.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,24 +96,28 @@ fn dyn_trait_in_self(ty: Ty<'_>) -> Option<ty::PolyExistentialTraitRef<'_>> {
9696
pub(crate) fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
9797
cx: &Cx,
9898
ty: Ty<'tcx>,
99-
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
99+
poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
100100
) -> Cx::Value {
101101
let tcx = cx.tcx();
102102

103103
// Check the cache.
104-
if let Some(&val) = cx.vtables().borrow().get(&(ty, trait_ref)) {
104+
if let Some(&val) = cx.vtables().borrow().get(&(ty, poly_trait_ref)) {
105105
return val;
106106
}
107107

108+
// FIXME(trait_upcasting): Take a non-higher-ranked vtable as arg.
109+
let trait_ref =
110+
poly_trait_ref.map(|trait_ref| tcx.instantiate_bound_regions_with_erased(trait_ref));
111+
108112
let vtable_alloc_id = tcx.vtable_allocation((ty, trait_ref));
109113
let vtable_allocation = tcx.global_alloc(vtable_alloc_id).unwrap_memory();
110114
let vtable_const = cx.const_data_from_alloc(vtable_allocation);
111115
let align = cx.data_layout().pointer_align.abi;
112116
let vtable = cx.static_addr_of(vtable_const, align, Some("vtable"));
113117

114-
cx.apply_vcall_visibility_metadata(ty, trait_ref, vtable);
115-
cx.create_vtable_debuginfo(ty, trait_ref, vtable);
116-
cx.vtables().borrow_mut().insert((ty, trait_ref), vtable);
118+
cx.apply_vcall_visibility_metadata(ty, poly_trait_ref, vtable);
119+
cx.create_vtable_debuginfo(ty, poly_trait_ref, vtable);
120+
cx.vtables().borrow_mut().insert((ty, poly_trait_ref), vtable);
117121
vtable
118122
}
119123

compiler/rustc_const_eval/src/interpret/cast.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
419419
self.tcx.supertrait_vtable_slot((src_pointee_ty, dest_pointee_ty));
420420
let vtable_entries = self.vtable_entries(data_a.principal(), ty);
421421
if let Some(entry_idx) = vptr_entry_idx {
422-
let Some(&ty::VtblEntry::TraitVPtr(upcast_trait_ref)) =
423-
vtable_entries.get(entry_idx)
422+
let Some(&ty::VtblEntry::TraitVPtr(_)) = vtable_entries.get(entry_idx)
424423
else {
425424
span_bug!(
426425
self.cur_span(),
@@ -429,13 +428,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
429428
dest_pointee_ty
430429
);
431430
};
432-
let erased_trait_ref = upcast_trait_ref
433-
.map_bound(|r| ty::ExistentialTraitRef::erase_self_ty(*self.tcx, r));
434-
assert!(
435-
data_b
436-
.principal()
437-
.is_some_and(|b| self.eq_in_param_env(erased_trait_ref, b))
438-
);
439431
} else {
440432
// In this case codegen would keep using the old vtable. We don't want to do
441433
// that as it has the wrong trait. The reason codegen can do this is that

compiler/rustc_const_eval/src/interpret/traits.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
5454
) -> &'tcx [VtblEntry<'tcx>] {
5555
if let Some(trait_) = trait_ {
5656
let trait_ref = trait_.with_self_ty(*self.tcx, dyn_ty);
57-
let trait_ref = self.tcx.erase_regions(trait_ref);
57+
let trait_ref =
58+
self.tcx.erase_regions(self.tcx.instantiate_bound_regions_with_erased(trait_ref));
5859
self.tcx.vtable_entries(trait_ref)
5960
} else {
6061
TyCtxt::COMMON_VTABLE_ENTRIES

compiler/rustc_hir_analysis/src/collect/dump.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
123123
);
124124
continue;
125125
};
126-
tcx.vtable_entries(ty::Binder::dummy(trait_ref))
126+
tcx.vtable_entries(trait_ref)
127127
}
128128
hir::ItemKind::TyAlias(_, _) => {
129129
let ty = tcx.type_of(def_id).instantiate_identity();
@@ -149,7 +149,7 @@ pub(crate) fn vtables<'tcx>(tcx: TyCtxt<'tcx>) {
149149
};
150150
if let Some(principal) = data.principal() {
151151
tcx.vtable_entries(
152-
principal.map_bound(|principal| principal.with_self_ty(tcx, ty)),
152+
tcx.instantiate_bound_regions_with_erased(principal).with_self_ty(tcx, ty),
153153
)
154154
} else {
155155
TyCtxt::COMMON_VTABLE_ENTRIES

compiler/rustc_middle/src/query/keys.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
9595
}
9696
}
9797

98-
impl<'tcx> Key for (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>) {
98+
impl<'tcx> Key for (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>) {
9999
type Cache<V> = DefaultCache<Self, V>;
100100

101101
fn default_span(&self, _: TyCtxt<'_>) -> Span {

compiler/rustc_middle/src/query/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,9 +1437,9 @@ rustc_queries! {
14371437
desc { |tcx| "finding all existential vtable entries for trait `{}`", tcx.def_path_str(key) }
14381438
}
14391439

1440-
query vtable_entries(key: ty::PolyTraitRef<'tcx>)
1440+
query vtable_entries(key: ty::TraitRef<'tcx>)
14411441
-> &'tcx [ty::VtblEntry<'tcx>] {
1442-
desc { |tcx| "finding all vtable entries for trait `{}`", tcx.def_path_str(key.def_id()) }
1442+
desc { |tcx| "finding all vtable entries for trait `{}`", tcx.def_path_str(key.def_id) }
14431443
}
14441444

14451445
query first_method_vtable_slot(key: ty::TraitRef<'tcx>) -> usize {
@@ -1451,7 +1451,7 @@ rustc_queries! {
14511451
key.1, key.0 }
14521452
}
14531453

1454-
query vtable_allocation(key: (Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>)) -> mir::interpret::AllocId {
1454+
query vtable_allocation(key: (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>)) -> mir::interpret::AllocId {
14551455
desc { |tcx| "vtable const allocation for <{} as {}>",
14561456
key.0,
14571457
key.1.map(|trait_ref| format!("{trait_ref}")).unwrap_or("_".to_owned())

0 commit comments

Comments
 (0)