Skip to content

Commit

Permalink
Rollup merge of rust-lang#44157 - alexcrichton:no-specializes-cache, …
Browse files Browse the repository at this point in the history
…r=eddyb

rustc: Remove `specialization_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!

cc rust-lang#44137
  • Loading branch information
Ariel Ben-Yehuda authored Aug 29, 2017
2 parents 3159cee + 27c4ff6 commit df7d744
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 21 deletions.
1 change: 1 addition & 0 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
};
}
Expand All @@ -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
};
}
3 changes: 1 addition & 2 deletions src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
Expand Down
18 changes: 6 additions & 12 deletions src/librustc/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down Expand Up @@ -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 =
Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/traits/specialize/specialization_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
3 changes: 0 additions & 3 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(),
Expand Down
12 changes: 12 additions & 0 deletions src/librustc/ty/maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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 }
}

0 comments on commit df7d744

Please sign in to comment.