Skip to content

Commit 07a81ad

Browse files
committed
Refactor how impl self types are stored
In order to avoid a confusing use of the tcache, I added an extra node ID field to trait refs. Now trait refs have a "ref ID" (the one that resolve3 resolves) and an "impl ID" (the one that you look up in the tcache to get the self type). Closes #2434
1 parent ee73b78 commit 07a81ad

File tree

10 files changed

+41
-31
lines changed

10 files changed

+41
-31
lines changed

src/libsyntax/ast.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -675,10 +675,15 @@ type attribute_ = {style: attr_style, value: meta_item, is_sugared_doc: bool};
675675

676676
/*
677677
trait_refs appear in both impls and in classes that implement traits.
678-
resolve maps each trait_ref's id to its defining trait.
678+
resolve maps each trait_ref's ref_id to its defining trait; that's all
679+
that the ref_id is for. The impl_id maps to the "self type" of this impl.
680+
If this impl is an item_impl, the impl_id is redundant (it could be the
681+
same as the impl's node id). If this impl is actually an impl_class, then
682+
conceptually, the impl_id stands in for the pair of (this class, this
683+
trait)
679684
*/
680685
#[auto_serialize]
681-
type trait_ref = {path: @path, id: node_id};
686+
type trait_ref = {path: @path, ref_id: node_id, impl_id: node_id};
682687

683688
#[auto_serialize]
684689
enum visibility { public, private }

