From 363a56bd9049bd4bbadea6a566b4ef0b5ac30094 Mon Sep 17 00:00:00 2001 From: Inokentiy Babushkin Date: Sun, 23 Jul 2017 17:29:57 +0200 Subject: [PATCH] Implemented crate tracking mechanism for #17. --- src/semcheck/mapping.rs | 27 +++++++++++++++++++++++++-- src/semcheck/mismatch.rs | 10 +++------- src/semcheck/traverse.rs | 4 ++-- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/semcheck/mapping.rs b/src/semcheck/mapping.rs index 6cbef888a9596..fc26922d8cf82 100644 --- a/src/semcheck/mapping.rs +++ b/src/semcheck/mapping.rs @@ -4,7 +4,7 @@ //! map used to temporarily match up unsorted item sequences' elements by name. use rustc::hir::def::{Def, Export}; -use rustc::hir::def_id::DefId; +use rustc::hir::def_id::{CrateNum, DefId}; use rustc::ty::TypeParameterDef; use std::collections::{BTreeSet, HashMap, VecDeque}; @@ -16,8 +16,11 @@ use syntax::ast::Name; /// Definitions and simple `DefId` mappings are kept separate to record both kinds of /// correspondence losslessly. The *access* to the stored data happens through the same API, /// however. -#[derive(Default)] pub struct IdMapping { + /// The old crate. + old_crate: CrateNum, + /// The new crate. + new_crate: CrateNum, /// Toplevel items' old `DefId` mapped to old and new `Def`. toplevel_mapping: HashMap, /// Trait items' old `DefId` mapped to old and new `Def`. @@ -31,6 +34,18 @@ pub struct IdMapping { } impl IdMapping { + pub fn new(old_crate: CrateNum, new_crate: CrateNum) -> IdMapping { + IdMapping { + old_crate: old_crate, + new_crate: new_crate, + toplevel_mapping: HashMap::new(), + trait_item_mapping: HashMap::new(), + internal_mapping: HashMap::new(), + child_mapping: HashMap::new(), + type_params: HashMap::new(), + } + } + /// Register two exports representing the same item across versions. pub fn add_export(&mut self, old: Def, new: Def) -> bool { if self.toplevel_mapping.contains_key(&old.def_id()) { @@ -132,6 +147,14 @@ impl IdMapping { .get(&parent) .map(|m| m.iter().map(move |old| (*old, self.internal_mapping[old]))) } + + pub fn in_old_crate(&self, did: DefId) -> bool { + self.old_crate == did.krate + } + + pub fn in_new_crate(&self, did: DefId) -> bool { + self.new_crate == did.krate + } } /// A mapping from names to pairs of old and new exports. diff --git a/src/semcheck/mismatch.rs b/src/semcheck/mismatch.rs index 3f03cb9181a21..caf78435f378a 100644 --- a/src/semcheck/mismatch.rs +++ b/src/semcheck/mismatch.rs @@ -4,7 +4,7 @@ //! essentially just renamed instances of the same item (as long as they are both unknown to us //! at the time of analysis). Thus, we may match them up to avoid some false positives. -use rustc::hir::def_id::{CrateNum, DefId}; +use rustc::hir::def_id::DefId; use rustc::ty; use rustc::ty::{Ty, TyCtxt}; use rustc::ty::Visibility::Public; @@ -27,20 +27,17 @@ pub struct Mismatch<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> { item_queue: VecDeque<(DefId, DefId)>, /// The id mapping to use. id_mapping: &'a mut IdMapping, - /// The old crate. - old_crate: CrateNum, } impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> Mismatch<'a, 'gcx, 'tcx> { /// Construct a new mismtach type relation. - pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, old_crate: CrateNum, id_mapping: &'a mut IdMapping) + pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, id_mapping: &'a mut IdMapping) -> Mismatch<'a, 'gcx, 'tcx> { Mismatch { tcx: tcx, item_queue: id_mapping.toplevel_queue(), id_mapping: id_mapping, - old_crate: old_crate, } } @@ -191,8 +188,7 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Mismatch<'a, 'gcx, 'tcx> { }; if let Some((old_def_id, new_def_id)) = matching { - // TODO: implement proper crate tracking and fix this then. - if !self.id_mapping.contains_id(old_def_id) && old_def_id.krate == self.old_crate { + if !self.id_mapping.contains_id(old_def_id) && self.id_mapping.in_old_crate(old_def_id) { self.id_mapping.add_internal_item(old_def_id, new_def_id); self.item_queue.push_back((old_def_id, new_def_id)); } diff --git a/src/semcheck/traverse.rs b/src/semcheck/traverse.rs index 2e5860de44e7d..fc08e411c256b 100644 --- a/src/semcheck/traverse.rs +++ b/src/semcheck/traverse.rs @@ -31,14 +31,14 @@ pub fn run_analysis<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, old: DefId, new: DefI -> ChangeSet<'tcx> { let mut changes = Default::default(); - let mut id_mapping = Default::default(); + let mut id_mapping = IdMapping::new(old.krate, new.krate); // first pass diff_structure(&mut changes, &mut id_mapping, tcx, old, new); // second pass { - let mut mismatch = Mismatch::new(tcx, old.krate, &mut id_mapping); + let mut mismatch = Mismatch::new(tcx, &mut id_mapping); mismatch.process(); }