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
This commit is contained in:
Marijn Haverbeke 2011-12-19 15:42:52 +01:00
parent 619d7c3f72
commit e4e2d6d1a1
2 changed files with 27 additions and 10 deletions

View File

@ -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,

View File

@ -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. {