Simplify get_trait_ref a bit
This commit is contained in:
parent
1ea4efd065
commit
72fe79244d
1 changed files with 7 additions and 11 deletions
|
@ -1,6 +1,6 @@
|
||||||
use crate::traits::*;
|
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_session::config::Lto;
|
||||||
use rustc_symbol_mangling::typeid_for_trait_ref;
|
use rustc_symbol_mangling::typeid_for_trait_ref;
|
||||||
use rustc_target::abi::call::FnAbi;
|
use rustc_target::abi::call::FnAbi;
|
||||||
|
@ -29,7 +29,7 @@ impl<'a, 'tcx> VirtualIndex {
|
||||||
&& bx.cx().sess().lto() == Lto::Fat
|
&& bx.cx().sess().lto() == Lto::Fat
|
||||||
{
|
{
|
||||||
let typeid =
|
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 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 type_checked_load = bx.type_checked_load(llvtable, vtable_byte_offset, typeid);
|
||||||
let func = bx.extract_value(type_checked_load, 0);
|
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() {
|
for arg in ty.peel_refs().walk() {
|
||||||
if let GenericArgKind::Type(ty) = arg.unpack() {
|
if let GenericArgKind::Type(ty) = arg.unpack() {
|
||||||
if let ty::Dynamic(trait_refs, _) = ty.kind() {
|
if let ty::Dynamic(data, _) = ty.kind() {
|
||||||
return trait_refs[0].map_bound(|trait_ref| match trait_ref {
|
return data.principal().expect("expected principal trait object");
|
||||||
ExistentialPredicate::Trait(tr) => tr,
|
|
||||||
ExistentialPredicate::Projection(proj) => proj.trait_ref(tcx),
|
|
||||||
ExistentialPredicate::AutoTrait(_) => {
|
|
||||||
bug!("auto traits don't have functions")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue