Skip to content

Commit 3a20dda

Browse files
committed
Get external interfaces / impls working
Issue #1227
1 parent 38c3bd9 commit 3a20dda

File tree

10 files changed

+152
-109
lines changed

10 files changed

+152
-109
lines changed

src/comp/metadata/common.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,9 @@ const tag_crate_hash: uint = 0x28u;
6666

6767
const tag_mod_impl: uint = 0x30u;
6868

69-
const tag_impl_method: uint = 0x31u;
69+
const tag_item_method: uint = 0x31u;
7070
const tag_impl_iface: uint = 0x32u;
71+
const tag_impl_iface_did: uint = 0x33u;
7172

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

src/comp/metadata/csearch.rs

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export get_type_param_count;
1010
export lookup_defs;
1111
export get_tag_variants;
1212
export get_impls_for_mod;
13-
export get_impl_methods;
13+
export get_iface_methods;
1414
export get_type;
1515
export get_item_name;
1616
export get_impl_iface;
@@ -66,33 +66,23 @@ fn get_tag_variants(tcx: ty::ctxt, def: ast::def_id) -> [ty::variant_info] {
6666

6767
fn get_impls_for_mod(cstore: cstore::cstore, def: ast::def_id,
6868
name: option::t<ast::ident>)
69-
-> [@middle::resolve::_impl] {
69+
-> @[@middle::resolve::_impl] {
7070
let cdata = cstore::get_crate_data(cstore, def.crate).data;
71-
let result = [];
72-
for did in decoder::get_impls_for_mod(cdata, def.node, def.crate) {
73-
let nm = decoder::lookup_item_name(cdata, did.node);
74-
if alt name { some(n) { n == nm } none. { true } } {
75-
result += [@{did: did,
76-
iface_did: none::<ast::def_id>, // FIXME[impl]
77-
ident: nm,
78-
methods: decoder::lookup_impl_methods(
79-
cdata, did.node, did.crate)}];
80-
}
81-
}
82-
result
71+
let resolver = bind translate_def_id(cstore, def.crate, _);
72+
decoder::get_impls_for_mod(cdata, def, name, resolver)
8373
}
8474

85-
fn get_impl_methods(cstore: cstore::cstore, def: ast::def_id)
86-
-> [@middle::resolve::method_info] {
75+
fn get_iface_methods(tcx: ty::ctxt, def: ast::def_id) -> @[ty::method] {
76+
let cstore = tcx.sess.get_cstore();
8777
let cdata = cstore::get_crate_data(cstore, def.crate).data;
88-
decoder::lookup_impl_methods(cdata, def.node, def.crate)
78+
let resolver = bind translate_def_id(cstore, def.crate, _);
79+
decoder::get_iface_methods(cdata, def, tcx, resolver)
8980
}
9081

9182
fn get_type(tcx: ty::ctxt, def: ast::def_id) -> ty::ty_param_bounds_and_ty {
9283
let cstore = tcx.sess.get_cstore();
93-
let cnum = def.crate;
94-
let cdata = cstore::get_crate_data(cstore, cnum).data;
95-
let resolver = bind translate_def_id(cstore, cnum, _);
84+
let cdata = cstore::get_crate_data(cstore, def.crate).data;
85+
let resolver = bind translate_def_id(cstore, def.crate, _);
9686
decoder::get_type(cdata, def, tcx, resolver)
9787
}
9888

src/comp/metadata/decoder.rs

Lines changed: 72 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export get_crate_deps;
2626
export get_crate_hash;
2727
export external_resolver;
2828
export get_impls_for_mod;
29-
export lookup_impl_methods;
29+
export get_iface_methods;
3030
// A function that takes a def_id relative to the crate being searched and
3131
// returns a def_id relative to the compilation environment, i.e. if we hit a
3232
// def_id for an item defined in another crate, somebody needs to figure out
@@ -105,38 +105,52 @@ fn parse_external_def_id(this_cnum: ast::crate_num,
105105
} else { ret extres(external_def_id); }
106106
}
107107

108+
fn doc_type(doc: ebml::doc, this_cnum: ast::crate_num, tcx: ty::ctxt,
109+
extres: external_resolver) -> ty::t {
110+
let tp = ebml::get_doc(doc, tag_items_data_item_type);
111+
let def_parser = bind parse_external_def_id(this_cnum, extres, _);
112+
parse_ty_data(tp.data, this_cnum, tp.start, def_parser, tcx)
113+
}
114+
108115
fn item_type(item: ebml::doc, this_cnum: ast::crate_num, tcx: ty::ctxt,
109116
extres: external_resolver) -> ty::t {
110-
let tp = ebml::get_doc(item, tag_items_data_item_type);
111-
let def_parser = bind parse_external_def_id(this_cnum, extres, _);
112-
let t = parse_ty_data(item.data, this_cnum, tp.start, tp.end - tp.start,
113-
def_parser, tcx);
117+
let t = doc_type(item, this_cnum, tcx, extres);
114118
if family_names_type(item_family(item)) {
115-
t = ty::mk_named(tcx, t, @item_name(item));
116-
}
117-
t
119+
ty::mk_named(tcx, t, @item_name(item))
120+
} else { t }
118121
}
119122

120123
fn item_impl_iface(item: ebml::doc, this_cnum: ast::crate_num, tcx: ty::ctxt,
121124
extres: external_resolver) -> option::t<ty::t> {
122125
let result = none;
123126
ebml::tagged_docs(item, tag_impl_iface) {|ity|
124127
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);
128+
let t = parse_ty_data(ity.data, this_cnum, ity.start, def_parser,
129+
tcx);
127130
result = some(t);
128131
}
129132
result
130133
}
131134

