about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-03-08 14:55:39 -0800
committerPatrick Walton <pcwalton@mimiga.net>2011-03-08 14:55:39 -0800
commitda9ea9ab69ebcf32ff9cc1ad557a6c2a5134bd0d (patch)
treef5499480dab04259e5137eed10342acb5e9a271f /src/comp
parent16344a0145555448fc202a2bb8eebd2477dc10b2 (diff)
downloadrust-da9ea9ab69ebcf32ff9cc1ad557a6c2a5134bd0d.tar.gz
rust-da9ea9ab69ebcf32ff9cc1ad557a6c2a5134bd0d.zip
rustc: Move type parameter resolution from translation into the typechecker
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/trans.rs15
-rw-r--r--src/comp/middle/typeck.rs64
2 files changed, 76 insertions, 3 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 7457a5326bd..4064cc0a053 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -3083,8 +3083,19 @@ fn lval_generic_fn(@block_ctxt cx,
 
     check (cx.fcx.ccx.fn_pairs.contains_key(fn_id));
     auto lv = lval_val(cx, cx.fcx.ccx.fn_pairs.get(fn_id));
-    auto monoty = node_ann_type(cx.fcx.ccx, ann);
-    auto tys = ty.resolve_ty_params(tpt, monoty);
+
+    auto monoty;
+    auto tys;
+    alt (ann) {
+        case (ast.ann_none) {
+            cx.fcx.ccx.sess.bug("no type annotation for path!");
+            fail;
+        }
+        case (ast.ann_type(?monoty_, ?tps)) {
+            monoty = monoty_;
+            tys = option.get[vec[@ty.t]](tps);
+        }
+    }
 
     if (_vec.len[@ty.t](tys) != 0u) {
         auto bcx = cx;
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 1538302011e..81458d2d755 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -128,6 +128,37 @@ fn substitute_ty_params(&@crate_ctxt ccx,
     ret ty.fold_ty(substituter, typ);
 }
 
+// Returns the type parameters and polytype of an item, if it's an item that
+// supports type parameters.
+fn ty_params_for_item(@crate_ctxt ccx, &ast.def d)
+        -> option.t[ty.ty_params_and_ty] {
+    auto params_id;
+    auto types_id;
+    alt (d) {
+        case (ast.def_fn(?id))          { params_id = id; types_id = id; }
+        case (ast.def_obj(?id))         { params_id = id; types_id = id; }
+        case (ast.def_obj_field(_))     { ret none[ty.ty_params_and_ty]; }
+        case (ast.def_mod(_))           { ret none[ty.ty_params_and_ty]; }
+        case (ast.def_const(_))         { ret none[ty.ty_params_and_ty]; }
+        case (ast.def_arg(_))           { ret none[ty.ty_params_and_ty]; }
+        case (ast.def_local(_))         { ret none[ty.ty_params_and_ty]; }
+        case (ast.def_variant(?tid, ?vid)) {
+            params_id = tid;
+            types_id = vid;
+        }
+        case (ast.def_ty(_))            { ret none[ty.ty_params_and_ty]; }
+        case (ast.def_ty_arg(_))        { ret none[ty.ty_params_and_ty]; }
+        case (ast.def_binding(_))       { ret none[ty.ty_params_and_ty]; }
+        case (ast.def_use(_))           { ret none[ty.ty_params_and_ty]; }
+        case (ast.def_native_ty(_))     { ret none[ty.ty_params_and_ty]; }
+        case (ast.def_native_fn(?id))   { params_id = id; types_id = id; }
+    }
+
+    auto tps = ccx.item_ty_params.get(params_id);
+    auto polyty = ccx.item_types.get(types_id);
+    ret some[ty.ty_params_and_ty](tup(tps, polyty));
+}
+
 // Parses the programmer's textual representation of a type into our internal
 // notion of a type. `getter` is a function that returns the type
 // corresponding to a definition ID.
@@ -1190,7 +1221,38 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
         case (ast.expr_path(?pth, ?d, ?ann)) {
             auto t = demand_full(fcx, e.span, expected,
                                  ann_to_type(ann), adk);
-            e_1 = ast.expr_path(pth, d, ast.ann_type(t, none[vec[@ty.t]]));
+
+            // Fill in the type parameter substitutions if they weren't
+            // provided by the programmer.
+            auto ty_params_opt;
+            alt (ann) {
+                case (ast.ann_none) {
+                    log "demand_expr(): no type annotation for path expr; " +
+                        "did you pass it to check_expr() first?";
+                    fail;
+                }
+                case (ast.ann_type(_, ?tps_opt)) {
+                    alt (tps_opt) {
+                        case (none[vec[@ty.t]]) {
+                            auto defn = option.get[ast.def](d);
+                            alt (ty_params_for_item(fcx.ccx, defn)) {
+                                case (none[ty.ty_params_and_ty]) {
+                                    ty_params_opt = none[vec[@ty.t]];
+                                }
+                                case (some[ty.ty_params_and_ty](?tpt)) {
+                                    auto tps = ty.resolve_ty_params(tpt, t);
+                                    ty_params_opt = some[vec[@ty.t]](tps);
+                                }
+                            }
+                        }
+                        case (some[vec[@ty.t]](?tps)) {
+                            ty_params_opt = some[vec[@ty.t]](tps);
+                        }
+                    }
+                }
+            }
+
+            e_1 = ast.expr_path(pth, d, ast.ann_type(t, ty_params_opt));
         }
         case (ast.expr_ext(?p, ?args, ?body, ?expanded, ?ann)) {
             auto t = demand_full(fcx, e.span, expected,