Skip to content

Commit 6559aa8

Browse files
committed
Write the iface type of an impl in the crate data
Also, move checking of ifaces into the collect phase of typeck to give further passes some guarantees. Issue #1227
1 parent 3eb3590 commit 6559aa8

File tree

6 files changed

+129
-105
lines changed

6 files changed

+129
-105
lines changed

src/comp/metadata/common.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ const tag_crate_hash: uint = 0x28u;
6767
const tag_mod_impl: uint = 0x30u;
6868

6969
const tag_impl_method: uint = 0x31u;
70+
const tag_impl_iface: uint = 0x32u;
7071

7172
// djb's cdb hashes.
7273
fn hash_node_id(&&node_id: int) -> uint { ret 177573u ^ (node_id as uint); }

src/comp/metadata/csearch.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export get_impls_for_mod;
1313
export get_impl_methods;
1414
export get_type;
1515
export get_item_name;
16+
export get_impl_iface;
1617

1718
fn get_symbol(cstore: cstore::cstore, def: ast::def_id) -> str {
1819
let cdata = cstore::get_crate_data(cstore, def.crate).data;
@@ -100,6 +101,14 @@ fn get_item_name(cstore: cstore::cstore, cnum: int, id: int) -> ast::ident {
100101
ret decoder::lookup_item_name(cdata, id);
101102
}
102103

104+
fn get_impl_iface(tcx: ty::ctxt, def: ast::def_id)
105+
-> option::t<ty::t> {
106+
let cstore = tcx.sess.get_cstore();
107+
let cdata = cstore::get_crate_data(cstore, def.crate).data;
108+
let resolver = bind translate_def_id(cstore, def.crate, _);
109+
decoder::get_impl_iface(cdata, def, tcx, resolver)
110+
}
111+
103112
// Translates a def_id from an external crate to a def_id for the current
104113
// compilation environment. We use this when trying to load types from
105114
// external crates - if those types further refer to types in other crates

src/comp/metadata/decoder.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ export get_symbol;
1414
export get_tag_variants;
1515
export get_type;
1616
export get_type_param_count;
17+
export get_impl_iface;
1718
export lookup_def;
1819
export lookup_item_name;
20+
export get_impl_iface;
1921
export resolve_path;
2022
export get_crate_attributes;
2123
export list_crate_metadata;
@@ -115,6 +117,18 @@ fn item_type(item: ebml::doc, this_cnum: ast::crate_num, tcx: ty::ctxt,
115117
t
116118
}
117119

120+
fn item_impl_iface(item: ebml::doc, this_cnum: ast::crate_num, tcx: ty::ctxt,
121+
extres: external_resolver) -> option::t<ty::t> {
122+
let result = none;
123+
ebml::tagged_docs(item, tag_impl_iface) {|ity|
124+
let def_parser = bind parse_external_def_id(this_cnum, extres, _);
125+
let t = parse_ty_data(ity.data, this_cnum, ity.start,
126+
ity.end - ity.start, def_parser, tcx);
127+
result = some(t);
128+
}
129+
result
130+
}
131+
118132
fn item_ty_param_bounds(item: ebml::doc, this_cnum: ast::crate_num,
119133
tcx: ty::ctxt, extres: external_resolver)
120134
-> @[ty::param_bounds] {
@@ -217,6 +231,11 @@ fn get_type_param_count(data: @[u8], id: ast::node_id) -> uint {
217231
item_ty_param_count(lookup_item(id, data))
218232
}
219233

234+
fn get_impl_iface(data: @[u8], def: ast::def_id, tcx: ty::ctxt,
235+
extres: external_resolver) -> option::t<ty::t> {
236+
item_impl_iface(lookup_item(def.node, data), def.crate, tcx, extres)
237+
}
238+
220239
fn get_symbol(data: @[u8], id: ast::node_id) -> str {
221240
ret item_symbol(lookup_item(id, data));
222241
}
@@ -269,7 +288,6 @@ fn lookup_impl_methods(data: @[u8], node: ast::node_id, cnum: ast::crate_num)
269288
rslt
270289
}
271290

272-
273291
fn family_has_type_params(fam_ch: u8) -> bool {
274292
ret alt fam_ch as char {
275293
'c' { false }

src/comp/metadata/encoder.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,13 +202,17 @@ fn encode_variant_id(ebml_w: ebml::writer, vid: def_id) {
202202
ebml::end_tag(ebml_w);
203203
}
204204

205-
fn encode_type(ecx: @encode_ctxt, ebml_w: ebml::writer, typ: ty::t) {
206-
ebml::start_tag(ebml_w, tag_items_data_item_type);
205+
fn write_type(ecx: @encode_ctxt, ebml_w: ebml::writer, typ: ty::t) {
207206
let ty_str_ctxt =
208207
@{ds: def_to_str,
209208
tcx: ecx.ccx.tcx,
210209
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
211210
tyencode::enc_ty(io::new_writer(ebml_w.writer), ty_str_ctxt, typ);
211+
}
212+
213+
fn encode_type(ecx: @encode_ctxt, ebml_w: ebml::writer, typ: ty::t) {
214+
ebml::start_tag(ebml_w, tag_items_data_item_type);
215+
write_type(ecx, ebml_w, typ);
212216
ebml::end_tag(ebml_w);
213217
}
214218

@@ -369,7 +373,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
369373
encode_symbol(ecx, ebml_w, ctor_id);
370374
ebml::end_tag(ebml_w);
371375
}
372-
item_impl(tps, _, _, methods) {
376+
item_impl(tps, ifce, _, methods) {
373377
ebml::start_tag(ebml_w, tag_items_data_item);
374378
encode_def_id(ebml_w, local_def(item.id));
375379
encode_family(ebml_w, 'i' as u8);
@@ -381,6 +385,15 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
381385
ebml_w.writer.write(str::bytes(def_to_str(local_def(m.id))));
382386
ebml::end_tag(ebml_w);
383387
}
388+
alt ifce {
389+
some(_) {
390+
ebml::start_tag(ebml_w, tag_impl_iface);
391+
write_type(ecx, ebml_w, ty::lookup_item_type(
392+
ecx.ccx.tcx, local_def(item.id)).ty);
393+
ebml::end_tag(ebml_w);
394+
}
395+
_ {}
396+
}
384397
ebml::end_tag(ebml_w);
385398

386399
for m in methods {

src/comp/middle/ty.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export substitute_type_params;
102102
export t;
103103
export new_ty_hash;
104104
export tag_variants;
105-
export iface_methods, store_iface_methods;
105+
export iface_methods, store_iface_methods, impl_iface;
106106
export tag_variant_with_id;
107107
export ty_param_substs_opt_and_ty;
108108
export ty_param_bounds_and_ty;
@@ -2670,6 +2670,14 @@ fn iface_methods(cx: ctxt, id: ast::def_id) -> @[method] {
26702670
result
26712671
}
26722672

2673+
fn impl_iface(cx: ctxt, id: ast::def_id) -> option::t<t> {
2674+
if id.crate == ast::local_crate {
2675+
option::map(cx.tcache.find(id), {|it| it.ty})
2676+
} else {
2677+
csearch::get_impl_iface(cx, id)
2678+
}
2679+
}
2680+
26732681
// Tag information
26742682
type variant_info = @{args: [ty::t], ctor_ty: ty::t, id: ast::def_id};
26752683

0 commit comments

Comments
 (0)