Skip to content

Commit 1ed6a27

Browse files
committed
Change representation of type params to handle interface bounds
Issue #1227
1 parent 5930463 commit 1ed6a27

17 files changed

+317
-229
lines changed

src/comp/metadata/common.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const tag_items_data_item: uint = 0x09u;
2222

2323
const tag_items_data_item_family: uint = 0x0au;
2424

25-
const tag_items_data_item_ty_param_kinds: uint = 0x0bu;
25+
const tag_items_data_item_ty_param_bounds: uint = 0x0bu;
2626

2727
const tag_items_data_item_type: uint = 0x0cu;
2828

src/comp/metadata/csearch.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ fn get_impl_methods(cstore: cstore::cstore, def: ast::def_id)
8686
decoder::lookup_impl_methods(cdata, def.node, def.crate)
8787
}
8888

89-
fn get_type(tcx: ty::ctxt, def: ast::def_id) -> ty::ty_param_kinds_and_ty {
89+
fn get_type(tcx: ty::ctxt, def: ast::def_id) -> ty::ty_param_bounds_and_ty {
9090
let cstore = tcx.sess.get_cstore();
9191
let cnum = def.crate;
9292
let cdata = cstore::get_crate_data(cstore, cnum).data;

src/comp/metadata/decoder.rs

+33-48
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ export get_symbol;
1414
export get_tag_variants;
1515
export get_type;
1616
export get_type_param_count;
17-
export get_type_param_kinds;
1817
export lookup_def;
1918
export lookup_item_name;
2019
export resolve_path;
@@ -90,21 +89,22 @@ fn variant_tag_id(d: ebml::doc) -> ast::def_id {
9089
ret parse_def_id(ebml::doc_data(tagdoc));
9190
}
9291

92+
fn parse_external_def_id(this_cnum: ast::crate_num,
93+
extres: external_resolver, s: str) ->
94+
ast::def_id {
95+
let buf = str::bytes(s);
96+
let external_def_id = parse_def_id(buf);
97+
98+
99+
// This item was defined in the crate we're searching if it's has the
100+
// local crate number, otherwise we need to search a different crate
101+
if external_def_id.crate == ast::local_crate {
102+
ret {crate: this_cnum, node: external_def_id.node};
103+
} else { ret extres(external_def_id); }
104+
}
105+
93106
fn item_type(item: ebml::doc, this_cnum: ast::crate_num, tcx: ty::ctxt,
94107
extres: external_resolver) -> ty::t {
95-
fn parse_external_def_id(this_cnum: ast::crate_num,
96-
extres: external_resolver, s: str) ->
97-
ast::def_id {
98-
let buf = str::bytes(s);
99-
let external_def_id = parse_def_id(buf);
100-
101-
102-
// This item was defined in the crate we're searching if it's has the
103-
// local crate number, otherwise we need to search a different crate
104-
if external_def_id.crate == ast::local_crate {
105-
ret {crate: this_cnum, node: external_def_id.node};
106-
} else { ret extres(external_def_id); }
107-
}
108108
let tp = ebml::get_doc(item, tag_items_data_item_type);
109109
let def_parser = bind parse_external_def_id(this_cnum, extres, _);
110110
let t = parse_ty_data(item.data, this_cnum, tp.start, tp.end - tp.start,
@@ -115,32 +115,24 @@ fn item_type(item: ebml::doc, this_cnum: ast::crate_num, tcx: ty::ctxt,
115115
t
116116
}
117117

118-
fn item_ty_param_kinds(item: ebml::doc) -> [ast::kind] {
119-
let ks: [ast::kind] = [];
120-
let tp = tag_items_data_item_ty_param_kinds;
121-
ebml::tagged_docs(item, tp) {|p|
122-
let dat: [u8] = ebml::doc_data(p);
123-
let vi = ebml::vint_at(dat, 0u);
124-
let i = 0u;
125-
while i < vi.val {
126-
let k =
127-
alt dat[vi.next + i] as char {
128-
's' { ast::kind_sendable }
129-
'c' { ast::kind_copyable }
130-
'a' { ast::kind_noncopyable }
131-
};
132-
ks += [k];
133-
i += 1u;
134-
}
135-
};
136-
ret ks;
118+
fn item_ty_param_bounds(item: ebml::doc, this_cnum: ast::crate_num,
119+
tcx: ty::ctxt, extres: external_resolver)
120+
-> [@[ty::param_bound]] {
121+
let bounds = [];
122+
let def_parser = bind parse_external_def_id(this_cnum, extres, _);
123+
ebml::tagged_docs(item, tag_items_data_item_ty_param_bounds) {|p|
124+
bounds += [tydecode::parse_bounds_data(@ebml::doc_data(p), this_cnum,
125+
def_parser, tcx)];
126+
}
127+
bounds
137128
}
138129

139130
fn item_ty_param_count(item: ebml::doc) -> uint {
140131
let n = 0u;
141-
let tp = tag_items_data_item_ty_param_kinds;
142-
ebml::tagged_docs(item, tp) {|p|
143-
n += ebml::vint_at(ebml::doc_data(p), 0u).val;
132+
ebml::tagged_docs(item, tag_items_data_item_ty_param_bounds) {|p|
133+
for byte in ebml::doc_data(p) {
134+
if byte as char == '.' { n += 1u; }
135+
}
144136
}
145137
n
146138
}
@@ -213,28 +205,21 @@ fn lookup_def(cnum: ast::crate_num, data: @[u8], did_: ast::def_id) ->
213205
}
214206

215207
fn get_type(data: @[u8], def: ast::def_id, tcx: ty::ctxt,
216-
extres: external_resolver) -> ty::ty_param_kinds_and_ty {
208+
extres: external_resolver) -> ty::ty_param_bounds_and_ty {
217209
let this_cnum = def.crate;
218210
let node_id = def.node;
219211
let item = lookup_item(node_id, data);
220212
let t = item_type(item, this_cnum, tcx, extres);
221-
let tp_kinds: [ast::kind];
222-
let fam_ch = item_family(item);
223-
let has_ty_params = family_has_type_params(fam_ch);
224-
if has_ty_params {
225-
tp_kinds = item_ty_param_kinds(item);
226-
} else { tp_kinds = []; }
227-
ret {kinds: tp_kinds, ty: t};
213+
let tp_bounds = if family_has_type_params(item_family(item)) {
214+
item_ty_param_bounds(item, this_cnum, tcx, extres)
215+
} else { [] };
216+
ret {bounds: tp_bounds, ty: t};
228217
}
229218

230219
fn get_type_param_count(data: @[u8], id: ast::node_id) -> uint {
231220
item_ty_param_count(lookup_item(id, data))
232221
}
233222

234-
fn get_type_param_kinds(data: @[u8], id: ast::node_id) -> [ast::kind] {
235-
ret item_ty_param_kinds(lookup_item(id, data));
236-
}
237-
238223
fn get_symbol(data: @[u8], id: ast::node_id) -> str {
239224
ret item_symbol(lookup_item(id, data));
240225
}

src/comp/metadata/encoder.rs

+22-24
Original file line numberDiff line numberDiff line change
@@ -183,18 +183,17 @@ fn encode_family(ebml_w: ebml::writer, c: u8) {
183183

184184
fn def_to_str(did: def_id) -> str { ret #fmt["%d:%d", did.crate, did.node]; }
185185

186-
fn encode_type_param_kinds(ebml_w: ebml::writer, tps: [ty_param]) {
187-
ebml::start_tag(ebml_w, tag_items_data_item_ty_param_kinds);
188-
ebml::write_vint(ebml_w.writer, vec::len::<ty_param>(tps));
189-
for tp: ty_param in tps {
190-
let c = alt ast_util::ty_param_kind(tp) {
191-
kind_sendable. { 's' }
192-
kind_copyable. { 'c' }
193-
kind_noncopyable. { 'a' }
194-
};
195-
ebml_w.writer.write([c as u8]);
186+
fn encode_type_param_bounds(ebml_w: ebml::writer, ecx: @encode_ctxt,
187+
params: [ty_param]) {
188+
let ty_str_ctxt = @{ds: def_to_str,
189+
tcx: ecx.ccx.tcx,
190+
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
191+
for param in params {
192+
ebml::start_tag(ebml_w, tag_items_data_item_ty_param_bounds);
193+
let bs = ecx.ccx.tcx.ty_param_bounds.get(local_def(param.id));
194+
tyencode::enc_bounds(io::new_writer(ebml_w.writer), ty_str_ctxt, bs);
195+
ebml::end_tag(ebml_w);
196196
}
197-
ebml::end_tag(ebml_w);
198197
}
199198

200199
fn encode_variant_id(ebml_w: ebml::writer, vid: def_id) {
@@ -205,9 +204,8 @@ fn encode_variant_id(ebml_w: ebml::writer, vid: def_id) {
205204

206205
fn encode_type(ecx: @encode_ctxt, ebml_w: ebml::writer, typ: ty::t) {
207206
ebml::start_tag(ebml_w, tag_items_data_item_type);
208-
let f = def_to_str;
209207
let ty_str_ctxt =
210-
@{ds: f,
208+
@{ds: def_to_str,
211209
tcx: ecx.ccx.tcx,
212210
abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
213211
tyencode::enc_ty(io::new_writer(ebml_w.writer), ty_str_ctxt, typ);
@@ -247,7 +245,7 @@ fn encode_tag_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
247245
encode_symbol(ecx, ebml_w, variant.node.id);
248246
}
249247
encode_discriminant(ecx, ebml_w, variant.node.id);
250-
encode_type_param_kinds(ebml_w, ty_params);
248+
encode_type_param_bounds(ebml_w, ecx, ty_params);
251249
ebml::end_tag(ebml_w);
252250
}
253251
}
@@ -293,7 +291,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
293291
pure_fn. { 'p' }
294292
impure_fn. { 'f' }
295293
} as u8);
296-
encode_type_param_kinds(ebml_w, tps);
294+
encode_type_param_bounds(ebml_w, ecx, tps);
297295
encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
298296
encode_symbol(ecx, ebml_w, item.id);
299297
ebml::end_tag(ebml_w);
@@ -312,7 +310,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
312310
ebml::start_tag(ebml_w, tag_items_data_item);
313311
encode_def_id(ebml_w, local_def(item.id));
314312
encode_family(ebml_w, 'y' as u8);
315-
encode_type_param_kinds(ebml_w, tps);
313+
encode_type_param_bounds(ebml_w, ecx, tps);
316314
encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
317315
encode_name(ebml_w, item.ident);
318316
ebml::end_tag(ebml_w);
@@ -321,7 +319,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
321319
ebml::start_tag(ebml_w, tag_items_data_item);
322320
encode_def_id(ebml_w, local_def(item.id));
323321
encode_family(ebml_w, 't' as u8);
324-
encode_type_param_kinds(ebml_w, tps);
322+
encode_type_param_bounds(ebml_w, ecx, tps);
325323
encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
326324
encode_name(ebml_w, item.ident);
327325
for v: variant in variants {
@@ -336,7 +334,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
336334
ebml::start_tag(ebml_w, tag_items_data_item);
337335
encode_def_id(ebml_w, local_def(ctor_id));
338336
encode_family(ebml_w, 'y' as u8);
339-
encode_type_param_kinds(ebml_w, tps);
337+
encode_type_param_bounds(ebml_w, ecx, tps);
340338
encode_type(ecx, ebml_w, ty::ty_fn_ret(ecx.ccx.tcx, fn_ty));
341339
encode_name(ebml_w, item.ident);
342340
encode_symbol(ecx, ebml_w, item.id);
@@ -346,7 +344,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
346344
ebml::start_tag(ebml_w, tag_items_data_item);
347345
encode_def_id(ebml_w, local_def(ctor_id));
348346
encode_family(ebml_w, 'f' as u8);
349-
encode_type_param_kinds(ebml_w, tps);
347+
encode_type_param_bounds(ebml_w, ecx, tps);
350348
encode_type(ecx, ebml_w, fn_ty);
351349
encode_symbol(ecx, ebml_w, ctor_id);
352350
ebml::end_tag(ebml_w);
@@ -357,7 +355,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
357355
ebml::start_tag(ebml_w, tag_items_data_item);
358356
encode_def_id(ebml_w, local_def(item.id));
359357
encode_family(ebml_w, 'y' as u8);
360-
encode_type_param_kinds(ebml_w, tps);
358+
encode_type_param_bounds(ebml_w, ecx, tps);
361359
encode_type(ecx, ebml_w, ty::ty_fn_ret(ecx.ccx.tcx, fn_ty));
362360
encode_name(ebml_w, item.ident);
363361
ebml::end_tag(ebml_w);
@@ -366,7 +364,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
366364
ebml::start_tag(ebml_w, tag_items_data_item);
367365
encode_def_id(ebml_w, local_def(ctor_id));
368366
encode_family(ebml_w, 'f' as u8);
369-
encode_type_param_kinds(ebml_w, tps);
367+
encode_type_param_bounds(ebml_w, ecx, tps);
370368
encode_type(ecx, ebml_w, fn_ty);
371369
encode_symbol(ecx, ebml_w, ctor_id);
372370
ebml::end_tag(ebml_w);
@@ -375,7 +373,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
375373
ebml::start_tag(ebml_w, tag_items_data_item);
376374
encode_def_id(ebml_w, local_def(item.id));
377375
encode_family(ebml_w, 'i' as u8);
378-
encode_type_param_kinds(ebml_w, tps);
376+
encode_type_param_bounds(ebml_w, ecx, tps);
379377
encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id));
380378
encode_name(ebml_w, item.ident);
381379
for m in methods {
@@ -390,7 +388,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
390388
ebml::start_tag(ebml_w, tag_items_data_item);
391389
encode_def_id(ebml_w, local_def(m.id));
392390
encode_family(ebml_w, 'f' as u8);
393-
encode_type_param_kinds(ebml_w, tps + m.tps);
391+
encode_type_param_bounds(ebml_w, ecx, tps + m.tps);
394392
encode_type(ecx, ebml_w,
395393
node_id_to_monotype(ecx.ccx.tcx, m.id));
396394
encode_name(ebml_w, m.ident);
@@ -421,7 +419,7 @@ fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer,
421419
} as u8;
422420
encode_def_id(ebml_w, local_def(nitem.id));
423421
encode_family(ebml_w, letter);
424-
encode_type_param_kinds(ebml_w, tps);
422+
encode_type_param_bounds(ebml_w, ecx, tps);
425423
encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, nitem.id));
426424
encode_symbol(ecx, ebml_w, nitem.id);
427425
}

src/comp/metadata/tydecode.rs

+27-15
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import middle::ty;
1010

1111
export parse_def_id;
1212
export parse_ty_data;
13+
export parse_bounds_data;
1314

1415
// Compact string representation for ty::t values. API ty_str &
1516
// parse_from_str. Extra parameters are for converting to/from def_ids in the
@@ -21,7 +22,9 @@ type str_def = fn@(str) -> ast::def_id;
2122
type pstate =
2223
{data: @[u8], crate: int, mutable pos: uint, len: uint, tcx: ty::ctxt};
2324

24-
fn peek(st: @pstate) -> u8 { ret st.data[st.pos]; }
25+
fn peek(st: @pstate) -> u8 {
26+
if st.pos < vec::len(*st.data) { st.data[st.pos] } else { 0u8 }
27+
}
2528

2629
fn next(st: @pstate) -> u8 {
2730
let ch = st.data[st.pos];
@@ -48,8 +51,7 @@ fn parse_ty_data(data: @[u8], crate_num: int, pos: uint, len: uint,
4851
sd: str_def, tcx: ty::ctxt) -> ty::t {
4952
let st =
5053
@{data: data, crate: crate_num, mutable pos: pos, len: len, tcx: tcx};
51-
let result = parse_ty(st, sd);
52-
ret result;
54+
parse_ty(st, sd)
5355
}
5456

5557
fn parse_ret_ty(st: @pstate, sd: str_def) -> (ast::ret_style, ty::t) {
@@ -201,18 +203,8 @@ fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
201203
ret ty::mk_tag(st.tcx, def, params);
202204
}
203205
'p' {
204-
let k =
205-
alt next(st) as char {
206-
's' { kind_sendable }
207-
'c' { kind_copyable }
208-
'a' { kind_noncopyable }
209-
c {
210-
#error("unexpected char in encoded type param: ");
211-
log(error, c);
212-
fail
213-
}
214-
};
215-
ret ty::mk_param(st.tcx, parse_int(st) as uint, k);
206+
let bounds = parse_bounds(st, sd);
207+
ret ty::mk_param(st.tcx, parse_int(st) as uint, bounds);
216208
}
217209
'@' { ret ty::mk_box(st.tcx, parse_mt(st, sd)); }
218210
'~' { ret ty::mk_uniq(st.tcx, parse_mt(st, sd)); }
@@ -400,6 +392,26 @@ fn parse_def_id(buf: [u8]) -> ast::def_id {
400392
ret {crate: crate_num, node: def_num};
401393
}
402394

395+
fn parse_bounds_data(data: @[u8], crate_num: int, sd: str_def, tcx: ty::ctxt)
396+
-> @[ty::param_bound] {
397+
let st = @{data: data, crate: crate_num, mutable pos: 0u,
398+
len: vec::len(*data), tcx: tcx};
399+
parse_bounds(st, sd)
400+
}
401+
402+
fn parse_bounds(st: @pstate, sd: str_def) -> @[ty::param_bound] {
403+
let bounds = [];
404+
while peek(st) as char == '.' {
405+
next(st);
406+
bounds += [alt next(st) as char {
407+
'S' { ty::bound_send }
408+
'C' { ty::bound_copy }
409+
'I' { ty::bound_iface(parse_ty(st, sd)) }
410+
}];
411+
}
412+
@bounds
413+
}
414+
403415
//
404416
// Local Variables:
405417
// mode: rust

0 commit comments

Comments
 (0)