Skip to content

Commit 58a81a6

Browse files
committed
Finish resolving and calling of crate-external impls
Issue #1227
1 parent dd9693f commit 58a81a6

File tree

7 files changed

+196
-76
lines changed

7 files changed

+196
-76
lines changed

src/comp/driver/rustc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ fn build_session(sopts: @session::options) -> session::session {
497497
sopts.target_triple,
498498
sopts.addl_lib_search_paths);
499499
ret session::session(target_cfg, sopts, cstore,
500-
@{cm: codemap::new_codemap(), mutable next_id: 0},
500+
@{cm: codemap::new_codemap(), mutable next_id: 1},
501501
none, 0u, filesearch, false);
502502
}
503503

src/comp/metadata/csearch.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22

33
import syntax::ast;
44
import middle::ty;
5-
import option;
5+
import option::{some, none};
66
import driver::session;
77

88
export get_symbol;
99
export get_type_param_count;
1010
export lookup_defs;
1111
export get_tag_variants;
12+
export get_impls_for_mod;
13+
export get_impl_methods;
1214
export get_type;
1315

1416
fn get_symbol(cstore: cstore::cstore, def: ast::def_id) -> str {
@@ -56,15 +58,38 @@ fn get_tag_variants(tcx: ty::ctxt, def: ast::def_id) -> [ty::variant_info] {
5658
let cstore = tcx.sess.get_cstore();
5759
let cnum = def.crate;
5860
let cdata = cstore::get_crate_data(cstore, cnum).data;
59-
let resolver = bind translate_def_id(tcx.sess, cnum, _);
61+
let resolver = bind translate_def_id(cstore, cnum, _);
6062
ret decoder::get_tag_variants(cdata, def, tcx, resolver)
6163
}
6264

65+
fn get_impls_for_mod(cstore: cstore::cstore, def: ast::def_id,
66+
name: option::t<ast::ident>)
67+
-> [@middle::resolve::_impl] {
68+
let cdata = cstore::get_crate_data(cstore, def.crate).data;
69+
let result = [];
70+
for did in decoder::get_impls_for_mod(cdata, def.node, def.crate) {
71+
let nm = decoder::lookup_item_name(cdata, did.node);
72+
if alt name { some(n) { n == nm } none. { true } } {
73+
result += [@{did: did,
74+
ident: nm,
75+
methods: decoder::lookup_impl_methods(
76+
cdata, did.node, did.crate)}];
77+
}
78+
}
79+
result
80+
}
81+
82+
fn get_impl_methods(cstore: cstore::cstore, def: ast::def_id)
83+
-> [@middle::resolve::method_info] {
84+
let cdata = cstore::get_crate_data(cstore, def.crate).data;
85+
decoder::lookup_impl_methods(cdata, def.node, def.crate)
86+
}
87+
6388
fn get_type(tcx: ty::ctxt, def: ast::def_id) -> ty::ty_param_kinds_and_ty {
6489
let cstore = tcx.sess.get_cstore();
6590
let cnum = def.crate;
6691
let cdata = cstore::get_crate_data(cstore, cnum).data;
67-
let resolver = bind translate_def_id(tcx.sess, cnum, _);
92+
let resolver = bind translate_def_id(cstore, cnum, _);
6893
decoder::get_type(cdata, def, tcx, resolver)
6994
}
7095

@@ -73,7 +98,7 @@ fn get_type(tcx: ty::ctxt, def: ast::def_id) -> ty::ty_param_kinds_and_ty {
7398
// external crates - if those types further refer to types in other crates
7499
// then we must translate the crate number from that encoded in the external
75100
// crate to the correct local crate number.
76-
fn translate_def_id(sess: session::session, searched_crate: ast::crate_num,
101+
fn translate_def_id(cstore: cstore::cstore, searched_crate: ast::crate_num,
77102
def_id: ast::def_id) -> ast::def_id {
78103

79104
let ext_cnum = def_id.crate;
@@ -82,13 +107,12 @@ fn translate_def_id(sess: session::session, searched_crate: ast::crate_num,
82107
assert (searched_crate != ast::local_crate);
83108
assert (ext_cnum != ast::local_crate);
84109

85-
let cstore = sess.get_cstore();
86110
let cmeta = cstore::get_crate_data(cstore, searched_crate);
87111

88112
let local_cnum =
89113
alt cmeta.cnum_map.find(ext_cnum) {
90114
option::some(n) { n }
91-
option::none. { sess.bug("didn't find a crate in the cnum_map") }
115+
option::none. { fail "didn't find a crate in the cnum_map"; }
92116
};
93117

94118
ret {crate: local_cnum, node: node_id};

src/comp/metadata/decoder.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@ export get_type;
1616
export get_type_param_count;
1717
export get_type_param_kinds;
1818
export lookup_def;
19+
export lookup_item_name;
1920
export resolve_path;
2021
export get_crate_attributes;
2122
export list_crate_metadata;
2223
export crate_dep;
2324
export get_crate_deps;
2425
export get_crate_hash;
2526
export external_resolver;
26-
27+
export get_impls_for_mod;
28+
export lookup_impl_methods;
2729
// A function that takes a def_id relative to the crate being searched and
2830
// returns a def_id relative to the compilation environment, i.e. if we hit a
2931
// def_id for an item defined in another crate, somebody needs to figure out
@@ -130,6 +132,15 @@ fn item_ty_param_kinds(item: ebml::doc) -> [ast::kind] {
130132
ret ks;
131133
}
132134

135+
fn item_ty_param_count(item: ebml::doc) -> uint {
136+
let n = 0u;
137+
let tp = tag_items_data_item_ty_param_kinds;
138+
ebml::tagged_docs(item, tp) {|p|
139+
n += ebml::vint_at(ebml::doc_data(p), 0u).val;
140+
}
141+
n
142+
}
143+
133144
fn tag_variant_ids(item: ebml::doc, this_cnum: ast::crate_num) ->
134145
[ast::def_id] {
135146
let ids: [ast::def_id] = [];
@@ -159,6 +170,15 @@ fn resolve_path(path: [ast::ident], data: @[u8]) -> [ast::def_id] {
159170
ret result;
160171
}
161172

173+
fn item_name(item: ebml::doc) -> ast::ident {
174+
let name = ebml::get_doc(item, tag_paths_data_name);
175+
str::unsafe_from_bytes(ebml::doc_data(name))
176+
}
177+
178+
fn lookup_item_name(data: @[u8], id: ast::node_id) -> ast::ident {
179+
item_name(lookup_item(id, data))
180+
}
181+
162182
// FIXME doesn't yet handle renamed re-exported externals
163183
fn lookup_def(cnum: ast::crate_num, data: @[u8], did_: ast::def_id) ->
164184
ast::def {
@@ -205,7 +225,7 @@ fn get_type(data: @[u8], def: ast::def_id, tcx: ty::ctxt,
205225
}
206226

207227
fn get_type_param_count(data: @[u8], id: ast::node_id) -> uint {
208-
ret vec::len(get_type_param_kinds(data, id));
228+
item_ty_param_count(lookup_item(id, data))
209229
}
210230

211231
fn get_type_param_kinds(data: @[u8], id: ast::node_id) -> [ast::kind] {
@@ -243,6 +263,31 @@ fn get_tag_variants(_data: @[u8], def: ast::def_id, tcx: ty::ctxt,
243263
ret infos;
244264
}
245265

266+
fn get_impls_for_mod(data: @[u8], node: ast::node_id, cnum: ast::crate_num)
267+
-> [ast::def_id] {
268+
let mod_item = lookup_item(node, data), result = [];
269+
ebml::tagged_docs(mod_item, tag_mod_impl) {|doc|
270+
let did = parse_def_id(ebml::doc_data(doc));
271+
result += [{crate: cnum with did}];
272+
}
273+
result
274+
}
275+
276+
fn lookup_impl_methods(data: @[u8], node: ast::node_id, cnum: ast::crate_num)
277+
-> [@middle::resolve::method_info] {
278+
let impl_item = lookup_item(node, data), rslt = [];
279+
let base_tps = item_ty_param_count(impl_item);
280+
ebml::tagged_docs(impl_item, tag_impl_method) {|doc|
281+
let m_did = parse_def_id(ebml::doc_data(doc));
282+
let mth_item = lookup_item(m_did.node, data);
283+
rslt += [@{did: {crate: cnum, node: m_did.node},
284+
n_tps: item_ty_param_count(mth_item) - base_tps,
285+
ident: item_name(mth_item)}];
286+
}
287+
rslt
288+
}
289+
290+
246291
fn family_has_type_params(fam_ch: u8) -> bool {
247292
ret alt fam_ch as char {
248293
'c' { false }
@@ -258,6 +303,7 @@ fn family_has_type_params(fam_ch: u8) -> bool {
258303
'm' { false }
259304
'n' { false }
260305
'v' { true }
306+
'i' { true }
261307
};
262308
}
263309

src/comp/metadata/encoder.rs

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,26 @@ fn encode_tag_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
249249
}
250250
}
251251

252+
fn encode_info_for_mod(ebml_w: ebml::writer, md: _mod,
253+
id: node_id) {
254+
ebml::start_tag(ebml_w, tag_items_data_item);
255+
encode_def_id(ebml_w, local_def(id));
256+
encode_family(ebml_w, 'm' as u8);
257+
for i in md.items {
258+
alt i.node {
259+
item_impl(_, _, _) {
260+
if ast_util::is_exported(i.ident, md) {
261+
ebml::start_tag(ebml_w, tag_mod_impl);
262+
ebml_w.writer.write(str::bytes(def_to_str(local_def(i.id))));
263+
ebml::end_tag(ebml_w);
264+
}
265+
}
266+
_ {}
267+
}
268+
}
269+
ebml::end_tag(ebml_w);
270+
}
271+
252272
fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
253273
&index: [entry<int>]) {
254274
alt item.node {
@@ -280,20 +300,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
280300
ebml::end_tag(ebml_w);
281301
}
282302
item_mod(m) {
283-
ebml::start_tag(ebml_w, tag_items_data_item);
284-
encode_def_id(ebml_w, local_def(item.id));
285-
encode_family(ebml_w, 'm' as u8);
286-
for i in m.items {
287-
alt i.node {
288-
item_impl(_, _, _) {
289-
ebml::start_tag(ebml_w, tag_mod_impl);
290-
ebml_w.writer.write(str::bytes(def_to_str(local_def(i.id))));
291-
ebml::end_tag(ebml_w);
292-
}
293-
_ {}
294-
}
295-
}
296-
ebml::end_tag(ebml_w);
303+
encode_info_for_mod(ebml_w, m, item.id);
297304
}
298305
item_native_mod(_) {
299306
ebml::start_tag(ebml_w, tag_items_data_item);
@@ -363,9 +370,10 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
363370
item_impl(tps, _, methods) {
364371
ebml::start_tag(ebml_w, tag_items_data_item);
365372
encode_def_id(ebml_w, local_def(item.id));
366-
encode_family(ebml_w, 'I' as u8);
373+
encode_family(ebml_w, 'i' as u8);
367374
encode_type_param_kinds(ebml_w, tps);
368375
encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
376+
encode_name(ebml_w, item.ident);
369377
for m in methods {
370378
ebml::start_tag(ebml_w, tag_impl_method);
371379
ebml_w.writer.write(str::bytes(def_to_str(local_def(m.node.id))));
@@ -377,10 +385,12 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
377385
index += [{val: m.node.id, pos: ebml_w.writer.tell()}];
378386
ebml::start_tag(ebml_w, tag_items_data_item);
379387
encode_def_id(ebml_w, local_def(m.node.id));
380-
encode_family(ebml_w, 'i' as u8);
388+
encode_family(ebml_w, 'f' as u8);
389+
encode_inlineness(ebml_w, 'n' as u8);
381390
encode_type_param_kinds(ebml_w, tps + m.node.tps);
382391
encode_type(ecx, ebml_w,
383392
node_id_to_monotype(ecx.ccx.tcx, m.node.id));
393+
encode_name(ebml_w, m.node.ident);
384394
encode_symbol(ecx, ebml_w, m.node.id);
385395
ebml::end_tag(ebml_w);
386396
}
@@ -415,10 +425,12 @@ fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer,
415425
ebml::end_tag(ebml_w);
416426
}
417427

418-
fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer) ->
419-
[entry<int>] {
428+
fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
429+
crate_mod: _mod) -> [entry<int>] {
420430
let index: [entry<int>] = [];
421431
ebml::start_tag(ebml_w, tag_items_data);
432+
index += [{val: crate_node_id, pos: ebml_w.writer.tell()}];
433+
encode_info_for_mod(ebml_w, crate_mod, crate_node_id);
422434
ecx.ccx.ast_map.items {|key, val|
423435
alt val {
424436
middle::ast_map::node_item(i) {
@@ -658,7 +670,7 @@ fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> str {
658670
// Encode and index the items.
659671

660672
ebml::start_tag(ebml_w, tag_items);
661-
let items_index = encode_info_for_items(ecx, ebml_w);
673+
let items_index = encode_info_for_items(ecx, ebml_w, crate.node.module);
662674
let items_buckets = create_index(items_index, hash_node_id);
663675
encode_index(ebml_w, items_buckets, write_int);
664676
ebml::end_tag(ebml_w);

src/comp/middle/ast_map.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ tag ast_node {
88
node_item(@item);
99
node_obj_ctor(@item);
1010
node_native_item(@native_item);
11+
node_method(@method);
1112
node_expr(@expr);
1213
// Locals are numbered, because the alias analysis needs to know in which
1314
// order they are introduced.
@@ -63,6 +64,9 @@ fn map_item(cx: ctx, i: @item) {
6364
cx.map.insert(i.id, node_item(i));
6465
alt i.node {
6566
item_obj(_, _, ctor_id) { cx.map.insert(ctor_id, node_obj_ctor(i)); }
67+
item_impl(_, _, ms) {
68+
for m in ms { cx.map.insert(m.node.id, node_method(m)); }
69+
}
6670
_ { }
6771
}
6872
}

0 commit comments

Comments
 (0)