It is pretty suspect to insert an entry twice.
self.map.get(k)
}
- pub fn get_mut(&mut self, k: &M::Key) -> Option<&mut M::Value> {
- self.read(k);
- self.write(k);
- self.map.get_mut(k)
- }
-
- pub fn insert(&mut self, k: M::Key, v: M::Value) -> Option<M::Value> {
+ pub fn insert(&mut self, k: M::Key, v: M::Value) {
self.write(&k);
- self.map.insert(k, v)
+ let _old_value = self.map.insert(k, v);
+ // assert!(old_value.is_none());
}
pub fn contains_key(&self, k: &M::Key) -> bool {
pub fn keys(&self) -> Vec<M::Key> {
self.map.keys().cloned().collect()
}
-
- /// Append `elem` to the vector stored for `k`, creating a new vector if needed.
- /// This is considered a write to `k`.
- pub fn push<E: Clone>(&mut self, k: M::Key, elem: E)
- where M: DepTrackingMapConfig<Value=Vec<E>>
- {
- self.write(&k);
- self.map.entry(k)
- .or_insert(Vec::new())
- .push(elem);
- }
}
impl<M: DepTrackingMapConfig> MemoizationMap for RefCell<DepTrackingMap<M>> {
let mir = tcx.alloc_mir(mir);
let def_id = tcx.hir.local_def_id(src.item_id());
- assert!(tcx.mir_map.borrow_mut().insert(def_id, mir).is_none());
+ tcx.mir_map.borrow_mut().insert(def_id, mir);
});
let body = self.tcx.hir.body(body_id);
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir::{Item, ItemImpl};
use rustc::hir;
+use rustc::util::nodemap::DefIdMap;
mod builtin;
mod orphan;
mod overlap;
mod unsafety;
-struct CoherenceChecker<'a, 'tcx: 'a> {
+struct CoherenceCollect<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ inherent_impls: DefIdMap<Vec<DefId>>,
}
-impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CoherenceChecker<'a, 'tcx> {
+impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CoherenceCollect<'a, 'tcx> {
fn visit_item(&mut self, item: &Item) {
if let ItemImpl(..) = item.node {
self.check_implementation(item)
}
}
-impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
+impl<'a, 'tcx> CoherenceCollect<'a, 'tcx> {
// Returns the def ID of the base type, if there is one.
fn get_base_type_def_id(&self, span: Span, ty: Ty<'tcx>) -> Option<DefId> {
match ty.sty {
// containing the inherent methods and extension methods. It also
// builds up the trait inheritance table.
self.tcx.visit_all_item_likes_in_krate(DepNode::CoherenceCheckImpl, self);
+
+ // Transfer the inherent impl lists, not that they are known, into the tcx
+ for (ty_def_id, impl_def_ids) in self.inherent_impls.drain() {
+ self.tcx.inherent_impls.borrow_mut().insert(ty_def_id, impl_def_ids);
+ }
}
- fn check_implementation(&self, item: &Item) {
+ fn check_implementation(&mut self, item: &Item) {
let tcx = self.tcx;
let impl_did = tcx.hir.local_def_id(item.id);
let self_type = tcx.item_type(impl_did);
}
}
- fn add_inherent_impl(&self, base_def_id: DefId, impl_def_id: DefId) {
- self.tcx.inherent_impls.borrow_mut().push(base_def_id, impl_def_id);
+ fn add_inherent_impl(&mut self, base_def_id: DefId, impl_def_id: DefId) {
+ self.inherent_impls.entry(base_def_id)
+ .or_insert(vec![])
+ .push(impl_def_id);
}
fn add_trait_impl(&self, impl_trait_ref: ty::TraitRef<'tcx>, impl_def_id: DefId) {
pub fn check_coherence(ccx: &CrateCtxt) {
let _task = ccx.tcx.dep_graph.in_task(DepNode::Coherence);
- CoherenceChecker { tcx: ccx.tcx }.check();
+ CoherenceCollect { tcx: ccx.tcx, inherent_impls: DefIdMap() }.check();
unsafety::check(ccx.tcx);
orphan::check(ccx.tcx);
overlap::check(ccx.tcx);
ccx.tcx.item_types.borrow_mut().insert(ty_f.did, tt);
let def_id = ccx.tcx.hir.local_def_id(field.id);
- ccx.tcx.item_types.borrow_mut().insert(def_id, tt);
+ assert_eq!(def_id, ty_f.did);
ccx.tcx.generics.borrow_mut().insert(def_id, struct_generics);
ccx.tcx.predicates.borrow_mut().insert(def_id, struct_predicates.clone());
}
items);
trait_predicates.predicates.extend(assoc_predicates);
- let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
- assert!(prev_predicates.is_none());
-
+ tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
return;
fn predicates_for_associated_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
};
let predicates = ty_generic_predicates(ccx, generics, None, vec![], false);
- let prev_predicates = ccx.tcx.predicates.borrow_mut().insert(def_id,
- predicates.clone());
- assert!(prev_predicates.is_none());
+ ccx.tcx.predicates.borrow_mut().insert(def_id, predicates.clone());
predicates
}
};
let predicates = ty_generic_predicates(ccx, generics, None, vec![], false);
- let prev_predicates = ccx.tcx.predicates.borrow_mut().insert(def_id, predicates);
- assert!(prev_predicates.is_none());
+ ccx.tcx.predicates.borrow_mut().insert(def_id, predicates);
}
// Is it marked with ?Sized
item_variances);
}
- let newly_added = tcx.item_variance_map
- .borrow_mut()
- .insert(item_def_id, Rc::new(item_variances))
- .is_none();
- assert!(newly_added);
+ tcx.item_variance_map
+ .borrow_mut()
+ .insert(item_def_id, Rc::new(item_variances));
}
}
// parameters".
if self.num_inferred() == inferreds_on_entry {
let item_def_id = self.tcx.hir.local_def_id(item_id);
- let newly_added = self.tcx
+ self.tcx
.item_variance_map
.borrow_mut()
- .insert(item_def_id, self.empty_variances.clone())
- .is_none();
- assert!(newly_added);
+ .insert(item_def_id, self.empty_variances.clone());
}
}