135+
fn item_impl_iface_did(item: ebml::doc, this_cnum: ast::crate_num,
136+
extres: external_resolver)
137+
-> option::t<ast::def_id> {
138+
let result = none;
139+
ebml::tagged_docs(item, tag_impl_iface_did) {|doc|
140+
let s = str::unsafe_from_bytes(ebml::doc_data(doc));
141+
result = some(parse_external_def_id(this_cnum, extres, s));
142+
}
143+
result
144+
}
145+
132146
fn item_ty_param_bounds(item: ebml::doc, this_cnum: ast::crate_num,
133147
tcx: ty::ctxt, extres: external_resolver)
134148
-> @[ty::param_bounds] {
135149
let bounds = [];
136150
let def_parser = bind parse_external_def_id(this_cnum, extres, _);
137151
ebml::tagged_docs(item, tag_items_data_item_ty_param_bounds) {|p|
138-
bounds += [tydecode::parse_bounds_data(@ebml::doc_data(p), this_cnum,
139-
def_parser, tcx)];
152+
bounds += [tydecode::parse_bounds_data(p.data, p.start,
153+
this_cnum, def_parser, tcx)];
140154
}
141155
@bounds
142156
}
@@ -211,18 +225,17 @@ fn lookup_def(cnum: ast::crate_num, data: @[u8], did_: ast::def_id) ->
211225
tid = {crate: cnum, node: tid.node};
212226
ast::def_variant(tid, did)
213227
}
228+
'I' { ast::def_ty(did) }
214229
};
215230
ret def;
216231
}
217232

218233
fn get_type(data: @[u8], def: ast::def_id, tcx: ty::ctxt,
219234
extres: external_resolver) -> ty::ty_param_bounds_and_ty {
220-
let this_cnum = def.crate;
221-
let node_id = def.node;
222-
let item = lookup_item(node_id, data);
223-
let t = item_type(item, this_cnum, tcx, extres);
235+
let item = lookup_item(def.node, data);
236+
let t = item_type(item, def.crate, tcx, extres);
224237
let tp_bounds = if family_has_type_params(item_family(item)) {
225-
item_ty_param_bounds(item, this_cnum, tcx, extres)
238+
item_ty_param_bounds(item, def.crate, tcx, extres)
226239
} else { @[] };
227240
ret {bounds: tp_bounds, ty: t};
228241
}
@@ -264,51 +277,59 @@ fn get_tag_variants(_data: @[u8], def: ast::def_id, tcx: ty::ctxt,
264277
ret infos;
265278
}
266279

