Skip to content

Commit e4e2d6d

Browse files
committed
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
1 parent 619d7c3 commit e4e2d6d

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

src/comp/middle/resolve.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,17 @@ fn resolve_names(e: @env, c: @ast::crate) {
370370

371371
// Visit helper functions
372372
fn visit_item_with_scope(i: @ast::item, sc: scopes, v: vt<scopes>) {
373-
visit::visit_item(i, cons(scope_item(i), @sc), v);
373+
let sc = cons(scope_item(i), @sc);
374+
alt i.node {
375+
ast::item_impl(tps, sty, methods) {
376+
visit::visit_ty(sty, sc, v);
377+
for m in methods {
378+
v.visit_fn(m.node.meth, tps + m.node.tps, m.span,
379+
some(m.node.ident), m.node.id, sc, v);
380+
}
381+
}
382+
_ { visit::visit_item(i, sc, v); }
383+
}
374384
}
375385

376386
fn visit_native_item_with_scope(ni: @ast::native_item, sc: scopes,

src/comp/middle/typeck.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,8 @@ mod collect {
692692
let ty = ty::method_ty_to_fn_ty(
693693
cx.tcx, ty_of_method(cx.tcx, m_collect, m));
694694
cx.tcx.tcache.insert(local_def(m.node.id),
695-
{kinds: [], ty: ty});
695+
{kinds: ty_param_kinds(m.node.tps),
696+
ty: ty});
696697
write::ty_only(cx.tcx, m.node.id, ty);
697698
}
698699
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,
21742175
}
21752176
}
21762177
} else { csearch::get_type(tcx, method.did).ty };
2177-
let ids = ids;
2178-
if method.n_tps > 0u {
2178+
let tvars = vec::map(ids, {|id| ty::mk_var(tcx, id)});
2179+
let n_tps = vec::len(ids);
2180+
if method.n_tps + n_tps > 0u {
21792181
let b = bind_params_in_type(expr.span, tcx,
2180-
bind next_ty_var_id(fcx),
2181-
fty, method.n_tps);
2182-
ids += b.ids;
2182+
bind next_ty_var_id(fcx), fty,
2183+
n_tps + method.n_tps);
2184+
let _tvars = vec::map(b.ids, {|id| ty::mk_var(tcx, id)});
2185+
let i = 0;
2186+
for v in tvars {
2187+
demand::simple(fcx, expr.span, v, _tvars[i]);
2188+
i += 1;
2189+
}
2190+
tvars = _tvars;
21832191
fty = b.ty;
21842192
if n_tys > 0u {
21852193
if n_tys != method.n_tps {
@@ -2190,7 +2198,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
21902198
}
21912199
let i = 0u;
21922200
for ty in tys {
2193-
let tvar = ty::mk_var(fcx.ccx.tcx, b.ids[i]);
2201+
let tvar = tvars[i + n_tps];
21942202
let t_subst = ast_ty_to_ty_crate(fcx.ccx, ty);
21952203
demand::simple(fcx, expr.span, tvar, t_subst);
21962204
i += 1u;
@@ -2201,8 +2209,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
22012209
"this method does not take type \
22022210
parameters");
22032211
}
2204-
let substs = vec::map(ids, {|id| ty::mk_var(tcx, id)});
2205-
write::ty_fixup(fcx, id, {substs: some(substs), ty: fty});
2212+
write::ty_fixup(fcx, id, {substs: some(tvars), ty: fty});
22062213
fcx.ccx.method_map.insert(id, method.did);
22072214
}
22082215
none. {

0 commit comments

Comments
 (0)