src/libsyntax/ast_map.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ fn map_item(i: @item, cx: ctx, v: vt) {
188188
let item_path = @/* FIXME (#2543) */ copy cx.path;
189189
cx.map.insert(i.id, node_item(i, item_path));
190190
alt i.node {
191-
item_impl(_, _, _, ms) {
191+
item_impl(_, opt_ir, _, ms) {
192192
let impl_did = ast_util::local_def(i.id);
193193
for ms.each |m| {
194194
map_method(impl_did, extend(cx, i.ident), m,
@@ -218,8 +218,14 @@ fn map_item(i: @item, cx: ctx, v: vt) {
218218
let (_, ms) = ast_util::split_class_items(items);
219219
// Map trait refs to their parent classes. This is
220220
// so we can find the self_ty
221-
do vec::iter(traits) |p| { cx.map.insert(p.id,
222-
node_item(i, item_path)); };
221+
do vec::iter(traits) |p| { cx.map.insert(p.ref_id,
222+
node_item(i, item_path));
223+
// This is so we can look up the right things when
224+
// encoding/decoding
225+
cx.map.insert(p.impl_id,
226+
node_item(i, item_path));
227+
228+
};
223229
let d_id = ast_util::local_def(i.id);
224230
let p = extend(cx, i.ident);
225231
// only need to handle methods

src/libsyntax/fold.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,8 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
287287
}
288288

289289
fn fold_trait_ref(&&p: @trait_ref, fld: ast_fold) -> @trait_ref {
290-
@{path: fld.fold_path(p.path), id: fld.new_id(p.id)}
290+
@{path: fld.fold_path(p.path), ref_id: fld.new_id(p.ref_id),
291+
impl_id: fld.new_id(p.impl_id)}
291292
}
292293

293294
fn noop_fold_method(&&m: @method, fld: ast_fold) -> @method {

src/libsyntax/parse/parser.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,7 +2189,7 @@ class parser {
21892189
if option::is_none(ident) {
21902190
ident = some(vec::last(path.idents));
21912191
}
2192-
some(@{path: path, id: self.get_id()})
2192+
some(@{path: path, ref_id: self.get_id(), impl_id: self.get_id()})
21932193
} else { none };
21942194
let ident = alt ident {
21952195
some(name) { name }
@@ -2223,7 +2223,7 @@ class parser {
22232223

22242224
fn parse_trait_ref() -> @trait_ref {
22252225
@{path: self.parse_path_with_tps(false),
2226-
id: self.get_id()}
2226+
ref_id: self.get_id(), impl_id: self.get_id()}
22272227
}
22282228

22292229
fn parse_trait_ref_list() -> ~[@trait_ref] {

src/rustc/metadata/encoder.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
227227

228228
fn encode_trait_ref(ebml_w: ebml::writer, ecx: @encode_ctxt, t: @trait_ref) {
229229
ebml_w.start_tag(tag_impl_trait);
230-
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, t.id));
230+
encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, t.ref_id));
231231
ebml_w.end_tag();
232232
}
233233

@@ -392,6 +392,7 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod,
392392
encode_family(ebml_w, 'm');
393393
encode_name(ebml_w, name);
394394
#debug("(encoding info for module) encoding info for module ID %d", id);
395+
// the impl map contains ref_ids
395396
let impls = ecx.impl_map(id);
396397
for impls.each |i| {
397398
let (ident, did) = i;
@@ -415,6 +416,7 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod,
415416
}
416417
none {
417418
// Must be a re-export, then!
419+
// ...or an iface ref
418420
ebml_w.wr_str(def_to_str(did));
419421
}
420422
};

src/rustc/middle/resolve.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -408,8 +408,11 @@ fn maybe_insert(e: @env, id: node_id, def: option<def>) {
408408
}
409409

410410
fn resolve_trait_ref(p: @trait_ref, sc: scopes, e: @env) {
411-
maybe_insert(e, p.id,
411+
maybe_insert(e, p.ref_id,
412412
lookup_path_strict(*e, sc, p.path.span, p.path, ns_type));
413+
maybe_insert(e, p.impl_id,
414+
lookup_path_strict(*e, sc, p.path.span, p.path, ns_type));
415+
413416
}
414417

415418
fn resolve_names(e: @env, c: @ast::crate) {
@@ -440,8 +443,8 @@ fn resolve_names(e: @env, c: @ast::crate) {
440443
/* At this point, the code knows what traits the trait refs
441444
refer to, so it's possible to resolve them.
442445
*/
443-
ast::item_impl(_, ifce, _, _) {
444-
ifce.iter(|p| resolve_trait_ref(p, sc, e))
446+
ast::item_impl(_, t, _, _) {
447+
t.iter(|p| resolve_trait_ref(p, sc, e));
445448
}
446449
ast::item_class(_, traits, _, _, _) {
447450
for traits.each |p| {
@@ -2290,7 +2293,7 @@ fn find_impls_in_item(e: env, i: @ast::item, &impls: ~[@_impl],
22902293
do vec::iter(ifces) |p| {
22912294
// The def_id, in this case, identifies the combination of
22922295
// class and trait
2293-
vec::push(impls, @{did: local_def(p.id),
2296+
vec::push(impls, @{did: local_def(p.impl_id),
22942297
ident: i.ident,
22952298
methods: vec::map(mthds, |m| {
22962299
@{did: local_def(m.id),

src/rustc/middle/resolve3.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3241,7 +3241,7 @@ class Resolver {
32413241

32423242
#debug("(resolving class) found trait def: %?", def);
32433243

3244-
self.record_def(interface.id, def);
3244+
self.record_def(interface.ref_id, def);
32453245

32463246
// XXX: This is wrong but is needed for tests to
32473247
// pass.
@@ -3349,7 +3349,7 @@ class Resolver {
33493349
unknown interface");
33503350
}
33513351
some(def) {
3352-
self.record_def(interface_reference.id, def);
3352+
self.record_def(interface_reference.ref_id, def);
33533353
}
33543354
}
33553355
}

src/rustc/middle/ty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2549,7 +2549,7 @@ fn impl_trait(cx: ctxt, id: ast::def_id) -> option<t> {
25492549
#debug("(impl_trait) searching for trait impl %?", id);
25502550
alt cx.items.find(id.node) {
25512551
some(ast_map::node_item(@{node: ast::item_impl(
2552-
_, some(@{id: id, _}), _, _), _}, _)) {
2552+
_, some(@{ref_id: id, _}), _, _), _}, _)) {
25532553
some(node_id_to_type(cx, id))
25542554
}
25552555
some(ast_map::node_item(@{node: ast::item_class(*),

src/rustc/middle/typeck/coherence.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ class CoherenceChecker {
128128
}
129129
some(associated_trait) {
130130
let def =
131-
self.crate_context.tcx.def_map.get(associated_trait.id);
131+
self.crate_context.tcx.def_map.get(associated_trait.ref_id);
132132
let def_id = def_id_of_def(def);
133133

134134
let implementation_list;
@@ -349,7 +349,7 @@ class CoherenceChecker {
349349
let def_map = self.crate_context
350350
.tcx.def_map;
351351
let trait_def =
352-
def_map.get(trait_ref.id);
352+
def_map.get(trait_ref.ref_id);
353353
let trait_id =
354354
def_id_of_def(trait_def);
355355
if trait_id.crate != local_crate {

src/rustc/middle/typeck/collect.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -392,17 +392,9 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
392392
let cms = convert_methods(ccx, methods, rp, bounds, selfty);
393393
for traits.each |ifce| {
394394
check_methods_against_trait(ccx, tps, rp, selfty, ifce, cms);
395-
396-
// FIXME #2434---this is somewhat bogus, but it seems that
397-
// the id of trait_ref is also the id of the impl, and so
398-
// we want to store the "self type" of the impl---in this
399-
// case, the class. The reason I say this is somewhat
400-
// bogus (and should be refactored) is that the tcache
401-
// stores the class type for ifce.id but the node_type
402-
// table stores the trait type. Weird. Probably just
403-
// adding a "self type" table rather than overloading the
404-
// tcache would be ok, or else adding more than one id.
405-
tcx.tcache.insert(local_def(ifce.id), tpt);
395+
// ifce.impl_id represents (class, iface) pair
396+
write_ty_to_tcx(tcx, ifce.impl_id, tpt.ty);
397+
tcx.tcache.insert(local_def(ifce.impl_id), tpt);
406398
}
407399
}
408400
_ {
@@ -462,9 +454,10 @@ fn instantiate_trait_ref(ccx: @crate_ctxt, t: @ast::trait_ref, rp: bool)
462454

463455
let rscope = type_rscope(rp);
464456

465-
alt lookup_def_tcx(ccx.tcx, t.path.span, t.id) {
457+
alt lookup_def_tcx(ccx.tcx, t.path.span, t.ref_id) {
466458
ast::def_ty(t_id) {
467-
let tpt = astconv::ast_path_to_ty(ccx, rscope, t_id, t.path, t.id);
459+
let tpt = astconv::ast_path_to_ty(ccx, rscope, t_id, t.path,
460+
t.ref_id);
468461
alt ty::get(tpt.ty).struct {
469462
ty::ty_trait(*) {
470463
(t_id, tpt)

0 commit comments

Comments
 (0)