diff options
Diffstat (limited to 'compiler/rustc_ty_utils/src/instance.rs')
| -rw-r--r-- | compiler/rustc_ty_utils/src/instance.rs | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 094903f61d4..fcd808b5946 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -213,13 +213,23 @@ fn resolve_associated_item<'tcx>( Some(ty::Instance::new(leaf_def.item.def_id, args)) } - traits::ImplSource::Builtin(BuiltinImplSource::Object { vtable_base }, _) => { - traits::get_vtable_index_of_object_method(tcx, *vtable_base, trait_item_id).map( - |index| Instance { - def: ty::InstanceDef::Virtual(trait_item_id, index), + traits::ImplSource::Builtin(BuiltinImplSource::Object(_), _) => { + let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_args); + if trait_ref.has_non_region_infer() || trait_ref.has_non_region_param() { + // We only resolve totally substituted vtable entries. + None + } else { + let vtable_base = tcx.first_method_vtable_slot(trait_ref); + let offset = tcx + .own_existential_vtable_entries(trait_id) + .iter() + .copied() + .position(|def_id| def_id == trait_item_id); + offset.map(|offset| Instance { + def: ty::InstanceDef::Virtual(trait_item_id, vtable_base + offset), args: rcvr_args, - }, - ) + }) + } } traits::ImplSource::Builtin(BuiltinImplSource::Misc, _) => { if tcx.is_lang_item(trait_ref.def_id, LangItem::Clone) { |
