Skip to content

Commit d594407

Browse files
committedJul 23, 2017
Improved the mapping handling. Closes rust-lang#17.
This uses the newly added crate tracking to make errors more discoverable and code more obvious in it's current behaviour.
1 parent 363a56b commit d594407

File tree

3 files changed

+66
-42
lines changed

3 files changed

+66
-42
lines changed
 

‎src/semcheck/mapping.rs

+49-11
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc::hir::def::{Def, Export};
77
use rustc::hir::def_id::{CrateNum, DefId};
88
use rustc::ty::TypeParameterDef;
99

10-
use std::collections::{BTreeSet, HashMap, VecDeque};
10+
use std::collections::{BTreeSet, HashMap, HashSet, VecDeque};
1111

1212
use syntax::ast::Name;
1313

@@ -23,6 +23,8 @@ pub struct IdMapping {
2323
new_crate: CrateNum,
2424
/// Toplevel items' old `DefId` mapped to old and new `Def`.
2525
toplevel_mapping: HashMap<DefId, (Def, Def)>,
26+
/// The set of toplevel items that have been removed.
27+
removed_items: HashSet<DefId>,
2628
/// Trait items' old `DefId` mapped to old and new `Def`.
2729
trait_item_mapping: HashMap<DefId, (Def, Def, DefId)>,
2830
/// Other items' old `DefId` mapped to new `DefId`.
@@ -39,6 +41,7 @@ impl IdMapping {
3941
old_crate: old_crate,
4042
new_crate: new_crate,
4143
toplevel_mapping: HashMap::new(),
44+
removed_items: HashSet::new(),
4245
trait_item_mapping: HashMap::new(),
4346
internal_mapping: HashMap::new(),
4447
child_mapping: HashMap::new(),
@@ -48,19 +51,30 @@ impl IdMapping {
4851

4952
/// Register two exports representing the same item across versions.
5053
pub fn add_export(&mut self, old: Def, new: Def) -> bool {
51-
if self.toplevel_mapping.contains_key(&old.def_id()) {
54+
let old_def_id = old.def_id();
55+
56+
if !self.in_old_crate(old_def_id) || self.toplevel_mapping.contains_key(&old_def_id) {
5257
return false;
5358
}
5459

5560
self.toplevel_mapping
56-
.insert(old.def_id(), (old, new));
61+
.insert(old_def_id, (old, new));
5762

5863
true
5964
}
6065

66+
/// Register that an old item has no corresponding new item.
67+
pub fn add_removal(&mut self, old: DefId) {
68+
self.removed_items.insert(old);
69+
}
70+
6171
/// Add any trait item's old and new `DefId`s.
6272
pub fn add_trait_item(&mut self, old: Def, new: Def, trait_def_id: DefId) {
63-
self.trait_item_mapping.insert(old.def_id(), (old, new, trait_def_id));
73+
let old_def_id = old.def_id();
74+
75+
assert!(self.in_old_crate(old_def_id));
76+
77+
self.trait_item_mapping.insert(old_def_id, (old, new, trait_def_id));
6478
}
6579

6680
/// Add any other item's old and new `DefId`s.
@@ -70,12 +84,14 @@ impl IdMapping {
7084
old,
7185
self.internal_mapping[&old],
7286
new);
87+
assert!(self.in_old_crate(old));
7388

7489
self.internal_mapping.insert(old, new);
7590
}
7691

7792
/// Add any other item's old and new `DefId`s, together with a parent entry.
7893
pub fn add_subitem(&mut self, parent: DefId, old: DefId, new: DefId) {
94+
// NB: we rely on the assers in `add_internal_item` here.
7995
self.add_internal_item(old, new);
8096
self.child_mapping
8197
.entry(parent)
@@ -85,29 +101,49 @@ impl IdMapping {
85101

86102
/// Record that a `DefId` represents a new type parameter.
87103
pub fn add_type_param(&mut self, new: TypeParameterDef) {
104+
assert!(self.in_new_crate(new.def_id));
88105
self.type_params.insert(new.def_id, new);
89106
}
90107

91108
/// Get the type parameter represented by a given `DefId`.
92-
pub fn get_type_param(&self, def_id: &DefId) -> TypeParameterDef {
93-
self.type_params[def_id]
109+
pub fn get_type_param(&self, did: &DefId) -> TypeParameterDef {
110+
self.type_params[did]
94111
}
95112

96113
/// Check whether a `DefId` represents a newly added defaulted type parameter.
97114
pub fn is_defaulted_type_param(&self, new: &DefId) -> bool {
115+
// TODO?
98116
self.type_params
99117
.get(new)
100118
.map_or(false, |def| def.has_default)
101119
}
102120

103121
/// Get the new `DefId` associated with the given old one.
104122
pub fn get_new_id(&self, old: DefId) -> DefId {
105-
if let Some(new) = self.toplevel_mapping.get(&old) {
106-
new.1.def_id()
107-
} else if let Some(new) = self.trait_item_mapping.get(&old) {
108-
new.1.def_id()
123+
assert!(!self.in_new_crate(old));
124+
125+
if self.in_old_crate(old) && !self.removed_items.contains(&old) {
126+
if let Some(new) = self.toplevel_mapping.get(&old) {
127+
new.1.def_id()
128+
} else if let Some(new) = self.trait_item_mapping.get(&old) {
129+
new.1.def_id()
130+
} else {
131+
self.internal_mapping[&old]
132+
}
133+
} else {
134+
old
135+
}
136+
}
137+
138+
/// Get the new `DefId` associated with the given old one, respecting possibly removed
139+
/// traits that are a parent of the given `DefId`.
140+
pub fn get_new_trait_item_id(&self, old: DefId, trait_id: DefId) -> DefId {
141+
assert!(!self.in_new_crate(trait_id));
142+
143+
if !self.removed_items.contains(&trait_id) {
144+
self.get_new_id(old)
109145
} else {
110-
self.internal_mapping[&old]
146+
old
111147
}
112148
}
113149

@@ -148,10 +184,12 @@ impl IdMapping {
148184
.map(|m| m.iter().map(move |old| (*old, self.internal_mapping[old])))
149185
}
150186

187+
/// Check whether a `DefId` belongs to an item in the old crate.
151188
pub fn in_old_crate(&self, did: DefId) -> bool {
152189
self.old_crate == did.krate
153190
}
154191

192+
/// Check whether a `DefId` belongs to an item in the new crate.
155193
pub fn in_new_crate(&self, did: DefId) -> bool {
156194
self.new_crate == did.krate
157195
}

‎src/semcheck/mismatch.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,12 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Mismatch<'a, 'gcx, 'tcx> {
111111
.collect();
112112

113113
for field in a_adt.all_fields().filter(|f| f.vis == Public) {
114-
if self.id_mapping.contains_id(field.did) {
115-
let a_field_ty = field.ty(self.tcx, a_substs);
116-
let b_field_ty =
117-
b_fields[&self.id_mapping.get_new_id(field.did)]
118-
.ty(self.tcx, b_substs);
119-
120-
let _ = self.relate(&a_field_ty, &b_field_ty)?;
121-
}
114+
let a_field_ty = field.ty(self.tcx, a_substs);
115+
let b_field_ty =
116+
b_fields[&self.id_mapping.get_new_id(field.did)]
117+
.ty(self.tcx, b_substs);
118+
119+
let _ = self.relate(&a_field_ty, &b_field_ty)?;
122120
}
123121

124122
Some((a_def.did, b_def.did))
@@ -188,7 +186,8 @@ impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Mismatch<'a, 'gcx, 'tcx> {
188186
};
189187

190188
if let Some((old_def_id, new_def_id)) = matching {
191-
if !self.id_mapping.contains_id(old_def_id) && self.id_mapping.in_old_crate(old_def_id) {
189+
if !self.id_mapping.contains_id(old_def_id) &&
190+
self.id_mapping.in_old_crate(old_def_id) {
192191
self.id_mapping.add_internal_item(old_def_id, new_def_id);
193192
self.item_queue.push_back((old_def_id, new_def_id));
194193
}

‎src/semcheck/traverse.rs

+9-22
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ fn diff_structure<'a, 'tcx>(changes: &mut ChangeSet,
261261
changes.new_path_change(n_def_id, o.ident.name, tcx.def_span(n_def_id));
262262
changes.add_path_removal(n_def_id, o.span);
263263
} else {
264+
id_mapping.add_removal(o_def_id);
264265
changes.new_path_change(o_def_id, o.ident.name, tcx.def_span(o_def_id));
265266
changes.add_path_removal(o_def_id, o.span);
266267
}
@@ -732,7 +733,7 @@ fn fold_to_new<'a, 'tcx, T>(id_mapping: &IdMapping,
732733

733734
old.fold_with(&mut BottomUpFolder { tcx: tcx, fldop: |ty| {
734735
match ty.sty {
735-
TyAdt(&AdtDef { ref did, .. }, substs) if id_mapping.contains_id(*did) => {
736+
TyAdt(&AdtDef { ref did, .. }, substs) if id_mapping.in_old_crate(*did) => {
736737
let new_def_id = id_mapping.get_new_id(*did);
737738
let new_adt = tcx.adt_def(new_def_id);
738739
tcx.mk_adt(new_adt, substs)
@@ -747,23 +748,15 @@ fn fold_to_new<'a, 'tcx, T>(id_mapping: &IdMapping,
747748
let new_preds = tcx.mk_existential_predicates(preds.iter().map(|p| {
748749
match *p.skip_binder() {
749750
Trait(ExistentialTraitRef { def_id: did, substs }) => {
750-
let new_def_id = if id_mapping.contains_id(did) {
751-
id_mapping.get_new_id(did)
752-
} else {
753-
did
754-
};
751+
let new_def_id = id_mapping.get_new_id(did);
755752

756753
Trait(ExistentialTraitRef {
757754
def_id: new_def_id,
758755
substs: substs
759756
})
760757
},
761758
Projection(ExistentialProjection { item_def_id, substs, ty }) => {
762-
let new_def_id = if id_mapping.contains_id(item_def_id) {
763-
id_mapping.get_new_id(item_def_id)
764-
} else {
765-
item_def_id
766-
};
759+
let new_def_id = id_mapping.get_new_id(item_def_id);
767760

768761
Projection(ExistentialProjection {
769762
item_def_id: new_def_id,
@@ -772,23 +765,17 @@ fn fold_to_new<'a, 'tcx, T>(id_mapping: &IdMapping,
772765
})
773766
},
774767
AutoTrait(did) => {
775-
if id_mapping.contains_id(did) {
776-
AutoTrait(id_mapping.get_new_id(did))
777-
} else {
778-
AutoTrait(did)
779-
}
768+
AutoTrait(id_mapping.get_new_id(did))
780769
},
781770
}
782771
}));
783772

784773
tcx.mk_dynamic(Binder(new_preds), region)
785774
},
786775
TyProjection(proj) => {
787-
let new_def_id = if id_mapping.contains_id(proj.item_def_id) {
788-
id_mapping.get_new_id(proj.item_def_id)
789-
} else {
790-
proj.item_def_id
791-
};
776+
let trait_def_id = tcx.associated_item(proj.item_def_id).container.id();
777+
let new_def_id =
778+
id_mapping.get_new_trait_item_id(proj.item_def_id, trait_def_id);
792779

793780
tcx.mk_projection(new_def_id, proj.substs)
794781
},
@@ -798,7 +785,7 @@ fn fold_to_new<'a, 'tcx, T>(id_mapping: &IdMapping,
798785
TyParam(param) => {
799786
if param.idx != 0 { // `Self` is special
800787
let old_did = index_map[&param.idx];
801-
if id_mapping.contains_id(old_did) {
788+
if id_mapping.in_old_crate(old_did) {
802789
let new_def_id = id_mapping.get_new_id(old_did);
803790
tcx.mk_param_from_def(&id_mapping.get_type_param(&new_def_id))
804791
} else {

0 commit comments

Comments
 (0)
Please sign in to comment.