Skip to content

Commit 057617c

Browse files
committed
Parse iface items and interface references in impl items.
The (temporary) syntax is iface seq<T> { fn len() -> uint; fn iter(f: block(T)); } // The 'blah<T>' can be left of to default the name of the // impl to seq<T>. The 'of seq<T>' can be left off when // not implementing a named interface. impl blah<T> of seq<T> for [T] { fn len() -> uint { vec::len(self) } fn iter(f: block(T)) { for x in self { f(x); } } }
1 parent 9292744 commit 057617c

File tree

12 files changed

+209
-139
lines changed

12 files changed

+209
-139
lines changed

src/comp/metadata/encoder.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ fn encode_native_module_item_paths(ebml_w: ebml::writer, nmod: native_mod,
6464

6565
fn encode_module_item_paths(ebml_w: ebml::writer, module: _mod, path: [str],
6666
&index: [entry<str>]) {
67+
// FIXME factor out add_to_index/start/encode_name/encode_def_id/end ops
6768
for it: @item in module.items {
6869
if !ast_util::is_exported(it.ident, module) { cont; }
6970
alt it.node {
@@ -137,7 +138,14 @@ fn encode_module_item_paths(ebml_w: ebml::writer, module: _mod, path: [str],
137138
encode_def_id(ebml_w, local_def(it.id));
138139
ebml::end_tag(ebml_w);
139140
}
140-
item_impl(_, _, _) {}
141+
item_iface(_, _) {
142+
add_to_index(ebml_w, path, index, it.ident);
143+
ebml::start_tag(ebml_w, tag_paths_data_item);
144+
encode_name(ebml_w, it.ident);
145+
encode_def_id(ebml_w, local_def(it.id));
146+
ebml::end_tag(ebml_w);
147+
}
148+
item_impl(_, _, _, _) {}
141149
}
142150
}
143151
}
@@ -252,7 +260,7 @@ fn encode_info_for_mod(ebml_w: ebml::writer, md: _mod,
252260
encode_name(ebml_w, name);
253261
for i in md.items {
254262
alt i.node {
255-
item_impl(_, _, _) {
263+
item_impl(_, _, _, _) {
256264
if ast_util::is_exported(i.ident, md) {
257265
ebml::start_tag(ebml_w, tag_mod_impl);
258266
ebml_w.writer.write(str::bytes(def_to_str(local_def(i.id))));
@@ -363,7 +371,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
363371
encode_symbol(ecx, ebml_w, ctor_id);
364372
ebml::end_tag(ebml_w);
365373
}
366-
item_impl(tps, _, methods) {
374+
item_impl(tps, _, _, methods) {
367375
ebml::start_tag(ebml_w, tag_items_data_item);
368376
encode_def_id(ebml_w, local_def(item.id));
369377
encode_family(ebml_w, 'i' as u8);
@@ -390,6 +398,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
390398
ebml::end_tag(ebml_w);
391399
}
392400
}
401+
item_iface(_, _) { /* FIXME[impl] */ }
393402
}
394403
}
395404

src/comp/middle/ast_map.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ fn map_item(cx: ctx, i: @item) {
7171
cx.map.insert(m.id, node_obj_method(m));
7272
}
7373
}
74-
item_impl(_, _, ms) {
74+
item_impl(_, _, _, ms) {
7575
for m in ms { cx.map.insert(m.id, node_method(m)); }
7676
}
7777
item_res(_, _, _, dtor_id, ctor_id) {

src/comp/middle/resolve.rs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,9 @@ fn resolve_names(e: @env, c: @ast::crate) {
401401
fn visit_item_with_scope(i: @ast::item, sc: scopes, v: vt<scopes>) {
402402
let sc = cons(scope_item(i), @sc);
403403
alt i.node {
404-
ast::item_impl(tps, sty, methods) {
405-
visit::visit_ty(sty, sc, v);
404+
ast::item_impl(tps, ifce, sty, methods) {
405+
alt ifce { some(ty) { v.visit_ty(ty, sc, v); } _ {} }
406+
v.visit_ty(sty, sc, v);
406407
for m in methods {
407408
v.visit_fn_proto(m.decl, tps + m.tps, m.body, m.span,
408409
some(m.ident), m.id, sc, v);
@@ -802,24 +803,22 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace)
802803
ast::item_obj(ob, ty_params, _) {
803804
ret lookup_in_obj(name, ob, ty_params, ns, it.id);
804805
}
805-
ast::item_impl(ty_params, _, _) {
806+
ast::item_impl(ty_params, _, _, _) {
806807
if (name == "self" && ns == ns_value) {
807808
ret some(ast::def_self(local_def(it.id)));
808809
}
809810
if ns == ns_type { ret lookup_in_ty_params(name, ty_params); }
810811
}
811-
ast::item_tag(_, ty_params) {
812-
if ns == ns_type { ret lookup_in_ty_params(name, ty_params); }
812+
ast::item_iface(tps, _) | ast::item_tag(_, tps) |
813+
ast::item_ty(_, tps) {
814+
if ns == ns_type { ret lookup_in_ty_params(name, tps); }
813815
}
814816
ast::item_mod(_) {
815817
ret lookup_in_local_mod(e, it.id, sp, name, ns, inside);
816818
}
817819
ast::item_native_mod(m) {
818820
ret lookup_in_local_native_mod(e, it.id, sp, name, ns);
819821
}
820-
ast::item_ty(_, ty_params) {
821-
if ns == ns_type { ret lookup_in_ty_params(name, ty_params); }
822-
}
823822
_ { }
824823
}
825824
}
@@ -1064,7 +1063,7 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option::t<def> {
10641063
ast::item_native_mod(_) {
10651064
if ns == ns_module { ret some(ast::def_native_mod(local_def(i.id))); }
10661065
}
1067-
ast::item_ty(_, _) {
1066+
ast::item_ty(_, _) | item_iface(_, _) | item_tag(_, _) {
10681067
if ns == ns_type { ret some(ast::def_ty(local_def(i.id))); }
10691068
}
10701069
ast::item_res(_, _, _, _, ctor_id) {
@@ -1076,9 +1075,6 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option::t<def> {
10761075
_ { }
10771076
}
10781077
}
1079-
ast::item_tag(_, _) {
1080-
if ns == ns_type { ret some(ast::def_ty(local_def(i.id))); }
1081-
}
10821078
ast::item_obj(_, _, ctor_id) {
10831079
alt ns {
10841080
ns_value. {
@@ -1322,7 +1318,7 @@ fn index_mod(md: ast::_mod) -> mod_index {
13221318
ast::item_const(_, _) | ast::item_fn(_, _, _) | ast::item_mod(_) |
13231319
ast::item_native_mod(_) | ast::item_ty(_, _) |
13241320
ast::item_res(_, _, _, _, _) | ast::item_obj(_, _, _) |
1325-
ast::item_impl(_, _, _) {
1321+
ast::item_impl(_, _, _, _) | ast::item_iface(_, _) {
13261322
add_to_index(index, it.ident, mie_item(it));
13271323
}
13281324
ast::item_tag(variants, _) {
@@ -1570,7 +1566,9 @@ fn check_block(e: @env, b: ast::blk, &&x: (), v: vt<()>) {
15701566
ast::item_const(_, _) | ast::item_fn(_, _, _) {
15711567
add_name(values, it.span, it.ident);
15721568
}
1573-
ast::item_ty(_, _) { add_name(types, it.span, it.ident); }
1569+
ast::item_ty(_, _) | ast::item_iface(_, _) {
1570+
add_name(types, it.span, it.ident);
1571+
}
15741572
ast::item_res(_, _, _, _, _) | ast::item_obj(_, _, _) {
15751573
add_name(types, it.span, it.ident);
15761574
add_name(values, it.span, it.ident);
@@ -1768,7 +1766,7 @@ fn find_impls_in_item(i: @ast::item, &impls: [@_impl],
17681766
name: option::t<ident>,
17691767
ck_exports: option::t<ast::_mod>) {
17701768
alt i.node {
1771-
ast::item_impl(_, _, mthds) {
1769+
ast::item_impl(_, _, _, mthds) {
17721770
if alt name { some(n) { n == i.ident } _ { true } } &&
17731771
alt ck_exports { some(m) { is_exported(i.ident, m) } _ { true } } {
17741772
impls += [@{did: local_def(i.id),

src/comp/middle/trans.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5013,7 +5013,7 @@ fn trans_item(cx: @local_ctxt, item: ast::item) {
50135013
with *extend_path(cx, item.ident)};
50145014
trans_obj(sub_cx, item.span, ob, ctor_id, tps);
50155015
}
5016-
ast::item_impl(tps, _, ms) {
5016+
ast::item_impl(tps, _, _, ms) {
50175017
trans_impl(cx, item.ident, ms, item.id, tps);
50185018
}
50195019
ast::item_res(decl, tps, body, dtor_id, ctor_id) {
@@ -5340,7 +5340,7 @@ fn collect_item_2(ccx: @crate_ctxt, i: @ast::item, &&pt: [str],
53405340
ccx.obj_methods.insert(m.id, ());
53415341
}
53425342
}
5343-
ast::item_impl(tps, _, methods) {
5343+
ast::item_impl(tps, _, _, methods) {
53445344
let name = ccx.names.next(i.ident);
53455345
for m in methods {
53465346
register_fn(ccx, i.span, pt + [name, m.ident],

src/comp/middle/tstate/pre_post_conditions.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ fn find_pre_post_item(ccx: crate_ctxt, i: item) {
6464
}
6565
item_mod(m) { find_pre_post_mod(m); }
6666
item_native_mod(nm) { find_pre_post_native_mod(nm); }
67-
item_ty(_, _) { ret; }
68-
item_tag(_, _) { ret; }
67+
item_ty(_, _) | item_tag(_, _) | item_iface(_, _) { ret; }
6968
item_res(_, _, body, dtor_id, _) {
7069
let fcx =
7170
{enclosing: ccx.fm.get(dtor_id),
@@ -75,7 +74,7 @@ fn find_pre_post_item(ccx: crate_ctxt, i: item) {
7574
find_pre_post_fn(fcx, body);
7675
}
7776
item_obj(o, _, _) {for m in o.methods { find_pre_post_method(ccx, m); }}
78-
item_impl(_, _, ms) { for m in ms { find_pre_post_method(ccx, m); } }
77+
item_impl(_, _, _, ms) { for m in ms { find_pre_post_method(ccx, m); } }
7978
}
8079
}
8180

src/comp/middle/ty.rs

Lines changed: 56 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export mk_native;
7373
export mk_native_fn;
7474
export mk_nil;
7575
export mk_obj;
76+
export mk_iface;
7677
export mk_res;
7778
export mk_param;
7879
export mk_ptr;
@@ -123,6 +124,7 @@ export ty_vec;
123124
export ty_native;
124125
export ty_nil;
125126
export ty_obj;
127+
export ty_iface;
126128
export ty_res;
127129
export ty_param;
128130
export ty_ptr;
@@ -256,6 +258,7 @@ tag sty {
256258
ty_fn(fn_ty);
257259
ty_native_fn([arg], t);
258260
ty_obj([method]);
261+
ty_iface(def_id, [t]);
259262
ty_res(def_id, t, [t]);
260263
ty_tup([t]);
261264
ty_var(int); // type variable
@@ -444,7 +447,7 @@ fn mk_raw_ty(cx: ctxt, st: sty) -> @raw_t {
444447
}
445448
ty_param(_, _) { has_params = true; }
446449
ty_var(_) { has_vars = true; }
447-
ty_tag(_, tys) {
450+
ty_tag(_, tys) | ty_iface(_, tys) {
448451
for tt: t in tys { derive_flags_t(cx, has_params, has_vars, tt); }
449452
}
450453
ty_box(m) { derive_flags_mt(cx, has_params, has_vars, m); }
@@ -584,6 +587,10 @@ fn mk_native_fn(cx: ctxt, args: [arg], ty: t) -> t {
584587

585588
fn mk_obj(cx: ctxt, meths: [method]) -> t { ret gen_ty(cx, ty_obj(meths)); }
586589

590+
fn mk_iface(cx: ctxt, did: ast::def_id, tys: [t]) -> t {
591+
ret gen_ty(cx, ty_iface(did, tys));
592+
}
593+
587594
fn mk_res(cx: ctxt, did: ast::def_id, inner: t, tps: [t]) -> t {
588595
ret gen_ty(cx, ty_res(did, inner, tps));
589596
}
@@ -634,7 +641,7 @@ fn walk_ty(cx: ctxt, walker: ty_walk, ty: t) {
634641
/* no-op */
635642
}
636643
ty_box(tm) | ty_vec(tm) | ty_ptr(tm) { walk_ty(cx, walker, tm.ty); }
637-
ty_tag(tid, subtys) {
644+
ty_tag(_, subtys) | ty_iface(_, subtys) {
638645
for subty: t in subtys { walk_ty(cx, walker, subty); }
639646
}
640647
ty_rec(fields) {
@@ -703,9 +710,10 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t {
703710
ty = mk_vec(cx, {ty: fold_ty(cx, fld, tm.ty), mut: tm.mut});
704711
}
705712
ty_tag(tid, subtys) {
706-
let new_subtys: [t] = [];
707-
for subty: t in subtys { new_subtys += [fold_ty(cx, fld, subty)]; }
708-
ty = mk_tag(cx, tid, new_subtys);
713+
ty = mk_tag(cx, tid, vec::map(subtys, {|t| fold_ty(cx, fld, t) }));
714+
}
715+
ty_iface(did, subtys) {
716+
ty = mk_iface(cx, did, vec::map(subtys, {|t| fold_ty(cx, fld, t) }));
709717
}
710718
ty_rec(fields) {
711719
let new_fields: [field] = [];
@@ -785,14 +793,10 @@ fn type_is_bool(cx: ctxt, ty: t) -> bool {
785793

786794
fn type_is_structural(cx: ctxt, ty: t) -> bool {
787795
alt struct(cx, ty) {
788-
ty_rec(_) { ret true; }
789-
ty_tup(_) { ret true; }
790-
ty_tag(_, _) { ret true; }
791-
ty_fn(_) { ret true; }
792-
ty_native_fn(_, _) { ret true; }
793-
ty_obj(_) { ret true; }
794-
ty_res(_, _, _) { ret true; }
795-
_ { ret false; }
796+
ty_rec(_) | ty_tup(_) | ty_tag(_, _) | ty_fn(_) |
797+
ty_native_fn(_, _) | ty_obj(_) | ty_res(_, _, _) |
798+
ty_iface(_, _) { true }
799+
_ { false }
796800
}
797801
}
798802

@@ -973,7 +977,7 @@ fn type_kind(cx: ctxt, ty: t) -> ast::kind {
973977
ty_opaque_closure. { kind_noncopyable }
974978
// Those with refcounts-to-inner raise pinned to shared,
975979
// lower unique to shared. Therefore just set result to shared.
976-
ty_box(mt) { ast::kind_copyable }
980+
ty_box(_) | ty_iface(_, _) { ast::kind_copyable }
977981
// Boxes and unique pointers raise pinned to shared.
978982
ty_vec(tm) | ty_uniq(tm) { type_kind(cx, tm.ty) }
979983
// Records lower to the lowest of their members.
@@ -1142,9 +1146,7 @@ fn type_is_pod(cx: ctxt, ty: t) -> bool {
11421146
ty_send_type. | ty_type. | ty_native(_) | ty_ptr(_) { result = true; }
11431147
// Boxed types
11441148
ty_str. | ty_box(_) | ty_uniq(_) | ty_vec(_) | ty_fn(_) |
1145-
ty_native_fn(_, _) | ty_obj(_) {
1146-
result = false;
1147-
}
1149+
ty_native_fn(_, _) | ty_obj(_) | ty_iface(_, _) { result = false; }
11481150
// Structural types
11491151
ty_tag(did, tps) {
11501152
let variants = tag_variants(cx, did);
@@ -1332,6 +1334,11 @@ fn hash_type_structure(st: sty) -> uint {
13321334
ty_send_type. { ret 38u; }
13331335
ty_opaque_closure. { ret 39u; }
13341336
ty_named(t, name) { (str::hash(*name) << 5u) + hash_subty(40u, t) }
1337+
ty_iface(did, tys) {
1338+
let h = hash_def(41u, did);
1339+
for typ: t in tys { h += (h << 5u) + typ; }
1340+
ret h;
1341+
}
13351342
}
13361343
}
13371344

@@ -2024,6 +2031,20 @@ mod unify {
20242031
}
20252032
}
20262033

2034+
fn unify_tps(cx: @ctxt, expected_tps: [t], actual_tps: [t],
2035+
variance: variance, finish: block([t]) -> result) -> result {
2036+
let result_tps = [], i = 0u;
2037+
for exp in expected_tps {
2038+
let act = actual_tps[i];
2039+
i += 1u;
2040+
let result = unify_step(cx, exp, act, variance);
2041+
alt result {
2042+
ures_ok(rty) { result_tps += [rty]; }
2043+
_ { ret result; }
2044+
}
2045+
}
2046+
finish(result_tps)
2047+
}
20272048
fn unify_step(cx: @ctxt, expected: t, actual: t,
20282049
variance: variance) -> result {
20292050
// FIXME: rewrite this using tuple pattern matching when available, to
@@ -2109,31 +2130,31 @@ mod unify {
21092130
ty::ty_tag(expected_id, expected_tps) {
21102131
alt struct(cx.tcx, actual) {
21112132
ty::ty_tag(actual_id, actual_tps) {
2112-
if expected_id.crate != actual_id.crate ||
2113-
expected_id.node != actual_id.node {
2133+
if expected_id != actual_id {
21142134
ret ures_err(terr_mismatch);
21152135
}
2116-
// TODO: factor this cruft out
2117-
let result_tps: [t] = [];
2118-
let i = 0u;
2119-
let expected_len = vec::len::<t>(expected_tps);
2120-
while i < expected_len {
2121-
let expected_tp = expected_tps[i];
2122-
let actual_tp = actual_tps[i];
2123-
let result = unify_step(
2124-
cx, expected_tp, actual_tp, variance);
2125-
alt result {
2126-
ures_ok(rty) { result_tps += [rty]; }
2127-
_ { ret result; }
2128-
}
2129-
i += 1u;
2130-
}
2131-
ret ures_ok(mk_tag(cx.tcx, expected_id, result_tps));
2136+
ret unify_tps(cx, expected_tps, actual_tps, variance, {|tps|
2137+
ures_ok(mk_tag(cx.tcx, expected_id, tps))
2138+
});
21322139
}
21332140
_ {/* fall through */ }
21342141
}
21352142
ret ures_err(terr_mismatch);
21362143
}
2144+
ty_iface(expected_id, expected_tps) {
2145+
alt struct(cx.tcx, actual) {
2146+
ty::ty_iface(actual_id, actual_tps) {
2147+
if expected_id != actual_id {
2148+
ret ures_err(terr_mismatch);
2149+
}
2150+
ret unify_tps(cx, expected_tps, actual_tps, variance, {|tps|
2151+
ures_ok(mk_iface(cx.tcx, expected_id, tps))
2152+
});
2153+
}
2154+
_ {}
2155+
}
2156+
ret ures_err(terr_mismatch);
2157+
}
21372158
ty::ty_box(expected_mt) {
21382159
alt struct(cx.tcx, actual) {
21392160
ty::ty_box(actual_mt) {

0 commit comments

Comments
 (0)