Skip to content

Commit a29ae30

Browse files
committed
convert inherent-impl-related things to on-demand queries
There are now 3 queries: - inherent_impls(def-id): for a given type, get a `Rc<Vec<DefId>>` with all its inherent impls. This internally uses `crate_inherent_impls`, doing some hacks to keep the current deps (which, btw, are not clearly correct). - crate_inherent_impls(crate): gathers up a map from types to `Rc<Vec<DefId>>`, touching the entire krate, possibly generating errors. - crate_inherent_impls_overlap_check(crate): performs overlap checks between the inherent impls for a given type, generating errors.
1 parent 8e6b10a commit a29ae30

File tree

11 files changed

+227
-186
lines changed

11 files changed

+227
-186
lines changed

src/librustc/dep_graph/dep_node.rs

-2
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ pub enum DepNode<D: Clone + Debug> {
7474
CoherenceCheckImpl(D),
7575
CoherenceOverlapCheck(D),
7676
CoherenceOverlapCheckSpecial(D),
77-
CoherenceOverlapInherentCheck(D),
7877
CoherenceOrphanCheck(D),
7978
Variance,
8079
WfCheck(D),
@@ -251,7 +250,6 @@ impl<D: Clone + Debug> DepNode<D> {
251250
CoherenceCheckImpl(ref d) => op(d).map(CoherenceCheckImpl),
252251
CoherenceOverlapCheck(ref d) => op(d).map(CoherenceOverlapCheck),
253252
CoherenceOverlapCheckSpecial(ref d) => op(d).map(CoherenceOverlapCheckSpecial),
254-
CoherenceOverlapInherentCheck(ref d) => op(d).map(CoherenceOverlapInherentCheck),
255253
CoherenceOrphanCheck(ref d) => op(d).map(CoherenceOrphanCheck),
256254
WfCheck(ref d) => op(d).map(WfCheck),
257255
TypeckItemType(ref d) => op(d).map(TypeckItemType),

src/librustc/dep_graph/dep_tracking_map.rs

-15
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,6 @@ impl<M: DepTrackingMapConfig> DepTrackingMap<M> {
8181
pub fn keys(&self) -> Vec<M::Key> {
8282
self.map.keys().cloned().collect()
8383
}
84-
85-
/// Append `elem` to the vector stored for `k`, creating a new vector if needed.
86-
/// This is considered a write to `k`.
87-
///
88-
/// NOTE: Caution is required when using this method. You should
89-
/// be sure that nobody is **reading from the vector** while you
90-
/// are writing to it. Eventually, it'd be nice to remove this.
91-
pub fn push<E: Clone>(&mut self, k: M::Key, elem: E)
92-
where M: DepTrackingMapConfig<Value=Vec<E>>
93-
{
94-
self.write(&k);
95-
self.map.entry(k)
96-
.or_insert(Vec::new())
97-
.push(elem);
98-
}
9984
}
10085

10186
impl<M: DepTrackingMapConfig> MemoizationMap for RefCell<DepTrackingMap<M>> {

src/librustc/middle/cstore.rs

-2
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ pub trait CrateStore {
176176
fn item_generics_cloned(&self, def: DefId) -> ty::Generics;
177177
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
178178
fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>;
179-
fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>;
180179

181180
// trait info
182181
fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>;
@@ -310,7 +309,6 @@ impl CrateStore for DummyCrateStore {
310309
{ bug!("item_generics_cloned") }
311310
fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
312311
fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name> { bug!("fn_arg_names") }
313-
fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId> { vec![] }
314312

315313
// trait info
316314
fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId> { vec![] }

src/librustc/ty/maps.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
1212
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
1313
use middle::const_val::ConstVal;
1414
use mir;
15-
use ty::{self, Ty, TyCtxt};
15+
use ty::{self, CrateInherentImpls, Ty, TyCtxt};
1616

1717
use rustc_data_structures::indexed_vec::IndexVec;
1818
use std::cell::{RefCell, RefMut};
@@ -176,9 +176,15 @@ impl<'tcx> QueryDescription for queries::coherent_trait<'tcx> {
176176
}
177177
}
178178

179-
impl<'tcx> QueryDescription for queries::coherent_inherent_impls<'tcx> {
179+
impl<'tcx> QueryDescription for queries::crate_inherent_impls<'tcx> {
180+
fn describe(_: TyCtxt, k: CrateNum) -> String {
181+
format!("all inherent impls defined in crate `{:?}`", k)
182+
}
183+
}
184+
185+
impl<'tcx> QueryDescription for queries::crate_inherent_impls_overlap_check<'tcx> {
180186
fn describe(_: TyCtxt, _: CrateNum) -> String {
181-
format!("coherence checking all inherent impls")
187+
format!("check for overlap between inherent impls defined in this crate")
182188
}
183189
}
184190

@@ -368,7 +374,7 @@ define_maps! { <'tcx>
368374
/// Maps a DefId of a type to a list of its inherent impls.
369375
/// Contains implementations of methods that are inherent to a type.
370376
/// Methods in these implementations don't need to be exported.
371-
pub inherent_impls: InherentImpls(DefId) -> Vec<DefId>,
377+
pub inherent_impls: InherentImpls(DefId) -> Rc<Vec<DefId>>,
372378

373379
/// Maps from the def-id of a function/method or const/static
374380
/// to its MIR. Mutation is done at an item granularity to
@@ -400,7 +406,15 @@ define_maps! { <'tcx>
400406

401407
pub coherent_trait: coherent_trait_dep_node((CrateNum, DefId)) -> (),
402408

403-
pub coherent_inherent_impls: coherent_inherent_impls_dep_node(CrateNum) -> (),
409+
/// Gets a complete map from all types to their inherent impls.
410+
/// Not meant to be used directly outside of coherence.
411+
/// (Defined only for LOCAL_CRATE)
412+
pub crate_inherent_impls: crate_inherent_impls_dep_node(CrateNum) -> CrateInherentImpls,
413+
414+
/// Checks all types in the krate for overlap in their inherent impls. Reports errors.
415+
/// Not meant to be used directly outside of coherence.
416+
/// (Defined only for LOCAL_CRATE)
417+
pub crate_inherent_impls_overlap_check: crate_inherent_impls_dep_node(CrateNum) -> (),
404418

405419
/// Results of evaluating monomorphic constants embedded in
406420
/// other items, such as enum variant explicit discriminants.
@@ -413,7 +427,7 @@ fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode<DefId> {
413427
DepNode::CoherenceCheckTrait(def_id)
414428
}
415429

416-
fn coherent_inherent_impls_dep_node(_: CrateNum) -> DepNode<DefId> {
430+
fn crate_inherent_impls_dep_node(_: CrateNum) -> DepNode<DefId> {
417431
DepNode::Coherence
418432
}
419433

src/librustc/ty/mod.rs

+14-29
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use ty::subst::{Subst, Substs};
3131
use ty::util::IntTypeExt;
3232
use ty::walk::TypeWalker;
3333
use util::common::MemoizationMap;
34-
use util::nodemap::{NodeSet, FxHashMap};
34+
use util::nodemap::{NodeSet, DefIdMap, FxHashMap};
3535

3636
use serialize::{self, Encodable, Encoder};
3737
use std::borrow::Cow;
@@ -2345,34 +2345,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
23452345
def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL)
23462346
}
23472347

2348-
/// Populates the type context with all the inherent implementations for
2349-
/// the given type if necessary.
2350-
pub fn populate_inherent_implementations_for_type_if_necessary(self,
2351-
span: Span,
2352-
type_id: DefId) {
2353-
if type_id.is_local() {
2354-
// Make sure coherence of inherent impls ran already.
2355-
ty::queries::coherent_inherent_impls::force(self, span, LOCAL_CRATE);
2356-
return
2357-
}
2358-
2359-
// The type is not local, hence we are reading this out of
2360-
// metadata and don't need to track edges.
2361-
let _ignore = self.dep_graph.in_ignore();
2362-
2363-
if self.populated_external_types.borrow().contains(&type_id) {
2364-
return
2365-
}
2366-
2367-
debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}",
2368-
type_id);
2369-
2370-
let inherent_impls = self.sess.cstore.inherent_implementations_for_type(type_id);
2371-
2372-
self.maps.inherent_impls.borrow_mut().insert(type_id, inherent_impls);
2373-
self.populated_external_types.borrow_mut().insert(type_id);
2374-
}
2375-
23762348
/// Populates the type context with all the implementations for the given
23772349
/// trait if necessary.
23782350
pub fn populate_implementations_for_trait_if_necessary(self, trait_id: DefId) {
@@ -2637,3 +2609,16 @@ pub fn provide(providers: &mut ty::maps::Providers) {
26372609
..*providers
26382610
};
26392611
}
2612+
2613+
2614+
/// A map for the local crate mapping each type to a vector of its
2615+
/// inherent impls. This is not meant to be used outside of coherence;
2616+
/// rather, you should request the vector for a specific type via
2617+
/// `ty::queries::inherent_impls::get(def_id)` so as to minimize your
2618+
/// dependencies (constructing this map requires touching the entire
2619+
/// crate).
2620+
#[derive(Clone, Debug)]
2621+
pub struct CrateInherentImpls {
2622+
pub inherent_impls: DefIdMap<Rc<Vec<DefId>>>,
2623+
}
2624+

src/librustc_metadata/cstore_impl.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ provide! { <'tcx> tcx, def_id, cdata
109109
typeck_tables => { cdata.item_body_tables(def_id.index, tcx) }
110110
closure_kind => { cdata.closure_kind(def_id.index) }
111111
closure_type => { cdata.closure_ty(def_id.index, tcx) }
112+
inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
112113
}
113114

114115
impl CrateStore for cstore::CStore {
@@ -162,12 +163,6 @@ impl CrateStore for cstore::CStore {
162163
self.get_crate_data(did.krate).get_fn_arg_names(did.index)
163164
}
164165

165-
fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>
166-
{
167-
self.dep_graph.read(DepNode::MetaData(def_id));
168-
self.get_crate_data(def_id.krate).get_inherent_implementations_for_type(def_id.index)
169-
}
170-
171166
fn implementations_of_trait(&self, filter: Option<DefId>) -> Vec<DefId>
172167
{
173168
if let Some(def_id) = filter {

src/librustc_typeck/check/method/probe.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -479,14 +479,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
479479
}
480480

481481
fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: DefId) {
482-
// Read the inherent implementation candidates for this type from the
483-
// metadata if necessary.
484-
self.tcx.populate_inherent_implementations_for_type_if_necessary(self.span, def_id);
485-
486-
if let Some(impl_infos) = self.tcx.maps.inherent_impls.borrow().get(&def_id) {
487-
for &impl_def_id in impl_infos.iter() {
488-
self.assemble_inherent_impl_probe(impl_def_id);
489-
}
482+
let impl_def_ids = ty::queries::inherent_impls::get(self.tcx, self.span, def_id);
483+
for &impl_def_id in impl_def_ids.iter() {
484+
self.assemble_inherent_impl_probe(impl_def_id);
490485
}
491486
}
492487

0 commit comments

Comments
 (0)