267-
fn get_impls_for_mod(data: @[u8], node: ast::node_id, cnum: ast::crate_num)
268-
-> [ast::def_id] {
269-
let mod_item = lookup_item(node, data), result = [];
270-
ebml::tagged_docs(mod_item, tag_mod_impl) {|doc|
271-
let did = parse_def_id(ebml::doc_data(doc));
272-
result += [{crate: cnum with did}];
273-
}
274-
result
275-
}
276-
277-
fn lookup_impl_methods(data: @[u8], node: ast::node_id, cnum: ast::crate_num)
280+
fn item_impl_methods(data: @[u8], item: ebml::doc, base_tps: uint)
278281
-> [@middle::resolve::method_info] {
279-
let impl_item = lookup_item(node, data), rslt = [];
280-
let base_tps = item_ty_param_count(impl_item);
281-
ebml::tagged_docs(impl_item, tag_impl_method) {|doc|
282+
let rslt = [];
283+
ebml::tagged_docs(item, tag_item_method) {|doc|
282284
let m_did = parse_def_id(ebml::doc_data(doc));
283285
let mth_item = lookup_item(m_did.node, data);
284-
rslt += [@{did: {crate: cnum, node: m_did.node},
286+
rslt += [@{did: m_did,
285287
n_tps: item_ty_param_count(mth_item) - base_tps,
286288
ident: item_name(mth_item)}];
287289
}
288290
rslt
289291
}
290292

293+
fn get_impls_for_mod(data: @[u8], m_def: ast::def_id,
294+
name: option::t<ast::ident>, extres: external_resolver)
295+
-> @[@middle::resolve::_impl] {
296+
let mod_item = lookup_item(m_def.node, data), result = [];
297+
ebml::tagged_docs(mod_item, tag_mod_impl) {|doc|
298+
let did = parse_external_def_id(
299+
m_def.crate, extres, str::unsafe_from_bytes(ebml::doc_data(doc)));
300+
let item = lookup_item(did.node, data), nm = item_name(item);
301+
if alt name { some(n) { n == nm } none. { true } } {
302+
let base_tps = item_ty_param_count(doc);
303+
let i_did = item_impl_iface_did(item, m_def.crate, extres);
304+
result += [@{did: did, iface_did: i_did, ident: nm,
305+
methods: item_impl_methods(data, doc, base_tps)}];
306+
}
307+
}
308+
@result
309+
}
310+
311+
fn get_iface_methods(data: @[u8], def: ast::def_id, tcx: ty::ctxt,
312+
extres: external_resolver) -> @[ty::method] {
313+
let item = lookup_item(def.node, data), result = [];
314+
ebml::tagged_docs(item, tag_item_method) {|mth|
315+
let bounds = item_ty_param_bounds(mth, def.crate, tcx, extres);
316+
let name = item_name(mth);
317+
let ty = doc_type(mth, def.crate, tcx, extres);
318+
let fty = alt ty::struct(tcx, ty) { ty::ty_fn(f) { f } };
319+
result += [{ident: name, tps: bounds, fty: fty}];
320+
}
321+
@result
322+
}
323+
291324
fn family_has_type_params(fam_ch: u8) -> bool {
292-
ret alt fam_ch as char {
293-
'c' { false }
294-
'f' { true }
295-
'u' { true }
296-
'p' { true }
297-
'F' { true }
298-
'U' { true }
299-
'P' { true }
300-
'y' { true }
301-
't' { true }
302-
'T' { false }
303-
'm' { false }
304-
'n' { false }
305-
'v' { true }
306-
'i' { true }
307-
};
325+
alt fam_ch as char {
326+
'c' | 'T' | 'm' | 'n' { false }
327+
'f' | 'u' | 'p' | 'F' | 'U' | 'P' | 'y' | 't' | 'v' | 'i' | 'I' { true }
328+
}
308329
}
309330

310331
fn family_names_type(fam_ch: u8) -> bool {
311-
alt fam_ch as char { 'y' | 't' { true } _ { false } }
332+
alt fam_ch as char { 'y' | 't' | 'I' { true } _ { false } }
312333
}
313334

314335
fn read_path(d: ebml::doc) -> {path: str, pos: uint} {
@@ -339,6 +360,8 @@ fn item_family_to_str(fam: u8) -> str {
339360
'm' { ret "mod"; }
340361
'n' { ret "native mod"; }
341362
'v' { ret "tag"; }
363+
'i' { ret "impl"; }
364+
'I' { ret "iface"; }
342365
}
343366
}
344367

src/comp/metadata/encoder.rs

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -277,12 +277,13 @@ fn encode_info_for_mod(ebml_w: ebml::writer, md: _mod,
277277

278278
fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
279279
&index: [entry<int>]) {
280+
let tcx = ecx.ccx.tcx;
280281
alt item.node {
281282
item_const(_, _) {
282283
ebml::start_tag(ebml_w, tag_items_data_item);
283284
encode_def_id(ebml_w, local_def(item.id));
284285
encode_family(ebml_w, 'c' as u8);
285-
encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
286+
encode_type(ecx, ebml_w, node_id_to_monotype(tcx, item.id));
286287
encode_symbol(ecx, ebml_w, item.id);
287288
ebml::end_tag(ebml_w);
288289
}
@@ -296,7 +297,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
296297
impure_fn. { 'f' }
297298
} as u8);
298299
encode_type_param_bounds(ebml_w, ecx, tps);
299-
encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
300+
encode_type(ecx, ebml_w, node_id_to_monotype(tcx, item.id));
300301
encode_symbol(ecx, ebml_w, item.id);
301302
ebml::end_tag(ebml_w);
302303
}
@@ -315,7 +316,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
315316
encode_def_id(ebml_w, local_def(item.id));
316317
encode_family(ebml_w, 'y' as u8);
317318
encode_type_param_bounds(ebml_w, ecx, tps);
318-
encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
319+
encode_type(ecx, ebml_w, node_id_to_monotype(tcx, item.id));
319320
encode_name(ebml_w, item.ident);
320321
ebml::end_tag(ebml_w);
321322
}
@@ -324,7 +325,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
324325
encode_def_id(ebml_w, local_def(item.id));
325326
encode_family(ebml_w, 't' as u8);
326327
encode_type_param_bounds(ebml_w, ecx, tps);
327-
encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
328+
encode_type(ecx, ebml_w, node_id_to_monotype(tcx, item.id));
328329
encode_name(ebml_w, item.ident);
329330
for v: variant in variants {
330331
encode_variant_id(ebml_w, local_def(v.node.id));
@@ -333,13 +334,13 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
333334
encode_tag_variant_info(ecx, ebml_w, item.id, variants, index, tps);
334335
}
335336
item_res(_, tps, _, _, ctor_id) {
336-
let fn_ty = node_id_to_monotype(ecx.ccx.tcx, ctor_id);
337+
let fn_ty = node_id_to_monotype(tcx, ctor_id);
337338

338339
ebml::start_tag(ebml_w, tag_items_data_item);
339340
encode_def_id(ebml_w, local_def(ctor_id));
340341
encode_family(ebml_w, 'y' as u8);
341342
encode_type_param_bounds(ebml_w, ecx, tps);
342-
encode_type(ecx, ebml_w, ty::ty_fn_ret(ecx.ccx.tcx, fn_ty));
343+
encode_type(ecx, ebml_w, ty::ty_fn_ret(tcx, fn_ty));
343344
encode_name(ebml_w, item.ident);
344345
encode_symbol(ecx, ebml_w, item.id);
345346
ebml::end_tag(ebml_w);
@@ -354,13 +355,13 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
354355
ebml::end_tag(ebml_w);
355356
}
356357
item_obj(_, tps, ctor_id) {
357-
let fn_ty = node_id_to_monotype(ecx.ccx.tcx, ctor_id);
358+
let fn_ty = node_id_to_monotype(tcx, ctor_id);
358359

359360
ebml::start_tag(ebml_w, tag_items_data_item);
360361
encode_def_id(ebml_w, local_def(item.id));
361362
encode_family(ebml_w, 'y' as u8);
362363
encode_type_param_bounds(ebml_w, ecx, tps);
363-
encode_type(ecx, ebml_w, ty::ty_fn_ret(ecx.ccx.tcx, fn_ty));
364+
encode_type(ecx, ebml_w, ty::ty_fn_ret(tcx, fn_ty));
364365
encode_name(ebml_w, item.ident);
365366
ebml::end_tag(ebml_w);
366367

@@ -378,18 +379,26 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
378379
encode_def_id(ebml_w, local_def(item.id));
379380
encode_family(ebml_w, 'i' as u8);
380381
encode_type_param_bounds(ebml_w, ecx, tps);
381-
encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
382+
encode_type(ecx, ebml_w, node_id_to_monotype(tcx, item.id));
382383
encode_name(ebml_w, item.ident);
383384
for m in methods {
384-
ebml::start_tag(ebml_w, tag_impl_method);
385+
ebml::start_tag(ebml_w, tag_item_method);
385386
ebml_w.writer.write(str::bytes(def_to_str(local_def(m.id))));
386387
ebml::end_tag(ebml_w);
387388
}
388389
alt ifce {
389390
some(_) {
391+
encode_symbol(ecx, ebml_w, item.id);
392+
let i_ty = ty::lookup_item_type(tcx, local_def(item.id)).ty;
390393
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);
394+
write_type(ecx, ebml_w, i_ty);
395+
ebml::end_tag(ebml_w);
396+
ebml::start_tag(ebml_w, tag_impl_iface_did);
397+
alt ty::struct(tcx, i_ty) {
398+
ty::ty_iface(did, _) {
399+
ebml_w.writer.write(str::bytes(def_to_str(did)));
400+
}
401+
}
393402
ebml::end_tag(ebml_w);
394403
}
395404
_ {}
@@ -403,13 +412,30 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
403412
encode_family(ebml_w, 'f' as u8);
404413
encode_type_param_bounds(ebml_w, ecx, tps + m.tps);
405414
encode_type(ecx, ebml_w,
406-
node_id_to_monotype(ecx.ccx.tcx, m.id));
415+
node_id_to_monotype(tcx, m.id));
407416
encode_name(ebml_w, m.ident);
408417
encode_symbol(ecx, ebml_w, m.id);
409418
ebml::end_tag(ebml_w);
410419
}
411420
}
412-
item_iface(_, _) { /* FIXME[impl] */ }
421+
item_iface(tps, ms) {
422+
ebml::start_tag(ebml_w, tag_items_data_item);
423+
encode_def_id(ebml_w, local_def(item.id));
424+
encode_family(ebml_w, 'I' as u8);
425+
encode_type_param_bounds(ebml_w, ecx, tps);
426+
encode_type(ecx, ebml_w, node_id_to_monotype(tcx, item.id));
427+
encode_name(ebml_w, item.ident);
428+
let i = 0u;
429+
for mty in *ty::iface_methods(tcx, local_def(item.id)) {
430+
ebml::start_tag(ebml_w, tag_item_method);
431+
encode_name(ebml_w, mty.ident);
432+
encode_type_param_bounds(ebml_w, ecx, ms[i].tps);
433+
encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty));
434+
ebml::end_tag(ebml_w);
435+
i += 1u;
436+
}
437+
ebml::end_tag(ebml_w);
438+
}
413439
}
414440
}
415441

0 commit comments

Comments
 (0)