mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-22 13:34:47 +00:00
Wrap vtable_methods return type in RC
This commit is contained in:
parent
b640c2b95a
commit
81f9d4e78f
@ -653,50 +653,52 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
pub fn vtable_methods<'a, 'tcx>(
|
pub fn vtable_methods<'a, 'tcx>(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>)
|
trait_ref: ty::PolyTraitRef<'tcx>)
|
||||||
-> Vec<Option<(DefId, &'tcx Substs<'tcx>)>>
|
-> Rc<Vec<Option<(DefId, &'tcx Substs<'tcx>)>>>
|
||||||
{
|
{
|
||||||
debug!("vtable_methods({:?})", trait_ref);
|
debug!("vtable_methods({:?})", trait_ref);
|
||||||
|
|
||||||
supertraits(tcx, trait_ref).flat_map(move |trait_ref| {
|
Rc::new(
|
||||||
let trait_methods = tcx.associated_items(trait_ref.def_id())
|
supertraits(tcx, trait_ref).flat_map(move |trait_ref| {
|
||||||
.filter(|item| item.kind == ty::AssociatedKind::Method);
|
let trait_methods = tcx.associated_items(trait_ref.def_id())
|
||||||
|
.filter(|item| item.kind == ty::AssociatedKind::Method);
|
||||||
|
|
||||||
// Now list each method's DefId and Substs (for within its trait).
|
// Now list each method's DefId and Substs (for within its trait).
|
||||||
// If the method can never be called from this object, produce None.
|
// If the method can never be called from this object, produce None.
|
||||||
trait_methods.map(move |trait_method| {
|
trait_methods.map(move |trait_method| {
|
||||||
debug!("vtable_methods: trait_method={:?}", trait_method);
|
debug!("vtable_methods: trait_method={:?}", trait_method);
|
||||||
let def_id = trait_method.def_id;
|
let def_id = trait_method.def_id;
|
||||||
|
|
||||||
// Some methods cannot be called on an object; skip those.
|
// Some methods cannot be called on an object; skip those.
|
||||||
if !tcx.is_vtable_safe_method(trait_ref.def_id(), &trait_method) {
|
if !tcx.is_vtable_safe_method(trait_ref.def_id(), &trait_method) {
|
||||||
debug!("vtable_methods: not vtable safe");
|
debug!("vtable_methods: not vtable safe");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the method may have some early-bound lifetimes, add
|
// the method may have some early-bound lifetimes, add
|
||||||
// regions for those
|
// regions for those
|
||||||
let substs = Substs::for_item(tcx, def_id,
|
let substs = Substs::for_item(tcx, def_id,
|
||||||
|_, _| tcx.types.re_erased,
|
|_, _| tcx.types.re_erased,
|
||||||
|def, _| trait_ref.substs().type_for_def(def));
|
|def, _| trait_ref.substs().type_for_def(def));
|
||||||
|
|
||||||
// the trait type may have higher-ranked lifetimes in it;
|
// the trait type may have higher-ranked lifetimes in it;
|
||||||
// so erase them if they appear, so that we get the type
|
// so erase them if they appear, so that we get the type
|
||||||
// at some particular call site
|
// at some particular call site
|
||||||
let substs = tcx.erase_late_bound_regions_and_normalize(&ty::Binder(substs));
|
let substs = tcx.erase_late_bound_regions_and_normalize(&ty::Binder(substs));
|
||||||
|
|
||||||
// It's possible that the method relies on where clauses that
|
// It's possible that the method relies on where clauses that
|
||||||
// do not hold for this particular set of type parameters.
|
// do not hold for this particular set of type parameters.
|
||||||
// Note that this method could then never be called, so we
|
// Note that this method could then never be called, so we
|
||||||
// do not want to try and trans it, in that case (see #23435).
|
// do not want to try and trans it, in that case (see #23435).
|
||||||
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
|
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
|
||||||
if !normalize_and_test_predicates(tcx, predicates.predicates) {
|
if !normalize_and_test_predicates(tcx, predicates.predicates) {
|
||||||
debug!("vtable_methods: predicates do not hold");
|
debug!("vtable_methods: predicates do not hold");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some((def_id, substs))
|
Some((def_id, substs))
|
||||||
})
|
})
|
||||||
}).collect()
|
}).collect()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx,O> Obligation<'tcx,O> {
|
impl<'tcx,O> Obligation<'tcx,O> {
|
||||||
|
@ -229,7 +229,7 @@ define_maps! { <'tcx>
|
|||||||
[] fn const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool,
|
[] fn const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool,
|
||||||
[] fn is_mir_available: IsMirAvailable(DefId) -> bool,
|
[] fn is_mir_available: IsMirAvailable(DefId) -> bool,
|
||||||
[] fn vtable_methods: vtable_methods_node(ty::PolyTraitRef<'tcx>)
|
[] fn vtable_methods: vtable_methods_node(ty::PolyTraitRef<'tcx>)
|
||||||
-> Vec<Option<(DefId, &'tcx Substs<'tcx>)>>,
|
-> Rc<Vec<Option<(DefId, &'tcx Substs<'tcx>)>>>,
|
||||||
|
|
||||||
[] fn trans_fulfill_obligation: fulfill_obligation_dep_node(
|
[] fn trans_fulfill_obligation: fulfill_obligation_dep_node(
|
||||||
(ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> Vtable<'tcx, ()>,
|
(ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> Vtable<'tcx, ()>,
|
||||||
|
@ -850,7 +850,7 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
|
|
||||||
// Walk all methods of the trait, including those of its supertraits
|
// Walk all methods of the trait, including those of its supertraits
|
||||||
let methods = tcx.vtable_methods(poly_trait_ref);
|
let methods = tcx.vtable_methods(poly_trait_ref);
|
||||||
let methods = methods.into_iter().filter_map(|method| method)
|
let methods = methods.iter().cloned().filter_map(|method| method)
|
||||||
.map(|(def_id, substs)| ty::Instance::resolve(
|
.map(|(def_id, substs)| ty::Instance::resolve(
|
||||||
tcx,
|
tcx,
|
||||||
ty::ParamEnv::empty(traits::Reveal::All),
|
ty::ParamEnv::empty(traits::Reveal::All),
|
||||||
|
@ -86,7 +86,8 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||||||
|
|
||||||
if let Some(trait_ref) = trait_ref {
|
if let Some(trait_ref) = trait_ref {
|
||||||
let trait_ref = trait_ref.with_self_ty(tcx, ty);
|
let trait_ref = trait_ref.with_self_ty(tcx, ty);
|
||||||
let methods = tcx.vtable_methods(trait_ref).into_iter().map(|opt_mth| {
|
let methods = tcx.vtable_methods(trait_ref);
|
||||||
|
let methods = methods.iter().cloned().map(|opt_mth| {
|
||||||
opt_mth.map_or(nullptr, |(def_id, substs)| {
|
opt_mth.map_or(nullptr, |(def_id, substs)| {
|
||||||
callee::resolve_and_get_fn(ccx, def_id, substs)
|
callee::resolve_and_get_fn(ccx, def_id, substs)
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user