diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2011-12-19 15:42:52 +0100 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2011-12-19 15:43:02 +0100 |
| commit | e4e2d6d1a15ae350301bb94452f968ba99d2ec6e (patch) | |
| tree | 25907a1f991b3b3c0ff8e131020bb9af0563c41b | |
| parent | 619d7c3f72a969c62789383af7d1a1446177adfc (diff) | |
| download | rust-e4e2d6d1a15ae350301bb94452f968ba99d2ec6e.tar.gz rust-e4e2d6d1a15ae350301bb94452f968ba99d2ec6e.zip | |
Fix bug in type parameter handling for impl methods
The parameters of the impl weren't being combined in the right way with the parameters of the methods. The test worked only by accident. Issue #1227
| -rw-r--r-- | src/comp/middle/resolve.rs | 12 | ||||
| -rw-r--r-- | src/comp/middle/typeck.rs | 25 |
2 files changed, 27 insertions, 10 deletions
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index 90d560f1eb1..bdb723ebaf8 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -370,7 +370,17 @@ fn resolve_names(e: @env, c: @ast::crate) { // Visit helper functions fn visit_item_with_scope(i: @ast::item, sc: scopes, v: vt<scopes>) { - visit::visit_item(i, cons(scope_item(i), @sc), v); + let sc = cons(scope_item(i), @sc); + alt i.node { + ast::item_impl(tps, sty, methods) { + visit::visit_ty(sty, sc, v); + for m in methods { + v.visit_fn(m.node.meth, tps + m.node.tps, m.span, + some(m.node.ident), m.node.id, sc, v); + } + } + _ { visit::visit_item(i, sc, v); } + } } fn visit_native_item_with_scope(ni: @ast::native_item, sc: scopes, diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index cacedb5dae0..383a4387a5d 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -692,7 +692,8 @@ mod collect { let ty = ty::method_ty_to_fn_ty( cx.tcx, ty_of_method(cx.tcx, m_collect, m)); cx.tcx.tcache.insert(local_def(m.node.id), - {kinds: [], ty: ty}); + {kinds: ty_param_kinds(m.node.tps), + ty: ty}); write::ty_only(cx.tcx, m.node.id, ty); } write::ty_only(cx.tcx, it.id, ast_ty_to_ty(cx.tcx, m_collect, @@ -2174,12 +2175,19 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, } } } else { csearch::get_type(tcx, method.did).ty }; - let ids = ids; - if method.n_tps > 0u { + let tvars = vec::map(ids, {|id| ty::mk_var(tcx, id)}); + let n_tps = vec::len(ids); + if method.n_tps + n_tps > 0u { let b = bind_params_in_type(expr.span, tcx, - bind next_ty_var_id(fcx), - fty, method.n_tps); - ids += b.ids; + bind next_ty_var_id(fcx), fty, + n_tps + method.n_tps); + let _tvars = vec::map(b.ids, {|id| ty::mk_var(tcx, id)}); + let i = 0; + for v in tvars { + demand::simple(fcx, expr.span, v, _tvars[i]); + i += 1; + } + tvars = _tvars; fty = b.ty; if n_tys > 0u { if n_tys != method.n_tps { @@ -2190,7 +2198,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, } let i = 0u; for ty in tys { - let tvar = ty::mk_var(fcx.ccx.tcx, b.ids[i]); + let tvar = tvars[i + n_tps]; let t_subst = ast_ty_to_ty_crate(fcx.ccx, ty); demand::simple(fcx, expr.span, tvar, t_subst); i += 1u; @@ -2201,8 +2209,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, "this method does not take type \ parameters"); } - let substs = vec::map(ids, {|id| ty::mk_var(tcx, id)}); - write::ty_fixup(fcx, id, {substs: some(substs), ty: fty}); + write::ty_fixup(fcx, id, {substs: some(tvars), ty: fty}); fcx.ccx.method_map.insert(id, method.did); } none. { |
