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;
&& 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);
}
}
-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");
}
}
}