about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/dep_graph/dep_node.rs1
-rw-r--r--src/librustc/traits/mod.rs4
-rw-r--r--src/librustc/traits/select.rs3
-rw-r--r--src/librustc/traits/specialize/mod.rs18
-rw-r--r--src/librustc/traits/specialize/specialization_graph.rs6
-rw-r--r--src/librustc/ty/context.rs3
-rw-r--r--src/librustc/ty/maps.rs12
7 files changed, 26 insertions, 21 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 9a80db472db..5114b94571d 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -527,6 +527,7 @@ define_dep_nodes!( <'tcx>
     [] HasGlobalAllocator(DefId),
     [] ExternCrate(DefId),
     [] LintLevels,
+    [] Specializes { impl1: DefId, impl2: DefId },
 );
 
 trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 228c9761756..019f0a70911 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -38,7 +38,7 @@ pub use self::project::{ProjectionCache, ProjectionCacheSnapshot, Reveal};
 pub use self::object_safety::ObjectSafetyViolation;
 pub use self::object_safety::MethodViolationCode;
 pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
-pub use self::specialize::{OverlapError, specialization_graph, specializes, translate_substs};
+pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
 pub use self::specialize::{SpecializesCache, find_associated_item};
 pub use self::util::elaborate_predicates;
 pub use self::util::supertraits;
@@ -831,6 +831,7 @@ pub fn provide(providers: &mut ty::maps::Providers) {
     *providers = ty::maps::Providers {
         is_object_safe: object_safety::is_object_safe_provider,
         specialization_graph_of: specialize::specialization_graph_provider,
+        specializes: specialize::specializes,
         ..*providers
     };
 }
@@ -839,6 +840,7 @@ pub fn provide_extern(providers: &mut ty::maps::Providers) {
     *providers = ty::maps::Providers {
         is_object_safe: object_safety::is_object_safe_provider,
         specialization_graph_of: specialize::specialization_graph_provider,
+        specializes: specialize::specializes,
         ..*providers
     };
 }
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 44b8af3c1df..8856176dcb0 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -36,7 +36,6 @@ use infer;
 use infer::{InferCtxt, InferOk, TypeFreshener};
 use ty::subst::{Kind, Subst, Substs};
 use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
-use traits;
 use ty::fast_reject;
 use ty::relate::TypeRelation;
 use middle::lang_items;
@@ -1927,7 +1926,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                 if other.evaluation == EvaluatedToOk {
                     if let ImplCandidate(victim_def) = victim.candidate {
                         let tcx = self.tcx().global_tcx();
-                        return traits::specializes(tcx, other_def, victim_def) ||
+                        return tcx.specializes((other_def, victim_def)) ||
                             tcx.impls_are_allowed_to_overlap(other_def, victim_def);
                     }
                 }
diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs
index 7c916e162a4..2dd6ca4b5a9 100644
--- a/src/librustc/traits/specialize/mod.rs
+++ b/src/librustc/traits/specialize/mod.rs
@@ -150,15 +150,12 @@ pub fn find_associated_item<'a, 'tcx>(
 /// Specialization is determined by the sets of types to which the impls apply;
 /// impl1 specializes impl2 if it applies to a subset of the types impl2 applies
 /// to.
-pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                             impl1_def_id: DefId,
-                             impl2_def_id: DefId) -> bool {
+pub(super) fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                    (impl1_def_id, impl2_def_id): (DefId, DefId))
+    -> bool
+{
     debug!("specializes({:?}, {:?})", impl1_def_id, impl2_def_id);
 
-    if let Some(r) = tcx.specializes_cache.borrow().check(impl1_def_id, impl2_def_id) {
-        return r;
-    }
-
     // The feature gate should prevent introducing new specializations, but not
     // taking advantage of upstream ones.
     if !tcx.sess.features.borrow().specialization &&
@@ -188,7 +185,7 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id).unwrap();
 
     // Create a infcx, taking the predicates of impl1 as assumptions:
-    let result = tcx.infer_ctxt().enter(|infcx| {
+    tcx.infer_ctxt().enter(|infcx| {
         // Normalize the trait reference. The WF rules ought to ensure
         // that this always succeeds.
         let impl1_trait_ref =
@@ -204,10 +201,7 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
         // Attempt to prove that impl2 applies, given all of the above.
         fulfill_implication(&infcx, penv, impl1_trait_ref, impl2_def_id).is_ok()
-    });
-
-    tcx.specializes_cache.borrow_mut().insert(impl1_def_id, impl2_def_id, result);
-    result
+    })
 }
 
 /// Attempt to fulfill all obligations of `target_impl` after unification with
diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs
index 8b31cb599e4..5242accceab 100644
--- a/src/librustc/traits/specialize/specialization_graph.rs
+++ b/src/librustc/traits/specialize/specialization_graph.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::{OverlapError, specializes};
+use super::OverlapError;
 
 use hir::def_id::DefId;
 use traits;
@@ -118,8 +118,8 @@ impl<'a, 'gcx, 'tcx> Children {
                         return Ok((false, false));
                     }
 
-                    let le = specializes(tcx, impl_def_id, possible_sibling);
-                    let ge = specializes(tcx, possible_sibling, impl_def_id);
+                    let le = tcx.specializes((impl_def_id, possible_sibling));
+                    let ge = tcx.specializes((possible_sibling, impl_def_id));
 
                     if le == ge {
                         // overlap, but no specialization; error out
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 1fe53882c70..1255a9c1f1e 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -808,8 +808,6 @@ pub struct GlobalCtxt<'tcx> {
 
     pub sess: &'tcx Session,
 
-    pub specializes_cache: RefCell<traits::SpecializesCache>,
-
     pub trans_trait_caches: traits::trans::TransTraitCaches<'tcx>,
 
     pub dep_graph: DepGraph,
@@ -1072,7 +1070,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         tls::enter_global(GlobalCtxt {
             sess: s,
             trans_trait_caches: traits::trans::TransTraitCaches::new(dep_graph.clone()),
-            specializes_cache: RefCell::new(traits::SpecializesCache::new()),
             global_arenas: arenas,
             global_interners: interners,
             dep_graph: dep_graph.clone(),
diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs
index 03e093c5a50..c7303c749a4 100644
--- a/src/librustc/ty/maps.rs
+++ b/src/librustc/ty/maps.rs
@@ -540,6 +540,12 @@ impl<'tcx> QueryDescription for queries::lint_levels<'tcx> {
     }
 }
 
+impl<'tcx> QueryDescription for queries::specializes<'tcx> {
+    fn describe(_tcx: TyCtxt, _: (DefId, DefId)) -> String {
+        format!("computing whether impls specialize one another")
+    }
+}
+
 // If enabled, send a message to the profile-queries thread
 macro_rules! profq_msg {
     ($tcx:expr, $msg:expr) => {
@@ -1108,6 +1114,8 @@ define_maps! { <'tcx>
     [] extern_crate: ExternCrate(DefId) -> Rc<Option<ExternCrate>>,
 
     [] lint_levels: lint_levels(CrateNum) -> Rc<lint::LintLevelMap>,
+
+    [] specializes: specializes_node((DefId, DefId)) -> bool,
 }
 
 fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> {
@@ -1183,3 +1191,7 @@ fn layout_dep_node<'tcx>(_: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConstructor<'
 fn lint_levels<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
     DepConstructor::LintLevels
 }
+
+fn specializes_node<'tcx>((a, b): (DefId, DefId)) -> DepConstructor<'tcx> {
+    DepConstructor::Specializes { impl1: a, impl2: b }
+}