Add visit_ty_params to visit.rs
And use it to make typechecking of bounds less error-prone.
This commit is contained in:
parent
e11d207113
commit
42f6608ffd
|
@ -1514,7 +1514,7 @@ fn lookup_method(fcx: @fn_ctxt, isc: resolve::iscopes,
|
|||
ty::bound_iface(t) {
|
||||
let (iid, tps) = alt ty::struct(tcx, t) {
|
||||
ty::ty_iface(i, tps) { (i, tps) }
|
||||
_ { ret none; }
|
||||
_ { cont; }
|
||||
};
|
||||
let ifce_methods = ty::iface_methods(tcx, iid);
|
||||
alt vec::position_pred(*ifce_methods, {|m| m.ident == name}) {
|
||||
|
@ -2765,15 +2765,12 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
|
|||
alt it.node {
|
||||
ast::item_const(_, e) { check_const(ccx, it.span, e, it.id); }
|
||||
ast::item_fn(decl, tps, body) {
|
||||
check_ty_params(ccx, tps);
|
||||
check_fn(ccx, ast::proto_bare, decl, body, it.id, none);
|
||||
}
|
||||
ast::item_res(decl, tps, body, dtor_id, _) {
|
||||
check_ty_params(ccx, tps);
|
||||
check_fn(ccx, ast::proto_bare, decl, body, dtor_id, none);
|
||||
}
|
||||
ast::item_obj(ob, tps, _) {
|
||||
check_ty_params(ccx, tps);
|
||||
// We're entering an object, so gather up the info we need.
|
||||
ccx.self_infos += [self_obj(ob.fields,
|
||||
ccx.tcx.tcache.get(local_def(it.id)).ty)];
|
||||
|
@ -2783,10 +2780,8 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
|
|||
vec::pop(ccx.self_infos);
|
||||
}
|
||||
ast::item_impl(tps, ifce, ty, ms) {
|
||||
check_ty_params(ccx, tps);
|
||||
ccx.self_infos += [self_impl(ast_ty_to_ty(ccx.tcx, m_check, ty))];
|
||||
let my_methods = vec::map(ms, {|m|
|
||||
check_ty_params(ccx, m.tps);
|
||||
check_method(ccx, m);
|
||||
ty_of_method(ccx.tcx, m_check, m)
|
||||
});
|
||||
|
@ -2821,20 +2816,10 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
|
|||
_ {}
|
||||
}
|
||||
}
|
||||
ast::item_iface(tps, _) | ast::item_ty(_, tps) | ast::item_tag(_, tps) {
|
||||
check_ty_params(ccx, tps);
|
||||
}
|
||||
_ {/* nothing to do */ }
|
||||
}
|
||||
}
|
||||
|
||||
fn check_native_item(ccx: @crate_ctxt, it: @ast::native_item) {
|
||||
alt it.node {
|
||||
ast::native_item_fn(_, tps) { check_ty_params(ccx, tps); }
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_ty_params(ccx: @crate_ctxt, tps: [ast::ty_param]) {
|
||||
for tp in tps {
|
||||
let i = 0u;
|
||||
|
@ -3100,11 +3085,11 @@ fn check_crate(tcx: ty::ctxt, impl_map: resolve::impl_map,
|
|||
method_map: std::map::new_int_hash(),
|
||||
dict_map: std::map::new_int_hash(),
|
||||
tcx: tcx};
|
||||
let visit =
|
||||
visit::mk_simple_visitor(@{visit_item: bind check_item(ccx, _),
|
||||
visit_native_item:
|
||||
bind check_native_item(ccx, _)
|
||||
with *visit::default_simple_visitor()});
|
||||
let visit = visit::mk_simple_visitor(@{
|
||||
visit_item: bind check_item(ccx, _),
|
||||
visit_ty_params: bind check_ty_params(ccx, _)
|
||||
with *visit::default_simple_visitor()
|
||||
});
|
||||
visit::visit_crate(*crate, (), visit);
|
||||
check_for_main_fn(tcx, crate);
|
||||
tcx.sess.abort_if_errors();
|
||||
|
|
|
@ -52,6 +52,7 @@ type visitor<E> =
|
|||
visit_decl: fn@(@decl, E, vt<E>),
|
||||
visit_expr: fn@(@expr, E, vt<E>),
|
||||
visit_ty: fn@(@ty, E, vt<E>),
|
||||
visit_ty_params: fn@([ty_param], E, vt<E>),
|
||||
visit_constr: fn@(@path, span, node_id, E, vt<E>),
|
||||
visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id, E, vt<E>)};
|
||||
|
||||
|
@ -68,6 +69,7 @@ fn default_visitor<E>() -> visitor<E> {
|
|||
visit_decl: bind visit_decl::<E>(_, _, _),
|
||||
visit_expr: bind visit_expr::<E>(_, _, _),
|
||||
visit_ty: bind skip_ty::<E>(_, _, _),
|
||||
visit_ty_params: bind visit_ty_params::<E>(_, _, _),
|
||||
visit_constr: bind visit_constr::<E>(_, _, _, _, _),
|
||||
visit_fn: bind visit_fn::<E>(_, _, _, _, _, _, _)};
|
||||
}
|
||||
|
@ -113,19 +115,19 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
|
|||
for vi: @view_item in nm.view_items { v.visit_view_item(vi, e, v); }
|
||||
for ni: @native_item in nm.items { v.visit_native_item(ni, e, v); }
|
||||
}
|
||||
item_ty(t, tps) { v.visit_ty(t, e, v); visit_ty_params(tps, e, v); }
|
||||
item_ty(t, tps) { v.visit_ty(t, e, v); v.visit_ty_params(tps, e, v); }
|
||||
item_res(decl, tps, body, dtor_id, _) {
|
||||
v.visit_fn(fk_res(i.ident, tps), decl, body, i.span,
|
||||
dtor_id, e, v);
|
||||
}
|
||||
item_tag(variants, tps) {
|
||||
visit_ty_params(tps, e, v);
|
||||
v.visit_ty_params(tps, e, v);
|
||||
for vr: variant in variants {
|
||||
for va: variant_arg in vr.node.args { v.visit_ty(va.ty, e, v); }
|
||||
}
|
||||
}
|
||||
item_obj(ob, tps, _) {
|
||||
visit_ty_params(tps, e, v);
|
||||
v.visit_ty_params(tps, e, v);
|
||||
for f: obj_field in ob.fields { v.visit_ty(f.ty, e, v); }
|
||||
for m: @method in ob.methods {
|
||||
v.visit_fn(fk_method(m.ident, m.tps), m.decl, m.body, m.span,
|
||||
|
@ -133,7 +135,7 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
|
|||
}
|
||||
}
|
||||
item_impl(tps, ifce, ty, methods) {
|
||||
visit_ty_params(tps, e, v);
|
||||
v.visit_ty_params(tps, e, v);
|
||||
alt ifce { some(ty) { v.visit_ty(ty, e, v); } _ {} }
|
||||
v.visit_ty(ty, e, v);
|
||||
for m in methods {
|
||||
|
@ -142,7 +144,7 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
|
|||
}
|
||||
}
|
||||
item_iface(tps, methods) {
|
||||
visit_ty_params(tps, e, v);
|
||||
v.visit_ty_params(tps, e, v);
|
||||
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);
|
||||
|
@ -217,7 +219,7 @@ fn visit_pat<E>(p: @pat, e: E, v: vt<E>) {
|
|||
fn visit_native_item<E>(ni: @native_item, e: E, v: vt<E>) {
|
||||
alt ni.node {
|
||||
native_item_fn(fd, tps) {
|
||||
visit_ty_params(tps, e, v);
|
||||
v.visit_ty_params(tps, e, v);
|
||||
visit_fn_decl(fd, e, v);
|
||||
}
|
||||
native_item_ty. { }
|
||||
|
@ -246,7 +248,7 @@ fn visit_fn_decl<E>(fd: fn_decl, e: E, v: vt<E>) {
|
|||
fn visit_fn<E>(fk: fn_kind, decl: fn_decl, body: blk, _sp: span,
|
||||
_id: node_id, e: E, v: vt<E>) {
|
||||
visit_fn_decl(decl, e, v);
|
||||
visit_ty_params(tps_of_fn(fk), e, v);
|
||||
v.visit_ty_params(tps_of_fn(fk), e, v);
|
||||
v.visit_block(body, e, v);
|
||||
}
|
||||
|
||||
|
@ -414,6 +416,7 @@ type simple_visitor =
|
|||
visit_decl: fn@(@decl),
|
||||
visit_expr: fn@(@expr),
|
||||
visit_ty: fn@(@ty),
|
||||
visit_ty_params: fn@([ty_param]),
|
||||
visit_constr: fn@(@path, span, node_id),
|
||||
visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id)};
|
||||
|
||||
|
@ -432,6 +435,7 @@ fn default_simple_visitor() -> simple_visitor {
|
|||
visit_decl: fn(_d: @decl) { },
|
||||
visit_expr: fn(_e: @expr) { },
|
||||
visit_ty: simple_ignore_ty,
|
||||
visit_ty_params: fn(_ps: [ty_param]) {},
|
||||
visit_constr: fn(_p: @path, _sp: span, _id: node_id) { },
|
||||
visit_fn: fn(_fk: fn_kind, _d: fn_decl, _b: blk, _sp: span,
|
||||
_id: node_id) { }
|
||||
|
@ -488,6 +492,10 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> {
|
|||
f(ty);
|
||||
visit_ty(ty, e, v);
|
||||
}
|
||||
fn v_ty_params(f: fn@([ty_param]), ps: [ty_param], &&e: (), v: vt<()>) {
|
||||
f(ps);
|
||||
visit_ty_params(ps, e, v);
|
||||
}
|
||||
fn v_constr(f: fn@(@path, span, node_id), pt: @path, sp: span,
|
||||
id: node_id, &&e: (), v: vt<()>) {
|
||||
f(pt, sp, id);
|
||||
|
@ -517,6 +525,7 @@ fn mk_simple_visitor(v: simple_visitor) -> vt<()> {
|
|||
visit_decl: bind v_decl(v.visit_decl, _, _, _),
|
||||
visit_expr: bind v_expr(v.visit_expr, _, _, _),
|
||||
visit_ty: visit_ty,
|
||||
visit_ty_params: bind v_ty_params(v.visit_ty_params, _, _, _),
|
||||
visit_constr: bind v_constr(v.visit_constr, _, _, _, _, _),
|
||||
visit_fn: bind v_fn(v.visit_fn, _, _, _, _, _, _, _)
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue