From 0db6e20b2ec62e6aa1e2445ddf1068028344e9cd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?=
 <respindola@mozilla.com>
Date: Fri, 21 Jan 2011 15:01:20 -0500
Subject: [PATCH] Implement a bit of type parameter matching to get a simple
 case working.

---
 src/Makefile               |  1 +
 src/comp/middle/resolve.rs |  4 ----
 src/comp/middle/typeck.rs  | 32 +++++++++++++++++++++++++++++++-
 3 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/src/Makefile b/src/Makefile
index 4f27b434abf66..5ba4bf0ff32ec 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -442,6 +442,7 @@ TEST_XFAILS_RUSTC := $(filter-out \
                         generic-fn-infer.rs \
                         generic-drop-glue.rs \
                         generic-tup.rs \
+                        generic-type.rs \
                         hello.rs \
                         int.rs \
                         i32-sub.rs \
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index 9e082ae47b110..01bb7311e3300 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -476,10 +476,6 @@ fn fold_ty_path(&env e, &span sp, ast.path p, &option.t[def] d) -> @ast.ty {
         e.sess.unimpl("resolving path ty with >1 component");
     }
 
-    if (_vec.len[@ast.ty](p.node.types) > 0u) {
-        e.sess.unimpl("resolving path ty with ty params");
-    }
-
     auto d_ = lookup_name(e, p.node.idents.(0));
 
     alt (d_) {
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 4d9efd4a5da30..24a5003f98a23 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -81,6 +81,23 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
         ret rec(mode=arg.mode, ty=ast_ty_to_ty(getter, arg.ty));
     }
 
+    fn replace_type_params(@ty.t t, ty_table param_map) -> @ty.t {
+        state obj param_replacer(ty_table param_map) {
+            fn fold_simple_ty(@ty.t t) -> @ty.t {
+                alt (t.struct) {
+                    case (ty.ty_param(?param_def)) {
+                        ret param_map.get(param_def);
+                    }
+                    case (_) {
+                        ret t;
+                    }
+                }
+            }
+        }
+        auto replacer = param_replacer(param_map);
+        ret ty.fold_ty(replacer, t);
+    }
+
     auto mut = ast.imm;
     auto sty;
     auto cname = none[str];
@@ -122,7 +139,20 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
                 case (ast.def_ty(?id)) {
                     // TODO: maybe record cname chains so we can do
                     // "foo = int" like OCaml?
-                    sty = getter(id).ty.struct;
+                    auto ty_and_params = getter(id);
+                    auto params = ty_and_params.params;
+                    auto num_type_params = _vec.len[@ast.ty](path.node.types);
+                    check(num_type_params == _vec.len[ast.ty_param](params));
+
+                    auto param_map = common.new_def_hash[@ty.t]();
+                    for each (uint i in _uint.range(0u, num_type_params)) {
+                        auto x = path.node.types.(i);
+                        auto y = params.(i);
+                        param_map.insert(y.id, ast_ty_to_ty(getter, x));
+                    }
+
+                    sty = replace_type_params(ty_and_params.ty,
+                                              param_map).struct;
                 }
                 case (ast.def_ty_arg(?id))  { sty = ty.ty_param(id); }
                 case (_)                    { fail; }