From 42f6608ffdeb823c2299d5166a19b9557eb30da1 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 4 Jan 2012 16:37:39 +0100 Subject: [PATCH] Add visit_ty_params to visit.rs And use it to make typechecking of bounds less error-prone. --- src/comp/middle/typeck.rs | 27 ++++++--------------------- src/comp/syntax/visit.rs | 23 ++++++++++++++++------- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 61ecf68e025..2e2a56d4ff5 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -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(); diff --git a/src/comp/syntax/visit.rs b/src/comp/syntax/visit.rs index e2767160302..1e5b88e1aa6 100644 --- a/src/comp/syntax/visit.rs +++ b/src/comp/syntax/visit.rs @@ -52,6 +52,7 @@ type visitor = visit_decl: fn@(@decl, E, vt), visit_expr: fn@(@expr, E, vt), visit_ty: fn@(@ty, E, vt), + visit_ty_params: fn@([ty_param], E, vt), visit_constr: fn@(@path, span, node_id, E, vt), visit_fn: fn@(fn_kind, fn_decl, blk, span, node_id, E, vt)}; @@ -68,6 +69,7 @@ fn default_visitor() -> visitor { visit_decl: bind visit_decl::(_, _, _), visit_expr: bind visit_expr::(_, _, _), visit_ty: bind skip_ty::(_, _, _), + visit_ty_params: bind visit_ty_params::(_, _, _), visit_constr: bind visit_constr::(_, _, _, _, _), visit_fn: bind visit_fn::(_, _, _, _, _, _, _)}; } @@ -113,19 +115,19 @@ fn visit_item(i: @item, e: E, v: vt) { 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(i: @item, e: E, v: vt) { } } 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(i: @item, e: E, v: vt) { } } 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(p: @pat, e: E, v: vt) { fn visit_native_item(ni: @native_item, e: E, v: vt) { 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(fd: fn_decl, e: E, v: vt) { fn visit_fn(fk: fn_kind, decl: fn_decl, body: blk, _sp: span, _id: node_id, e: E, v: vt) { 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, _, _, _, _, _, _, _) });