mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
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); } } }
This commit is contained in:
parent
9292744959
commit
057617c665
@ -64,6 +64,7 @@ fn encode_native_module_item_paths(ebml_w: ebml::writer, nmod: native_mod,
|
||||
|
||||
fn encode_module_item_paths(ebml_w: ebml::writer, module: _mod, path: [str],
|
||||
&index: [entry<str>]) {
|
||||
// FIXME factor out add_to_index/start/encode_name/encode_def_id/end ops
|
||||
for it: @item in module.items {
|
||||
if !ast_util::is_exported(it.ident, module) { cont; }
|
||||
alt it.node {
|
||||
@ -137,7 +138,14 @@ fn encode_module_item_paths(ebml_w: ebml::writer, module: _mod, path: [str],
|
||||
encode_def_id(ebml_w, local_def(it.id));
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
item_impl(_, _, _) {}
|
||||
item_iface(_, _) {
|
||||
add_to_index(ebml_w, path, index, it.ident);
|
||||
ebml::start_tag(ebml_w, tag_paths_data_item);
|
||||
encode_name(ebml_w, it.ident);
|
||||
encode_def_id(ebml_w, local_def(it.id));
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
item_impl(_, _, _, _) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -252,7 +260,7 @@ fn encode_info_for_mod(ebml_w: ebml::writer, md: _mod,
|
||||
encode_name(ebml_w, name);
|
||||
for i in md.items {
|
||||
alt i.node {
|
||||
item_impl(_, _, _) {
|
||||
item_impl(_, _, _, _) {
|
||||
if ast_util::is_exported(i.ident, md) {
|
||||
ebml::start_tag(ebml_w, tag_mod_impl);
|
||||
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,
|
||||
encode_symbol(ecx, ebml_w, ctor_id);
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
item_impl(tps, _, methods) {
|
||||
item_impl(tps, _, _, methods) {
|
||||
ebml::start_tag(ebml_w, tag_items_data_item);
|
||||
encode_def_id(ebml_w, local_def(item.id));
|
||||
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,
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
}
|
||||
item_iface(_, _) { /* FIXME[impl] */ }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ fn map_item(cx: ctx, i: @item) {
|
||||
cx.map.insert(m.id, node_obj_method(m));
|
||||
}
|
||||
}
|
||||
item_impl(_, _, ms) {
|
||||
item_impl(_, _, _, ms) {
|
||||
for m in ms { cx.map.insert(m.id, node_method(m)); }
|
||||
}
|
||||
item_res(_, _, _, dtor_id, ctor_id) {
|
||||
|
@ -401,8 +401,9 @@ fn resolve_names(e: @env, c: @ast::crate) {
|
||||
fn visit_item_with_scope(i: @ast::item, sc: scopes, v: vt<scopes>) {
|
||||
let sc = cons(scope_item(i), @sc);
|
||||
alt i.node {
|
||||
ast::item_impl(tps, sty, methods) {
|
||||
visit::visit_ty(sty, sc, v);
|
||||
ast::item_impl(tps, ifce, sty, methods) {
|
||||
alt ifce { some(ty) { v.visit_ty(ty, sc, v); } _ {} }
|
||||
v.visit_ty(sty, sc, v);
|
||||
for m in methods {
|
||||
v.visit_fn_proto(m.decl, tps + m.tps, m.body, m.span,
|
||||
some(m.ident), m.id, sc, v);
|
||||
@ -802,14 +803,15 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace)
|
||||
ast::item_obj(ob, ty_params, _) {
|
||||
ret lookup_in_obj(name, ob, ty_params, ns, it.id);
|
||||
}
|
||||
ast::item_impl(ty_params, _, _) {
|
||||
ast::item_impl(ty_params, _, _, _) {
|
||||
if (name == "self" && ns == ns_value) {
|
||||
ret some(ast::def_self(local_def(it.id)));
|
||||
}
|
||||
if ns == ns_type { ret lookup_in_ty_params(name, ty_params); }
|
||||
}
|
||||
ast::item_tag(_, ty_params) {
|
||||
if ns == ns_type { ret lookup_in_ty_params(name, ty_params); }
|
||||
ast::item_iface(tps, _) | ast::item_tag(_, tps) |
|
||||
ast::item_ty(_, tps) {
|
||||
if ns == ns_type { ret lookup_in_ty_params(name, tps); }
|
||||
}
|
||||
ast::item_mod(_) {
|
||||
ret lookup_in_local_mod(e, it.id, sp, name, ns, inside);
|
||||
@ -817,9 +819,6 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace)
|
||||
ast::item_native_mod(m) {
|
||||
ret lookup_in_local_native_mod(e, it.id, sp, name, ns);
|
||||
}
|
||||
ast::item_ty(_, ty_params) {
|
||||
if ns == ns_type { ret lookup_in_ty_params(name, ty_params); }
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
@ -1064,7 +1063,7 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option::t<def> {
|
||||
ast::item_native_mod(_) {
|
||||
if ns == ns_module { ret some(ast::def_native_mod(local_def(i.id))); }
|
||||
}
|
||||
ast::item_ty(_, _) {
|
||||
ast::item_ty(_, _) | item_iface(_, _) | item_tag(_, _) {
|
||||
if ns == ns_type { ret some(ast::def_ty(local_def(i.id))); }
|
||||
}
|
||||
ast::item_res(_, _, _, _, ctor_id) {
|
||||
@ -1076,9 +1075,6 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option::t<def> {
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
ast::item_tag(_, _) {
|
||||
if ns == ns_type { ret some(ast::def_ty(local_def(i.id))); }
|
||||
}
|
||||
ast::item_obj(_, _, ctor_id) {
|
||||
alt ns {
|
||||
ns_value. {
|
||||
@ -1322,7 +1318,7 @@ fn index_mod(md: ast::_mod) -> mod_index {
|
||||
ast::item_const(_, _) | ast::item_fn(_, _, _) | ast::item_mod(_) |
|
||||
ast::item_native_mod(_) | ast::item_ty(_, _) |
|
||||
ast::item_res(_, _, _, _, _) | ast::item_obj(_, _, _) |
|
||||
ast::item_impl(_, _, _) {
|
||||
ast::item_impl(_, _, _, _) | ast::item_iface(_, _) {
|
||||
add_to_index(index, it.ident, mie_item(it));
|
||||
}
|
||||
ast::item_tag(variants, _) {
|
||||
@ -1570,7 +1566,9 @@ fn check_block(e: @env, b: ast::blk, &&x: (), v: vt<()>) {
|
||||
ast::item_const(_, _) | ast::item_fn(_, _, _) {
|
||||
add_name(values, it.span, it.ident);
|
||||
}
|
||||
ast::item_ty(_, _) { add_name(types, it.span, it.ident); }
|
||||
ast::item_ty(_, _) | ast::item_iface(_, _) {
|
||||
add_name(types, it.span, it.ident);
|
||||
}
|
||||
ast::item_res(_, _, _, _, _) | ast::item_obj(_, _, _) {
|
||||
add_name(types, it.span, it.ident);
|
||||
add_name(values, it.span, it.ident);
|
||||
@ -1768,7 +1766,7 @@ fn find_impls_in_item(i: @ast::item, &impls: [@_impl],
|
||||
name: option::t<ident>,
|
||||
ck_exports: option::t<ast::_mod>) {
|
||||
alt i.node {
|
||||
ast::item_impl(_, _, mthds) {
|
||||
ast::item_impl(_, _, _, mthds) {
|
||||
if alt name { some(n) { n == i.ident } _ { true } } &&
|
||||
alt ck_exports { some(m) { is_exported(i.ident, m) } _ { true } } {
|
||||
impls += [@{did: local_def(i.id),
|
||||
|
@ -5013,7 +5013,7 @@ fn trans_item(cx: @local_ctxt, item: ast::item) {
|
||||
with *extend_path(cx, item.ident)};
|
||||
trans_obj(sub_cx, item.span, ob, ctor_id, tps);
|
||||
}
|
||||
ast::item_impl(tps, _, ms) {
|
||||
ast::item_impl(tps, _, _, ms) {
|
||||
trans_impl(cx, item.ident, ms, item.id, tps);
|
||||
}
|
||||
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],
|
||||
ccx.obj_methods.insert(m.id, ());
|
||||
}
|
||||
}
|
||||
ast::item_impl(tps, _, methods) {
|
||||
ast::item_impl(tps, _, _, methods) {
|
||||
let name = ccx.names.next(i.ident);
|
||||
for m in methods {
|
||||
register_fn(ccx, i.span, pt + [name, m.ident],
|
||||
|
@ -64,8 +64,7 @@ fn find_pre_post_item(ccx: crate_ctxt, i: item) {
|
||||
}
|
||||
item_mod(m) { find_pre_post_mod(m); }
|
||||
item_native_mod(nm) { find_pre_post_native_mod(nm); }
|
||||
item_ty(_, _) { ret; }
|
||||
item_tag(_, _) { ret; }
|
||||
item_ty(_, _) | item_tag(_, _) | item_iface(_, _) { ret; }
|
||||
item_res(_, _, body, dtor_id, _) {
|
||||
let fcx =
|
||||
{enclosing: ccx.fm.get(dtor_id),
|
||||
@ -75,7 +74,7 @@ fn find_pre_post_item(ccx: crate_ctxt, i: item) {
|
||||
find_pre_post_fn(fcx, body);
|
||||
}
|
||||
item_obj(o, _, _) {for m in o.methods { find_pre_post_method(ccx, m); }}
|
||||
item_impl(_, _, ms) { for m in ms { find_pre_post_method(ccx, m); } }
|
||||
item_impl(_, _, _, ms) { for m in ms { find_pre_post_method(ccx, m); } }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,6 +73,7 @@ export mk_native;
|
||||
export mk_native_fn;
|
||||
export mk_nil;
|
||||
export mk_obj;
|
||||
export mk_iface;
|
||||
export mk_res;
|
||||
export mk_param;
|
||||
export mk_ptr;
|
||||
@ -123,6 +124,7 @@ export ty_vec;
|
||||
export ty_native;
|
||||
export ty_nil;
|
||||
export ty_obj;
|
||||
export ty_iface;
|
||||
export ty_res;
|
||||
export ty_param;
|
||||
export ty_ptr;
|
||||
@ -256,6 +258,7 @@ tag sty {
|
||||
ty_fn(fn_ty);
|
||||
ty_native_fn([arg], t);
|
||||
ty_obj([method]);
|
||||
ty_iface(def_id, [t]);
|
||||
ty_res(def_id, t, [t]);
|
||||
ty_tup([t]);
|
||||
ty_var(int); // type variable
|
||||
@ -444,7 +447,7 @@ fn mk_raw_ty(cx: ctxt, st: sty) -> @raw_t {
|
||||
}
|
||||
ty_param(_, _) { has_params = true; }
|
||||
ty_var(_) { has_vars = true; }
|
||||
ty_tag(_, tys) {
|
||||
ty_tag(_, tys) | ty_iface(_, tys) {
|
||||
for tt: t in tys { derive_flags_t(cx, has_params, has_vars, tt); }
|
||||
}
|
||||
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 {
|
||||
|
||||
fn mk_obj(cx: ctxt, meths: [method]) -> t { ret gen_ty(cx, ty_obj(meths)); }
|
||||
|
||||
fn mk_iface(cx: ctxt, did: ast::def_id, tys: [t]) -> t {
|
||||
ret gen_ty(cx, ty_iface(did, tys));
|
||||
}
|
||||
|
||||
fn mk_res(cx: ctxt, did: ast::def_id, inner: t, tps: [t]) -> t {
|
||||
ret gen_ty(cx, ty_res(did, inner, tps));
|
||||
}
|
||||
@ -634,7 +641,7 @@ fn walk_ty(cx: ctxt, walker: ty_walk, ty: t) {
|
||||
/* no-op */
|
||||
}
|
||||
ty_box(tm) | ty_vec(tm) | ty_ptr(tm) { walk_ty(cx, walker, tm.ty); }
|
||||
ty_tag(tid, subtys) {
|
||||
ty_tag(_, subtys) | ty_iface(_, subtys) {
|
||||
for subty: t in subtys { walk_ty(cx, walker, subty); }
|
||||
}
|
||||
ty_rec(fields) {
|
||||
@ -703,9 +710,10 @@ fn fold_ty(cx: ctxt, fld: fold_mode, ty_0: t) -> t {
|
||||
ty = mk_vec(cx, {ty: fold_ty(cx, fld, tm.ty), mut: tm.mut});
|
||||
}
|
||||
ty_tag(tid, subtys) {
|
||||
let new_subtys: [t] = [];
|
||||
for subty: t in subtys { new_subtys += [fold_ty(cx, fld, subty)]; }
|
||||
ty = mk_tag(cx, tid, new_subtys);
|
||||
ty = mk_tag(cx, tid, vec::map(subtys, {|t| fold_ty(cx, fld, t) }));
|
||||
}
|
||||
ty_iface(did, subtys) {
|
||||
ty = mk_iface(cx, did, vec::map(subtys, {|t| fold_ty(cx, fld, t) }));
|
||||
}
|
||||
ty_rec(fields) {
|
||||
let new_fields: [field] = [];
|
||||
@ -785,14 +793,10 @@ fn type_is_bool(cx: ctxt, ty: t) -> bool {
|
||||
|
||||
fn type_is_structural(cx: ctxt, ty: t) -> bool {
|
||||
alt struct(cx, ty) {
|
||||
ty_rec(_) { ret true; }
|
||||
ty_tup(_) { ret true; }
|
||||
ty_tag(_, _) { ret true; }
|
||||
ty_fn(_) { ret true; }
|
||||
ty_native_fn(_, _) { ret true; }
|
||||
ty_obj(_) { ret true; }
|
||||
ty_res(_, _, _) { ret true; }
|
||||
_ { ret false; }
|
||||
ty_rec(_) | ty_tup(_) | ty_tag(_, _) | ty_fn(_) |
|
||||
ty_native_fn(_, _) | ty_obj(_) | ty_res(_, _, _) |
|
||||
ty_iface(_, _) { true }
|
||||
_ { false }
|
||||
}
|
||||
}
|
||||
|
||||
@ -973,7 +977,7 @@ fn type_kind(cx: ctxt, ty: t) -> ast::kind {
|
||||
ty_opaque_closure. { kind_noncopyable }
|
||||
// Those with refcounts-to-inner raise pinned to shared,
|
||||
// lower unique to shared. Therefore just set result to shared.
|
||||
ty_box(mt) { ast::kind_copyable }
|
||||
ty_box(_) | ty_iface(_, _) { ast::kind_copyable }
|
||||
// Boxes and unique pointers raise pinned to shared.
|
||||
ty_vec(tm) | ty_uniq(tm) { type_kind(cx, tm.ty) }
|
||||
// Records lower to the lowest of their members.
|
||||
@ -1142,9 +1146,7 @@ fn type_is_pod(cx: ctxt, ty: t) -> bool {
|
||||
ty_send_type. | ty_type. | ty_native(_) | ty_ptr(_) { result = true; }
|
||||
// Boxed types
|
||||
ty_str. | ty_box(_) | ty_uniq(_) | ty_vec(_) | ty_fn(_) |
|
||||
ty_native_fn(_, _) | ty_obj(_) {
|
||||
result = false;
|
||||
}
|
||||
ty_native_fn(_, _) | ty_obj(_) | ty_iface(_, _) { result = false; }
|
||||
// Structural types
|
||||
ty_tag(did, tps) {
|
||||
let variants = tag_variants(cx, did);
|
||||
@ -1332,6 +1334,11 @@ fn hash_type_structure(st: sty) -> uint {
|
||||
ty_send_type. { ret 38u; }
|
||||
ty_opaque_closure. { ret 39u; }
|
||||
ty_named(t, name) { (str::hash(*name) << 5u) + hash_subty(40u, t) }
|
||||
ty_iface(did, tys) {
|
||||
let h = hash_def(41u, did);
|
||||
for typ: t in tys { h += (h << 5u) + typ; }
|
||||
ret h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2024,6 +2031,20 @@ mod unify {
|
||||
}
|
||||
}
|
||||
|
||||
fn unify_tps(cx: @ctxt, expected_tps: [t], actual_tps: [t],
|
||||
variance: variance, finish: block([t]) -> result) -> result {
|
||||
let result_tps = [], i = 0u;
|
||||
for exp in expected_tps {
|
||||
let act = actual_tps[i];
|
||||
i += 1u;
|
||||
let result = unify_step(cx, exp, act, variance);
|
||||
alt result {
|
||||
ures_ok(rty) { result_tps += [rty]; }
|
||||
_ { ret result; }
|
||||
}
|
||||
}
|
||||
finish(result_tps)
|
||||
}
|
||||
fn unify_step(cx: @ctxt, expected: t, actual: t,
|
||||
variance: variance) -> result {
|
||||
// FIXME: rewrite this using tuple pattern matching when available, to
|
||||
@ -2109,31 +2130,31 @@ mod unify {
|
||||
ty::ty_tag(expected_id, expected_tps) {
|
||||
alt struct(cx.tcx, actual) {
|
||||
ty::ty_tag(actual_id, actual_tps) {
|
||||
if expected_id.crate != actual_id.crate ||
|
||||
expected_id.node != actual_id.node {
|
||||
if expected_id != actual_id {
|
||||
ret ures_err(terr_mismatch);
|
||||
}
|
||||
// TODO: factor this cruft out
|
||||
let result_tps: [t] = [];
|
||||
let i = 0u;
|
||||
let expected_len = vec::len::<t>(expected_tps);
|
||||
while i < expected_len {
|
||||
let expected_tp = expected_tps[i];
|
||||
let actual_tp = actual_tps[i];
|
||||
let result = unify_step(
|
||||
cx, expected_tp, actual_tp, variance);
|
||||
alt result {
|
||||
ures_ok(rty) { result_tps += [rty]; }
|
||||
_ { ret result; }
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
ret ures_ok(mk_tag(cx.tcx, expected_id, result_tps));
|
||||
ret unify_tps(cx, expected_tps, actual_tps, variance, {|tps|
|
||||
ures_ok(mk_tag(cx.tcx, expected_id, tps))
|
||||
});
|
||||
}
|
||||
_ {/* fall through */ }
|
||||
}
|
||||
ret ures_err(terr_mismatch);
|
||||
}
|
||||
ty_iface(expected_id, expected_tps) {
|
||||
alt struct(cx.tcx, actual) {
|
||||
ty::ty_iface(actual_id, actual_tps) {
|
||||
if expected_id != actual_id {
|
||||
ret ures_err(terr_mismatch);
|
||||
}
|
||||
ret unify_tps(cx, expected_tps, actual_tps, variance, {|tps|
|
||||
ures_ok(mk_iface(cx.tcx, expected_id, tps))
|
||||
});
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
ret ures_err(terr_mismatch);
|
||||
}
|
||||
ty::ty_box(expected_mt) {
|
||||
alt struct(cx.tcx, actual) {
|
||||
ty::ty_box(actual_mt) {
|
||||
|
@ -422,7 +422,15 @@ fn ty_of_item(tcx: ty::ctxt, mode: mode, it: @ast::item)
|
||||
tcx.tcache.insert(local_def(it.id), tpt);
|
||||
ret tpt;
|
||||
}
|
||||
ast::item_impl(_, _, _) | ast::item_mod(_) |
|
||||
ast::item_iface(tps, methods) {
|
||||
let t = ty::mk_named(tcx, ty::mk_iface(tcx, local_def(it.id),
|
||||
mk_ty_params(tcx, tps)),
|
||||
@it.ident);
|
||||
let tpt = {kinds: ty_param_kinds(tps), ty: t};
|
||||
tcx.tcache.insert(local_def(it.id), tpt);
|
||||
ret tpt;
|
||||
}
|
||||
ast::item_impl(_, _, _, _) | ast::item_mod(_) |
|
||||
ast::item_native_mod(_) { fail; }
|
||||
}
|
||||
}
|
||||
@ -647,7 +655,7 @@ mod collect {
|
||||
write::ty_only(cx.tcx, it.id, tpt.ty);
|
||||
get_tag_variant_types(cx, tpt.ty, variants, ty_params);
|
||||
}
|
||||
ast::item_impl(_, selfty, ms) {
|
||||
ast::item_impl(_, _, selfty, ms) {
|
||||
for m in ms {
|
||||
let ty = ty::mk_fn(cx.tcx, ty_of_fn_decl(cx.tcx, m_collect,
|
||||
m.decl));
|
||||
@ -1429,9 +1437,9 @@ fn lookup_method(fcx: @fn_ctxt, isc: resolve::iscopes,
|
||||
some(m) {
|
||||
let (n_tps, self_ty) = if did.crate == ast::local_crate {
|
||||
alt fcx.ccx.tcx.items.get(did.node) {
|
||||
ast_map::node_item(@{node: ast::item_impl(tps, st, _),
|
||||
ast_map::node_item(@{node: ast::item_impl(ts, _, st, _),
|
||||
_}) {
|
||||
(vec::len(tps), ast_ty_to_ty_crate(fcx.ccx, st))
|
||||
(vec::len(ts), ast_ty_to_ty_crate(fcx.ccx, st))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -2637,7 +2645,7 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
|
||||
// Now remove the info from the stack.
|
||||
vec::pop(ccx.self_infos);
|
||||
}
|
||||
ast::item_impl(_, ty, ms) {
|
||||
ast::item_impl(_, _, ty, ms) {
|
||||
ccx.self_infos += [self_impl(ast_ty_to_ty(ccx.tcx, m_check, ty))];
|
||||
for m in ms { check_method(ccx, m); }
|
||||
vec::pop(ccx.self_infos);
|
||||
|
@ -490,7 +490,9 @@ tag item_ {
|
||||
item_obj(_obj, [ty_param], /* constructor id */node_id);
|
||||
item_res(fn_decl /* dtor */, [ty_param], blk,
|
||||
node_id /* dtor id */, node_id /* ctor id */);
|
||||
item_impl([ty_param], @ty /* self */, [@method]);
|
||||
item_iface([ty_param], [ty_method]);
|
||||
item_impl([ty_param], option::t<@ty> /* iface */,
|
||||
@ty /* self */, [@method]);
|
||||
}
|
||||
|
||||
type native_item =
|
||||
|
@ -65,7 +65,7 @@ type a_f =
|
||||
fold_native_mod: fn@(native_mod) -> native_mod,
|
||||
fold_variant: fn@(variant) -> variant,
|
||||
fold_ident: fn@(&&ident) -> ident,
|
||||
fold_path: fn@(@path) -> @path,
|
||||
fold_path: fn@(&&@path) -> @path,
|
||||
fold_local: fn@(&&@local) -> @local,
|
||||
map_exprs: fn@(fn@(&&@expr) -> @expr, [@expr]) -> [@expr],
|
||||
new_id: fn@(node_id) -> node_id,
|
||||
@ -94,7 +94,7 @@ fn nf_mod_dummy(_m: _mod) -> _mod { fail; }
|
||||
fn nf_native_mod_dummy(_n: native_mod) -> native_mod { fail; }
|
||||
fn nf_variant_dummy(_v: variant) -> variant { fail; }
|
||||
fn nf_ident_dummy(&&_i: ident) -> ident { fail; }
|
||||
fn nf_path_dummy(_p: @path) -> @path { fail; }
|
||||
fn nf_path_dummy(&&_p: @path) -> @path { fail; }
|
||||
fn nf_obj_field_dummy(_o: obj_field) -> obj_field { fail; }
|
||||
fn nf_local_dummy(&&_o: @local) -> @local { fail; }
|
||||
|
||||
@ -243,10 +243,13 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
|
||||
methods: vec::map(o.methods, fld.fold_method)},
|
||||
typms, d)
|
||||
}
|
||||
item_impl(tps, ty, methods) {
|
||||
item_impl(tps, fld.fold_ty(ty),
|
||||
item_impl(tps, ifce, ty, methods) {
|
||||
item_impl(tps, option::map(ifce, fld.fold_ty), fld.fold_ty(ty),
|
||||
vec::map(methods, fld.fold_method))
|
||||
}
|
||||
item_iface(tps, methods) {
|
||||
item_iface(tps, methods)
|
||||
}
|
||||
item_res(decl, typms, body, did, cid) {
|
||||
item_res(fold_fn_decl(decl, fld), typms, fld.fold_block(body),
|
||||
did, cid)
|
||||
@ -471,7 +474,7 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ {
|
||||
|
||||
fn noop_fold_ident(&&i: ident, _fld: ast_fold) -> ident { ret i; }
|
||||
|
||||
fn noop_fold_path(p: path_, fld: ast_fold) -> path_ {
|
||||
fn noop_fold_path(&&p: path_, fld: ast_fold) -> path_ {
|
||||
ret {global: p.global,
|
||||
idents: vec::map(p.idents, fld.fold_ident),
|
||||
types: vec::map(p.types, fld.fold_ty)};
|
||||
@ -630,7 +633,7 @@ fn make_fold(afp: ast_fold_precursor) -> ast_fold {
|
||||
fn f_ident(afp: ast_fold_precursor, f: ast_fold, &&x: ident) -> ident {
|
||||
ret afp.fold_ident(x, f);
|
||||
}
|
||||
fn f_path(afp: ast_fold_precursor, f: ast_fold, x: @path) -> @path {
|
||||
fn f_path(afp: ast_fold_precursor, f: ast_fold, &&x: @path) -> @path {
|
||||
ret @{node: afp.fold_path(x.node, f), span: afp.new_span(x.span)};
|
||||
}
|
||||
fn f_local(afp: ast_fold_precursor, f: ast_fold, &&x: @local) -> @local {
|
||||
|
@ -165,7 +165,7 @@ fn bad_expr_word_table() -> hashmap<str, ()> {
|
||||
"cont", "ret", "be", "fail", "type", "resource", "check",
|
||||
"assert", "claim", "native", "fn", "lambda", "pure",
|
||||
"unsafe", "block", "import", "export", "let", "const",
|
||||
"log", "tag", "obj", "copy", "sendfn", "impl"] {
|
||||
"log", "tag", "obj", "copy", "sendfn", "impl", "iface"] {
|
||||
words.insert(word, ());
|
||||
}
|
||||
words
|
||||
@ -285,7 +285,7 @@ fn parse_ty_fn(proto: ast::proto, p: parser) -> ast::ty_ {
|
||||
constraints: constrs});
|
||||
}
|
||||
|
||||
fn parse_ty_obj(p: parser) -> ast::ty_ {
|
||||
fn parse_ty_methods(p: parser) -> [ast::ty_method] {
|
||||
fn parse_method_sig(p: parser) -> ast::ty_method {
|
||||
let flo = p.get_lo_pos();
|
||||
let proto: ast::proto = parse_method_proto(p);
|
||||
@ -298,10 +298,8 @@ fn parse_ty_obj(p: parser) -> ast::ty_ {
|
||||
}
|
||||
}
|
||||
}
|
||||
let meths =
|
||||
parse_seq(token::LBRACE, token::RBRACE, seq_sep_none(),
|
||||
parse_method_sig, p);
|
||||
ret ast::ty_obj(meths.node);
|
||||
parse_seq(token::LBRACE, token::RBRACE, seq_sep_none(),
|
||||
parse_method_sig, p).node
|
||||
}
|
||||
|
||||
fn parse_mt(p: parser) -> ast::mt {
|
||||
@ -519,7 +517,7 @@ fn parse_ty(p: parser, colons_before_params: bool) -> @ast::ty {
|
||||
} else if eat_word(p, "sendfn") {
|
||||
t = parse_ty_fn(ast::proto_send, p);
|
||||
} else if eat_word(p, "obj") {
|
||||
t = parse_ty_obj(p);
|
||||
t = ast::ty_obj(parse_ty_methods(p));
|
||||
} else if p.peek() == token::MOD_SEP || is_ident(p.peek()) {
|
||||
let path = parse_path(p);
|
||||
t = ast::ty_path(path, p.get_id());
|
||||
@ -676,47 +674,22 @@ fn is_plain_ident(p: parser) -> bool {
|
||||
|
||||
fn parse_path(p: parser) -> @ast::path {
|
||||
let lo = p.get_lo_pos();
|
||||
let hi = lo;
|
||||
|
||||
let global;
|
||||
if p.peek() == token::MOD_SEP {
|
||||
global = true;
|
||||
p.bump();
|
||||
} else { global = false; }
|
||||
|
||||
let ids: [ast::ident] = [];
|
||||
while true {
|
||||
alt p.peek() {
|
||||
token::IDENT(i, _) {
|
||||
hi = p.get_hi_pos();
|
||||
ids += [p.get_str(i)];
|
||||
hi = p.get_hi_pos();
|
||||
p.bump();
|
||||
if p.peek() == token::MOD_SEP && p.look_ahead(1u) != token::LT {
|
||||
p.bump();
|
||||
} else { break; }
|
||||
}
|
||||
_ { break; }
|
||||
}
|
||||
let global = eat(p, token::MOD_SEP), ids = [parse_ident(p)];
|
||||
while p.look_ahead(1u) != token::LT && eat(p, token::MOD_SEP) {
|
||||
ids += [parse_ident(p)];
|
||||
}
|
||||
ret @spanned(lo, hi, {global: global, idents: ids, types: []});
|
||||
ret @spanned(lo, p.get_last_hi_pos(),
|
||||
{global: global, idents: ids, types: []});
|
||||
}
|
||||
|
||||
fn parse_path_and_ty_param_substs(p: parser) -> @ast::path {
|
||||
fn parse_path_and_ty_param_substs(p: parser, colons: bool) -> @ast::path {
|
||||
let lo = p.get_lo_pos();
|
||||
let path = parse_path(p);
|
||||
if p.peek() == token::MOD_SEP {
|
||||
p.bump();
|
||||
|
||||
let seq =
|
||||
parse_seq_lt_gt(some(token::COMMA), {|p| parse_ty(p, false)}, p);
|
||||
let hi = seq.span.hi;
|
||||
path = @spanned(lo, hi,
|
||||
{global: path.node.global,
|
||||
idents: path.node.idents,
|
||||
types: seq.node});
|
||||
}
|
||||
ret path;
|
||||
if colons ? eat(p, token::MOD_SEP) : p.peek() == token::LT {
|
||||
let seq = parse_seq_lt_gt(some(token::COMMA),
|
||||
{|p| parse_ty(p, false)}, p);
|
||||
@spanned(lo, seq.span.hi, {types: seq.node with path.node})
|
||||
} else { path }
|
||||
}
|
||||
|
||||
fn parse_mutability(p: parser) -> ast::mutability {
|
||||
@ -958,7 +931,7 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
|
||||
is_ident(p.peek()) && !is_word(p, "true") &&
|
||||
!is_word(p, "false") {
|
||||
check_bad_word(p);
|
||||
let pth = parse_path_and_ty_param_substs(p);
|
||||
let pth = parse_path_and_ty_param_substs(p, true);
|
||||
hi = pth.span.hi;
|
||||
ex = ast::expr_path(pth);
|
||||
} else {
|
||||
@ -984,10 +957,11 @@ fn parse_syntax_ext(p: parser) -> @ast::expr {
|
||||
}
|
||||
|
||||
fn parse_syntax_ext_naked(p: parser, lo: uint) -> @ast::expr {
|
||||
let pth = parse_path(p);
|
||||
if vec::len(pth.node.idents) == 0u {
|
||||
p.fatal("expected a syntax expander name");
|
||||
alt p.peek() {
|
||||
token::IDENT(_, _) {}
|
||||
_ { p.fatal("expected a syntax expander name"); }
|
||||
}
|
||||
let pth = parse_path(p);
|
||||
//temporary for a backwards-compatible cycle:
|
||||
let sep = seq_sep(token::COMMA);
|
||||
let es =
|
||||
@ -1518,7 +1492,7 @@ fn parse_pat(p: parser) -> @ast::pat {
|
||||
let sub = eat(p, token::AT) ? some(parse_pat(p)) : none;
|
||||
pat = ast::pat_bind(name, sub);
|
||||
} else {
|
||||
let tag_path = parse_path_and_ty_param_substs(p);
|
||||
let tag_path = parse_path_and_ty_param_substs(p, true);
|
||||
hi = tag_path.span.hi;
|
||||
let args: [@ast::pat];
|
||||
alt p.peek() {
|
||||
@ -1751,12 +1725,9 @@ fn parse_ty_param(p: parser) -> ast::ty_param {
|
||||
}
|
||||
|
||||
fn parse_ty_params(p: parser) -> [ast::ty_param] {
|
||||
let ty_params: [ast::ty_param] = [];
|
||||
if p.peek() == token::LT {
|
||||
p.bump();
|
||||
ty_params = parse_seq_to_gt(some(token::COMMA), parse_ty_param, p);
|
||||
}
|
||||
ret ty_params;
|
||||
if eat(p, token::LT) {
|
||||
parse_seq_to_gt(some(token::COMMA), parse_ty_param, p)
|
||||
} else { [] }
|
||||
}
|
||||
|
||||
fn parse_fn_decl(p: parser, proto: ast::proto, purity: ast::purity)
|
||||
@ -1866,15 +1837,47 @@ fn parse_item_obj(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
||||
attrs);
|
||||
}
|
||||
|
||||
fn parse_item_impl(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
||||
fn parse_item_iface(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
||||
let lo = p.get_last_lo_pos(), ident = parse_ident(p),
|
||||
tps = parse_ty_params(p), meths = parse_ty_methods(p);
|
||||
ret mk_item(p, lo, p.get_last_hi_pos(), ident,
|
||||
ast::item_iface(tps, meths), attrs);
|
||||
}
|
||||
|
||||
fn parse_item_impl(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
||||
let lo = p.get_last_lo_pos(), ident, tps, ifce;
|
||||
fn wrap_path(p: parser, pt: @ast::path) -> @ast::ty {
|
||||
@{node: ast::ty_path(pt, p.get_id()), span: pt.span}
|
||||
}
|
||||
if eat_word(p, "of") {
|
||||
let path = parse_path_and_ty_param_substs(p, false);
|
||||
tps = vec::map(path.node.types, {|tp|
|
||||
alt tp.node {
|
||||
ast::ty_path(pt, _) {
|
||||
if vec::len(pt.node.idents) == 1u &&
|
||||
vec::len(pt.node.types) == 0u {
|
||||
ret {ident: pt.node.idents[0], kind: ast::kind_sendable};
|
||||
}
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
p.fatal("only single-word, parameter-less types allowed here");
|
||||
});
|
||||
ident = path.node.idents[vec::len(path.node.idents)-1u];
|
||||
ifce = some(wrap_path(p, path));
|
||||
} else {
|
||||
ident = parse_ident(p);
|
||||
tps = parse_ty_params(p);
|
||||
ifce = if eat_word(p, "of") {
|
||||
some(wrap_path(p, parse_path_and_ty_param_substs(p, false)))
|
||||
} else { none };
|
||||
};
|
||||
expect_word(p, "for");
|
||||
let ty = parse_ty(p, false), meths = [];
|
||||
expect(p, token::LBRACE);
|
||||
while !eat(p, token::RBRACE) { meths += [parse_method(p, true)]; }
|
||||
ret mk_item(p, lo, p.get_last_hi_pos(), ident,
|
||||
ast::item_impl(tps, ty, meths), attrs);
|
||||
ast::item_impl(tps, ifce, ty, meths), attrs);
|
||||
}
|
||||
|
||||
fn parse_item_res(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
||||
@ -2145,6 +2148,8 @@ fn parse_item(p: parser, attrs: [ast::attribute]) -> option::t<@ast::item> {
|
||||
} else if is_word(p, "obj") && p.look_ahead(1u) != token::LPAREN {
|
||||
p.bump();
|
||||
ret some(parse_item_obj(p, attrs));
|
||||
} else if eat_word(p, "iface") {
|
||||
ret some(parse_item_iface(p, attrs));
|
||||
} else if eat_word(p, "impl") {
|
||||
ret some(parse_item_impl(p, attrs));
|
||||
} else if eat_word(p, "resource") {
|
||||
|
@ -311,14 +311,7 @@ fn print_type(s: ps, &&ty: @ast::ty) {
|
||||
ast::ty_obj(methods) {
|
||||
head(s, "obj");
|
||||
bopen(s);
|
||||
for m: ast::ty_method in methods {
|
||||
hardbreak_if_not_bol(s);
|
||||
cbox(s, indent_unit);
|
||||
maybe_print_comment(s, m.span.lo);
|
||||
print_ty_fn(s, m.decl, some(m.ident));
|
||||
word(s.s, ";");
|
||||
end(s);
|
||||
}
|
||||
for m in methods { print_ty_method(s, m); }
|
||||
bclose(s, ty.span);
|
||||
}
|
||||
ast::ty_path(path, _) { print_path(s, path, false); }
|
||||
@ -473,11 +466,19 @@ fn print_item(s: ps, &&item: @ast::item) {
|
||||
}
|
||||
bclose(s, item.span);
|
||||
}
|
||||
ast::item_impl(tps, ty, methods) {
|
||||
ast::item_impl(tps, ifce, ty, methods) {
|
||||
head(s, "impl");
|
||||
word(s.s, item.ident);
|
||||
print_type_params(s, tps);
|
||||
nbsp(s);
|
||||
space(s.s);
|
||||
alt ifce {
|
||||
some(ty) {
|
||||
word_nbsp(s, "of");
|
||||
print_type(s, ty);
|
||||
space(s.s);
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
word_nbsp(s, "for");
|
||||
print_type(s, ty);
|
||||
space(s.s);
|
||||
@ -491,6 +492,14 @@ fn print_item(s: ps, &&item: @ast::item) {
|
||||
}
|
||||
bclose(s, item.span);
|
||||
}
|
||||
ast::item_iface(tps, methods) {
|
||||
head(s, "iface");
|
||||
word(s.s, item.ident);
|
||||
print_type_params(s, tps);
|
||||
bopen(s);
|
||||
for meth in methods { print_ty_method(s, meth); }
|
||||
bclose(s, item.span);
|
||||
}
|
||||
ast::item_res(decl, tps, body, dt_id, ct_id) {
|
||||
head(s, "resource");
|
||||
word(s.s, item.ident);
|
||||
@ -506,6 +515,15 @@ fn print_item(s: ps, &&item: @ast::item) {
|
||||
s.ann.post(ann_node);
|
||||
}
|
||||
|
||||
fn print_ty_method(s: ps, m: ast::ty_method) {
|
||||
hardbreak_if_not_bol(s);
|
||||
cbox(s, indent_unit);
|
||||
maybe_print_comment(s, m.span.lo);
|
||||
print_ty_fn(s, m.decl, some(m.ident));
|
||||
word(s.s, ";");
|
||||
end(s);
|
||||
}
|
||||
|
||||
fn print_outer_attributes(s: ps, attrs: [ast::attribute]) {
|
||||
let count = 0;
|
||||
for attr: ast::attribute in attrs {
|
||||
|
@ -120,13 +120,20 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
|
||||
some(m.ident), m.id, e, v);
|
||||
}
|
||||
}
|
||||
item_impl(_, ty, methods) {
|
||||
visit_ty(ty, e, v);
|
||||
item_impl(_, ifce, ty, methods) {
|
||||
alt ifce { some(ty) { v.visit_ty(ty, e, v); } _ {} }
|
||||
v.visit_ty(ty, e, v);
|
||||
for m in methods {
|
||||
v.visit_fn_proto(m.decl, m.tps, m.body, m.span,
|
||||
some(m.ident), m.id, e, v);
|
||||
}
|
||||
}
|
||||
item_iface(_, methods) {
|
||||
for m in methods {
|
||||
for a in m.decl.inputs { v.visit_ty(a.ty, e, v); }
|
||||
v.visit_ty(m.decl.output, e, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user