From c6dec379b0870ea1a56bfbe9126b5f9c751a17ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= 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 999f6a7a1b8..4682daa48f2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -446,6 +446,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 9e082ae47b1..01bb7311e33 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 6ce899f6fdf..42322c20556 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; }