diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2012-01-03 16:07:26 +0100 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2012-01-03 16:18:40 +0100 |
| commit | 5ea3c96938e6defa894c4ae646a75ba00c4dce22 (patch) | |
| tree | 29e1f046ab8e0ef64a3f18c763a0dae4a3c73809 /src/comp | |
| parent | 506a6ec38b4e5f5fc80d8c6bfc388e5cdba4d772 (diff) | |
| download | rust-5ea3c96938e6defa894c4ae646a75ba00c4dce22.tar.gz rust-5ea3c96938e6defa894c4ae646a75ba00c4dce22.zip | |
Wire in resolution of param bounds for method calls
Issue #1227
Diffstat (limited to 'src/comp')
| -rw-r--r-- | src/comp/middle/ty.rs | 2 | ||||
| -rw-r--r-- | src/comp/middle/typeck.rs | 52 |
2 files changed, 39 insertions, 15 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index dd20be61057..1b1eb83c4a2 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -1462,8 +1462,6 @@ fn constrs_eq(cs: [@constr], ds: [@constr]) -> bool { // Type lookups fn node_id_to_ty_param_substs_opt_and_ty(cx: ctxt, id: ast::node_id) -> ty_param_substs_opt_and_ty { - - // Pull out the node type table. alt smallintmap::find(*cx.node_types, id as uint) { none. { diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 27d94559139..662516141dc 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -2875,11 +2875,21 @@ type dict_map = hashmap<ast::node_id, dict_res>; // Detect points where an interface-bounded type parameter is instantiated, // resolve the impls for the parameters. fn resolve_dicts(tcx: ty::ctxt, impl_map: resolve::impl_map, - crate: @ast::crate) -> dict_map { + method_map: method_map, crate: @ast::crate) -> dict_map { type ccx = {tcx: ty::ctxt, impl_map: resolve::impl_map, + method_map: method_map, dict_map: dict_map}; - let cx = {tcx: tcx, impl_map: impl_map, dict_map: new_int_hash()}; + let cx = {tcx: tcx, impl_map: impl_map, + method_map: method_map, dict_map: new_int_hash()}; + + fn has_iface_bounds(tps: [ty::param_bounds]) -> bool { + vec::any(tps, {|bs| + vec::any(*bs, {|b| + alt b { ty::bound_iface(_) { true } _ { false } } + }) + }) + } fn resolve_expr(ex: @ast::expr, cx: ccx, v: visit::vt<ccx>) { alt ex.node { ast::expr_path(_) { @@ -2889,14 +2899,25 @@ fn resolve_dicts(tcx: ty::ctxt, impl_map: resolve::impl_map, some(ts) { let did = ast_util::def_id_of_def(cx.tcx.def_map.get(ex.id)); let item_ty = ty::lookup_item_type(cx.tcx, did); - if vec::any(*item_ty.bounds, {|bs| - vec::any(*bs, {|b| - alt b { ty::bound_iface(_) { true } _ { false } } - }) - }) { + if has_iface_bounds(*item_ty.bounds) { let impls = cx.impl_map.get(ex.id); cx.dict_map.insert(ex.id, lookup_dicts( - cx.tcx, impls, ex.span, *item_ty.bounds, ts)); + cx.tcx, impls, ex.span, item_ty.bounds, ts)); + } + } + _ {} + } + } + // Must resolve bounds on methods with bounded params + ast::expr_field(_, _, _) { + alt cx.method_map.find(ex.id) { + some(method_static(did)) { + let bounds = ty::lookup_item_type(cx.tcx, did).bounds; + if has_iface_bounds(*bounds) { + let tys = ty::node_id_to_type_params(cx.tcx, ex.id); + let iscs = cx.impl_map.get(ex.id); + cx.dict_map.insert(ex.id, lookup_dicts( + cx.tcx, iscs, ex.span, bounds, tys)); } } _ {} @@ -2906,8 +2927,9 @@ fn resolve_dicts(tcx: ty::ctxt, impl_map: resolve::impl_map, } visit::visit_expr(ex, cx, v); } + fn lookup_dicts(tcx: ty::ctxt, isc: resolve::iscopes, sp: span, - bounds: [ty::param_bounds], tys: [ty::t]) + bounds: @[ty::param_bounds], tys: [ty::t]) -> dict_res { let result = [], i = 0u; for ty in tys { @@ -2923,6 +2945,7 @@ fn resolve_dicts(tcx: ty::ctxt, impl_map: resolve::impl_map, } @result } + fn lookup_dict(tcx: ty::ctxt, isc: resolve::iscopes, sp: span, ty: ty::t, iface_ty: ty::t) -> dict_origin { let iface_id = alt ty::struct(tcx, iface_ty) { @@ -2951,6 +2974,7 @@ fn resolve_dicts(tcx: ty::ctxt, impl_map: resolve::impl_map, for im in *impls { if im.iface_did == some(iface_id) { let self_ty = impl_self_ty(tcx, im.did).ty; + let im_bs = ty::lookup_item_type(tcx, im.did).bounds; let params = @mutable [mutable]; alt ty::unify::unify(ty, self_ty, ty::unify::bind_params(params), @@ -2963,9 +2987,10 @@ fn resolve_dicts(tcx: ty::ctxt, impl_map: resolve::impl_map, } else { let params = vec::map_mut( *params, {|p| option::get(p)}); - // FIXME[impl] check for sub-bounds - found = some(dict_static( - im.did, params, @[])); + let subres = lookup_dicts(tcx, isc, sp, + im_bs, params); + found = some(dict_static(im.did, params, + subres)); } } _ {} @@ -2985,6 +3010,7 @@ fn resolve_dicts(tcx: ty::ctxt, impl_map: resolve::impl_map, ty_to_str(tcx, iface_ty) + " for " + ty_to_str(tcx, ty)); } + visit::visit_crate(*crate, cx, visit::mk_vt(@{ visit_expr: resolve_expr with *visit::default_visitor() @@ -3006,7 +3032,7 @@ fn check_crate(tcx: ty::ctxt, impl_map: resolve::impl_map, bind check_native_item(ccx, _) with *visit::default_simple_visitor()}); visit::visit_crate(*crate, (), visit); - let dict_map = resolve_dicts(tcx, impl_map, crate); + let dict_map = resolve_dicts(tcx, impl_map, ccx.method_map, crate); check_for_main_fn(tcx, crate); tcx.sess.abort_if_errors(); (ccx.method_map, dict_map) |
