Skip to content

Commit 27c4ff6

Browse files
committed
rustc: Remove specailization_cache in favor of a query
This commit removes the `specialization_cache` field of `TyCtxt` by moving it to a dedicated query, which it turned out was already quite easily structured to do so!
1 parent faf477a commit 27c4ff6

File tree

7 files changed

+26
-21
lines changed

7 files changed

+26
-21
lines changed

src/librustc/dep_graph/dep_node.rs

+1
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ define_dep_nodes!( <'tcx>
527527
[] HasGlobalAllocator(DefId),
528528
[] ExternCrate(DefId),
529529
[] LintLevels,
530+
[] Specializes { impl1: DefId, impl2: DefId },
530531
);
531532

532533
trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {

src/librustc/traits/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ pub use self::project::{ProjectionCache, ProjectionCacheSnapshot, Reveal};
3838
pub use self::object_safety::ObjectSafetyViolation;
3939
pub use self::object_safety::MethodViolationCode;
4040
pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
41-
pub use self::specialize::{OverlapError, specialization_graph, specializes, translate_substs};
41+
pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
4242
pub use self::specialize::{SpecializesCache, find_associated_item};
4343
pub use self::util::elaborate_predicates;
4444
pub use self::util::supertraits;
@@ -831,6 +831,7 @@ pub fn provide(providers: &mut ty::maps::Providers) {
831831
*providers = ty::maps::Providers {
832832
is_object_safe: object_safety::is_object_safe_provider,
833833
specialization_graph_of: specialize::specialization_graph_provider,
834+
specializes: specialize::specializes,
834835
..*providers
835836
};
836837
}
@@ -839,6 +840,7 @@ pub fn provide_extern(providers: &mut ty::maps::Providers) {
839840
*providers = ty::maps::Providers {
840841
is_object_safe: object_safety::is_object_safe_provider,
841842
specialization_graph_of: specialize::specialization_graph_provider,
843+
specializes: specialize::specializes,
842844
..*providers
843845
};
844846
}

src/librustc/traits/select.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ use infer;
3636
use infer::{InferCtxt, InferOk, TypeFreshener};
3737
use ty::subst::{Kind, Subst, Substs};
3838
use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
39-
use traits;
4039
use ty::fast_reject;
4140
use ty::relate::TypeRelation;
4241
use middle::lang_items;
@@ -1927,7 +1926,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
19271926
if other.evaluation == EvaluatedToOk {
19281927
if let ImplCandidate(victim_def) = victim.candidate {
19291928
let tcx = self.tcx().global_tcx();
1930-
return traits::specializes(tcx, other_def, victim_def) ||
1929+
return tcx.specializes((other_def, victim_def)) ||
19311930
tcx.impls_are_allowed_to_overlap(other_def, victim_def);
19321931
}
19331932
}

src/librustc/traits/specialize/mod.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,12 @@ pub fn find_associated_item<'a, 'tcx>(
150150
/// Specialization is determined by the sets of types to which the impls apply;
151151
/// impl1 specializes impl2 if it applies to a subset of the types impl2 applies
152152
/// to.
153-
pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
154-
impl1_def_id: DefId,
155-
impl2_def_id: DefId) -> bool {
153+
pub(super) fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
154+
(impl1_def_id, impl2_def_id): (DefId, DefId))
155+
-> bool
156+
{
156157
debug!("specializes({:?}, {:?})", impl1_def_id, impl2_def_id);
157158

158-
if let Some(r) = tcx.specializes_cache.borrow().check(impl1_def_id, impl2_def_id) {
159-
return r;
160-
}
161-
162159
// The feature gate should prevent introducing new specializations, but not
163160
// taking advantage of upstream ones.
164161
if !tcx.sess.features.borrow().specialization &&
@@ -188,7 +185,7 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
188185
let impl1_trait_ref = tcx.impl_trait_ref(impl1_def_id).unwrap();
189186

190187
// Create a infcx, taking the predicates of impl1 as assumptions:
191-
let result = tcx.infer_ctxt().enter(|infcx| {
188+
tcx.infer_ctxt().enter(|infcx| {
192189
// Normalize the trait reference. The WF rules ought to ensure
193190
// that this always succeeds.
194191
let impl1_trait_ref =
@@ -204,10 +201,7 @@ pub fn specializes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
204201

205202
// Attempt to prove that impl2 applies, given all of the above.
206203
fulfill_implication(&infcx, penv, impl1_trait_ref, impl2_def_id).is_ok()
207-
});
208-
209-
tcx.specializes_cache.borrow_mut().insert(impl1_def_id, impl2_def_id, result);
210-
result
204+
})
211205
}
212206

213207
/// Attempt to fulfill all obligations of `target_impl` after unification with

src/librustc/traits/specialize/specialization_graph.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use super::{OverlapError, specializes};
11+
use super::OverlapError;
1212

1313
use hir::def_id::DefId;
1414
use traits;
@@ -118,8 +118,8 @@ impl<'a, 'gcx, 'tcx> Children {
118118
return Ok((false, false));
119119
}
120120

121-
let le = specializes(tcx, impl_def_id, possible_sibling);
122-
let ge = specializes(tcx, possible_sibling, impl_def_id);
121+
let le = tcx.specializes((impl_def_id, possible_sibling));
122+
let ge = tcx.specializes((possible_sibling, impl_def_id));
123123

124124
if le == ge {
125125
// overlap, but no specialization; error out

src/librustc/ty/context.rs

-3
Original file line numberDiff line numberDiff line change
@@ -808,8 +808,6 @@ pub struct GlobalCtxt<'tcx> {
808808

809809
pub sess: &'tcx Session,
810810

811-
pub specializes_cache: RefCell<traits::SpecializesCache>,
812-
813811
pub trans_trait_caches: traits::trans::TransTraitCaches<'tcx>,
814812

815813
pub dep_graph: DepGraph,
@@ -1072,7 +1070,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
10721070
tls::enter_global(GlobalCtxt {
10731071
sess: s,
10741072
trans_trait_caches: traits::trans::TransTraitCaches::new(dep_graph.clone()),
1075-
specializes_cache: RefCell::new(traits::SpecializesCache::new()),
10761073
global_arenas: arenas,
10771074
global_interners: interners,
10781075
dep_graph: dep_graph.clone(),

src/librustc/ty/maps.rs

+12
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,12 @@ impl<'tcx> QueryDescription for queries::lint_levels<'tcx> {
540540
}
541541
}
542542

543+
impl<'tcx> QueryDescription for queries::specializes<'tcx> {
544+
fn describe(_tcx: TyCtxt, _: (DefId, DefId)) -> String {
545+
format!("computing whether impls specialize one another")
546+
}
547+
}
548+
543549
// If enabled, send a message to the profile-queries thread
544550
macro_rules! profq_msg {
545551
($tcx:expr, $msg:expr) => {
@@ -1108,6 +1114,8 @@ define_maps! { <'tcx>
11081114
[] extern_crate: ExternCrate(DefId) -> Rc<Option<ExternCrate>>,
11091115

11101116
[] lint_levels: lint_levels(CrateNum) -> Rc<lint::LintLevelMap>,
1117+
1118+
[] specializes: specializes_node((DefId, DefId)) -> bool,
11111119
}
11121120

11131121
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<'
11831191
fn lint_levels<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
11841192
DepConstructor::LintLevels
11851193
}
1194+
1195+
fn specializes_node<'tcx>((a, b): (DefId, DefId)) -> DepConstructor<'tcx> {
1196+
DepConstructor::Specializes { impl1: a, impl2: b }
1197+
}

0 commit comments

Comments
 (0)