From e4e2d6d1a15ae350301bb94452f968ba99d2ec6e Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 19 Dec 2011 15:42:52 +0100 Subject: [PATCH] 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 --- src/comp/middle/resolve.rs | 12 +++++++++++- 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 90d560f1eb1a..bdb723ebaf85 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) { - 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 cacedb5dae06..383a4387a5d9 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. {