diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index b44262416343d1d9338d726374eaef6582cd33da..4600cdbc692e7f37e51bf1d0a510bc346cb6c979 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -506,6 +506,7 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool { [] SpecializationGraph(DefId), [] ObjectSafety(DefId), [] FulfillObligation { param_env: ParamEnv<'tcx>, trait_ref: PolyTraitRef<'tcx> }, + [] VtableMethods { trait_ref: PolyTraitRef<'tcx> }, [] IsCopy { param_env: ParamEnvAnd<'tcx, Ty<'tcx>> }, [] IsSized { param_env: ParamEnvAnd<'tcx, Ty<'tcx>> }, diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index b58ffd4c7b8f23b6e6147f984030c3cf1f59f172..8da0f8f13ff815f358a6cd9ed9bf9004817c022f 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -650,12 +650,12 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, /// Given a trait `trait_ref`, iterates the vtable entries /// that come from `trait_ref`, including its supertraits. #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait. -pub fn get_vtable_methods<'a, 'tcx>( +pub fn vtable_methods<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) -> Vec)>> { - debug!("get_vtable_methods({:?})", trait_ref); + debug!("vtable_methods({:?})", trait_ref); supertraits(tcx, trait_ref).flat_map(move |trait_ref| { let trait_methods = tcx.associated_items(trait_ref.def_id()) @@ -664,12 +664,12 @@ pub fn get_vtable_methods<'a, 'tcx>( // Now list each method's DefId and Substs (for within its trait). // If the method can never be called from this object, produce None. trait_methods.map(move |trait_method| { - debug!("get_vtable_methods: trait_method={:?}", trait_method); + debug!("vtable_methods: trait_method={:?}", trait_method); let def_id = trait_method.def_id; // Some methods cannot be called on an object; skip those. if !tcx.is_vtable_safe_method(trait_ref.def_id(), &trait_method) { - debug!("get_vtable_methods: not vtable safe"); + debug!("vtable_methods: not vtable safe"); return None; } @@ -690,7 +690,7 @@ pub fn get_vtable_methods<'a, 'tcx>( // do not want to try and trans it, in that case (see #23435). let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs); if !normalize_and_test_predicates(tcx, predicates.predicates) { - debug!("get_vtable_methods: predicates do not hold"); + debug!("vtable_methods: predicates do not hold"); return None; } @@ -836,6 +836,7 @@ pub fn provide(providers: &mut ty::maps::Providers) { specialization_graph_of: specialize::specialization_graph_provider, specializes: specialize::specializes, trans_fulfill_obligation: trans::trans_fulfill_obligation, + vtable_methods, ..*providers }; } @@ -846,6 +847,7 @@ pub fn provide_extern(providers: &mut ty::maps::Providers) { specialization_graph_of: specialize::specialization_graph_provider, specializes: specialize::specializes, trans_fulfill_obligation: trans::trans_fulfill_obligation, + vtable_methods, ..*providers }; } diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index dee1516e0f8b310efe16cee10b13ef4895765e99..137039598a55b5601ca6b7d887d6f740d0fd760f 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -503,6 +503,12 @@ fn describe(_tcx: TyCtxt, _: CrateNum) -> String { } } +impl<'tcx> QueryDescription for queries::vtable_methods<'tcx> { + fn describe(tcx: TyCtxt, key: ty::PolyTraitRef<'tcx> ) -> String { + format!("finding all methods for trait {}", tcx.item_path_str(key.def_id())) + } +} + impl<'tcx> QueryDescription for queries::has_copy_closures<'tcx> { fn describe(_tcx: TyCtxt, _: CrateNum) -> String { format!("seeing if the crate has enabled `Copy` closures") diff --git a/src/librustc/ty/maps/keys.rs b/src/librustc/ty/maps/keys.rs index 1bd4f3e657eb0260d632b263266927d4b4b43243..ee4523d6f3e1ef8b148cc4c7605a9e54cfd041f1 100644 --- a/src/librustc/ty/maps/keys.rs +++ b/src/librustc/ty/maps/keys.rs @@ -143,6 +143,15 @@ fn default_span(&self, tcx: TyCtxt) -> Span { } } +impl<'tcx> Key for ty::PolyTraitRef<'tcx>{ + fn map_crate(&self) -> CrateNum { + self.def_id().krate + } + fn default_span(&self, tcx: TyCtxt) -> Span { + tcx.def_span(self.def_id()) + } +} + impl<'tcx> Key for Ty<'tcx> { fn map_crate(&self) -> CrateNum { LOCAL_CRATE diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs index 2001de88803aa233ced8fe63e65513fc50067f68..872069d381b9be57b59cb494e1c9e70e895eee0d 100644 --- a/src/librustc/ty/maps/mod.rs +++ b/src/librustc/ty/maps/mod.rs @@ -228,6 +228,8 @@ [] fn item_body_nested_bodies: ItemBodyNestedBodies(DefId) -> ExternBodyNestedBodies, [] fn const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool, [] fn is_mir_available: IsMirAvailable(DefId) -> bool, + [] fn vtable_methods: vtable_methods_node(ty::PolyTraitRef<'tcx>) + -> Vec)>>, [] fn trans_fulfill_obligation: fulfill_obligation_dep_node( (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)) -> Vtable<'tcx, ()>, @@ -470,3 +472,7 @@ fn collect_and_partition_translation_items_node<'tcx>(_: CrateNum) -> DepConstru fn output_filenames_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { DepConstructor::OutputFilenames } + +fn vtable_methods_node<'tcx>(trait_ref: ty::PolyTraitRef<'tcx>) -> DepConstructor<'tcx> { + DepConstructor::VtableMethods{ trait_ref } +} diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs index 61355381761091effa681331470e1f214faf2252..462149c2ed8e5d9ed576c99ff0c580c34804a688 100644 --- a/src/librustc/ty/maps/plumbing.rs +++ b/src/librustc/ty/maps/plumbing.rs @@ -749,6 +749,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>, DepKind::CodegenUnit | DepKind::CompileCodegenUnit | DepKind::FulfillObligation | + DepKind::VtableMethods | // These are just odd DepKind::Null | diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 835283aa09b4fee92c45665c4d0d00542f2f8efd..084787000016ea64fa640236bf51aeec1223c401 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -849,7 +849,7 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, assert!(!poly_trait_ref.has_escaping_regions()); // Walk all methods of the trait, including those of its supertraits - let methods = traits::get_vtable_methods(tcx, poly_trait_ref); + let methods = tcx.vtable_methods(poly_trait_ref); let methods = methods.into_iter().filter_map(|method| method) .map(|(def_id, substs)| ty::Instance::resolve( tcx, diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index 72f580c2d3867f14590e7cf58baf16d2f0c95436..66d633cf9a1f1ced5a634d64fb41367b2349a2ae 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -9,7 +9,6 @@ // except according to those terms. use llvm::ValueRef; -use rustc::traits; use callee; use common::*; use builder::Builder; @@ -87,7 +86,7 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, if let Some(trait_ref) = trait_ref { let trait_ref = trait_ref.with_self_ty(tcx, ty); - let methods = traits::get_vtable_methods(tcx, trait_ref).into_iter().map(|opt_mth| { + let methods = tcx.vtable_methods(trait_ref).into_iter().map(|opt_mth| { opt_mth.map_or(nullptr, |(def_id, substs)| { callee::resolve_and_get_fn(ccx, def_id, substs) })