Skip to content

Commit

Permalink
Implemented crate tracking mechanism for rust-lang#17.
Browse files Browse the repository at this point in the history
  • Loading branch information
ibabushkin committed Jul 23, 2017
1 parent 60ac97f commit 363a56b
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 11 deletions.
27 changes: 25 additions & 2 deletions src/semcheck/mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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<DefId, (Def, Def)>,
/// Trait items' old `DefId` mapped to old and new `Def`.
Expand All @@ -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()) {
Expand Down Expand Up @@ -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.
Expand Down
10 changes: 3 additions & 7 deletions src/semcheck/mismatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
}
}

Expand Down Expand Up @@ -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));
}
Expand Down
4 changes: 2 additions & 2 deletions src/semcheck/traverse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down

0 comments on commit 363a56b

Please sign in to comment.