Simplify get_trait_ref a bit

This commit is contained in:
Michael Goulet 2022-08-29 04:19:14 +00:00
parent 1ea4efd065
commit 72fe79244d

View File

@ -1,6 +1,6 @@
use crate::traits::*;
use rustc_middle::ty::{self, subst::GenericArgKind, ExistentialPredicate, Ty, TyCtxt};
use rustc_middle::ty::{self, subst::GenericArgKind, Ty};
use rustc_session::config::Lto;
use rustc_symbol_mangling::typeid_for_trait_ref;
use rustc_target::abi::call::FnAbi;
@ -29,7 +29,7 @@ impl<'a, 'tcx> VirtualIndex {
&& bx.cx().sess().lto() == Lto::Fat
{
let typeid =
bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), get_trait_ref(bx.tcx(), ty)));
bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), expect_dyn_trait_in_self(ty)));
let vtable_byte_offset = self.0 * bx.data_layout().pointer_size.bytes();
let type_checked_load = bx.type_checked_load(llvtable, vtable_byte_offset, typeid);
let func = bx.extract_value(type_checked_load, 0);
@ -64,17 +64,13 @@ impl<'a, 'tcx> VirtualIndex {
}
}
fn get_trait_ref<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::PolyExistentialTraitRef<'tcx> {
/// This takes a valid `self` receiver type and extracts the principal trait
/// ref of the type.
fn expect_dyn_trait_in_self<'tcx>(ty: Ty<'tcx>) -> ty::PolyExistentialTraitRef<'tcx> {
for arg in ty.peel_refs().walk() {
if let GenericArgKind::Type(ty) = arg.unpack() {
if let ty::Dynamic(trait_refs, _) = ty.kind() {
return trait_refs[0].map_bound(|trait_ref| match trait_ref {
ExistentialPredicate::Trait(tr) => tr,
ExistentialPredicate::Projection(proj) => proj.trait_ref(tcx),
ExistentialPredicate::AutoTrait(_) => {
bug!("auto traits don't have functions")
}
});
if let ty::Dynamic(data, _) = ty.kind() {
return data.principal().expect("expected principal trait object");
}
}
}