about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-12-19 15:42:52 +0100
committerMarijn Haverbeke <marijnh@gmail.com>2011-12-19 15:43:02 +0100
commite4e2d6d1a15ae350301bb94452f968ba99d2ec6e (patch)
tree25907a1f991b3b3c0ff8e131020bb9af0563c41b
parent619d7c3f72a969c62789383af7d1a1446177adfc (diff)
downloadrust-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.rs12
-rw-r--r--src/comp/middle/typeck.rs25
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. {