about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-03-08 18:48:17 -0800
committerPatrick Walton <pcwalton@mimiga.net>2011-03-08 18:48:17 -0800
commit0a22a4edbb2300e338ef01c524265ecc647cbff4 (patch)
treef7a417d31b8d705c82e5193edc69a0cbb1ac4cb7 /src/comp
parente64085b0a2b512822ed7f020659fc6bdb8ed8ef5 (diff)
downloadrust-0a22a4edbb2300e338ef01c524265ecc647cbff4.tar.gz
rust-0a22a4edbb2300e338ef01c524265ecc647cbff4.zip
rustc: Factor out path type instantiation so that tag patterns can use it as well
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/typeck.rs211
1 files changed, 108 insertions, 103 deletions
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index cbb6e4acf24..e035e733fb5 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -128,6 +128,112 @@ fn substitute_ty_params(&@crate_ctxt ccx,
     ret ty.fold_ty(substituter, typ);
 }
 
+// Instantiates the given path, which must refer to an item with the given
+// definition.
+fn instantiate_path(@fn_ctxt fcx, &ast.path pth, &ast.def defn, &span sp)
+        -> ast.ann {
+    auto t;
+    auto ty_params;
+    alt (defn) {
+        case (ast.def_arg(?id)) {
+            check (fcx.locals.contains_key(id));
+            t = fcx.locals.get(id);
+            ty_params = none[vec[ast.def_id]];
+        }
+        case (ast.def_local(?id)) {
+            alt (fcx.locals.find(id)) {
+                case (some[@ty.t](?t1)) { t = t1; }
+                case (none[@ty.t]) { t = plain_ty(ty.ty_local(id)); }
+            }
+            ty_params = none[vec[ast.def_id]];
+        }
+        case (ast.def_obj_field(?id)) {
+            check (fcx.locals.contains_key(id));
+            t = fcx.locals.get(id);
+            ty_params = none[vec[ast.def_id]];
+        }
+        case (ast.def_fn(?id)) {
+            check (fcx.ccx.item_types.contains_key(id));
+            t = fcx.ccx.item_types.get(id);
+            ty_params = some(fcx.ccx.item_ty_params.get(id));
+        }
+        case (ast.def_native_fn(?id)) {
+            check (fcx.ccx.item_types.contains_key(id));
+            t = fcx.ccx.item_types.get(id);
+            ty_params = some(fcx.ccx.item_ty_params.get(id));
+        }
+        case (ast.def_const(?id)) {
+            check (fcx.ccx.item_types.contains_key(id));
+            t = fcx.ccx.item_types.get(id);
+            ty_params = none[vec[ast.def_id]];
+        }
+        case (ast.def_variant(?tag_id, ?variant_id)) {
+            check (fcx.ccx.item_types.contains_key(variant_id));
+            t = fcx.ccx.item_types.get(variant_id);
+            ty_params = some(fcx.ccx.item_ty_params.get(tag_id));
+        }
+        case (ast.def_binding(?id)) {
+            check (fcx.locals.contains_key(id));
+            t = fcx.locals.get(id);
+            ty_params = none[vec[ast.def_id]];
+        }
+        case (ast.def_obj(?id)) {
+            check (fcx.ccx.item_types.contains_key(id));
+            t = fcx.ccx.item_types.get(id);
+            ty_params = some(fcx.ccx.item_ty_params.get(id));
+        }
+
+        case (ast.def_mod(_)) {
+            // Hopefully part of a path.
+            t = plain_ty(ty.ty_nil);    // TODO: something more poisonous?
+            ty_params = none[vec[ast.def_id]];
+        }
+
+        case (_) {
+            // FIXME: handle other names.
+            fcx.ccx.sess.unimpl("definition variant for: "
+                                + _str.connect(pth.node.idents, "."));
+            fail;
+        }
+    }
+
+    auto ty_substs_opt;
+    auto ty_substs_len = _vec.len[@ast.ty](pth.node.types);
+    if (ty_substs_len > 0u) {
+        let vec[@ty.t] ty_substs = vec();
+        auto i = 0u;
+        while (i < ty_substs_len) {
+            ty_substs += vec(ast_ty_to_ty_crate(fcx.ccx, pth.node.types.(i)));
+            i += 1u;
+        }
+        ty_substs_opt = some[vec[@ty.t]](ty_substs);
+
+        alt (ty_params) {
+            case (none[vec[ast.def_id]]) {
+                fcx.ccx.sess.span_err(sp, "this kind of item may not take " +
+                                          "type parameters");
+                fail;
+            }
+            case (some[vec[ast.def_id]](?tps)) {
+                t = substitute_ty_params(fcx.ccx, t, tps, ty_substs, sp);
+            }
+        }
+    } else {
+        ty_substs_opt = none[vec[@ty.t]];
+
+        alt (ty_params) {
+            case (none[vec[ast.def_id]]) {  /* nothing */ }
+            case (some[vec[ast.def_id]](_)) {
+                // We will acquire the type parameters through
+                // unification.
+                t = generalize_ty(fcx.ccx, t);
+            }
+        }
+    }
+
+    ret ast.ann_type(t, ty_substs_opt);
+}
+
 // 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)
@@ -1561,109 +1667,8 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
         case (ast.expr_path(?pth, ?defopt, _)) {
             auto t = plain_ty(ty.ty_nil);
             check (defopt != none[ast.def]);
-
-            auto ty_params;
-            alt (option.get[ast.def](defopt)) {
-                case (ast.def_arg(?id)) {
-                    check (fcx.locals.contains_key(id));
-                    t = fcx.locals.get(id);
-                    ty_params = none[vec[ast.def_id]];
-                }
-                case (ast.def_local(?id)) {
-                    alt (fcx.locals.find(id)) {
-                        case (some[@ty.t](?t1)) { t = t1; }
-                        case (none[@ty.t]) { t = plain_ty(ty.ty_local(id)); }
-                    }
-                    ty_params = none[vec[ast.def_id]];
-                }
-                case (ast.def_obj_field(?id)) {
-                    check (fcx.locals.contains_key(id));
-                    t = fcx.locals.get(id);
-                    ty_params = none[vec[ast.def_id]];
-                }
-                case (ast.def_fn(?id)) {
-                    check (fcx.ccx.item_types.contains_key(id));
-                    t = fcx.ccx.item_types.get(id);
-                    ty_params = some(fcx.ccx.item_ty_params.get(id));
-                }
-                case (ast.def_native_fn(?id)) {
-                    check (fcx.ccx.item_types.contains_key(id));
-                    t = fcx.ccx.item_types.get(id);
-                    ty_params = some(fcx.ccx.item_ty_params.get(id));
-                }
-                case (ast.def_const(?id)) {
-                    check (fcx.ccx.item_types.contains_key(id));
-                    t = fcx.ccx.item_types.get(id);
-                    ty_params = none[vec[ast.def_id]];
-                }
-                case (ast.def_variant(?tag_id, ?variant_id)) {
-                    check (fcx.ccx.item_types.contains_key(variant_id));
-                    t = fcx.ccx.item_types.get(variant_id);
-                    ty_params = some(fcx.ccx.item_ty_params.get(tag_id));
-                }
-                case (ast.def_binding(?id)) {
-                    check (fcx.locals.contains_key(id));
-                    t = fcx.locals.get(id);
-                    ty_params = none[vec[ast.def_id]];
-                }
-                case (ast.def_obj(?id)) {
-                    check (fcx.ccx.item_types.contains_key(id));
-                    t = fcx.ccx.item_types.get(id);
-                    ty_params = some(fcx.ccx.item_ty_params.get(id));
-                }
-
-                case (ast.def_mod(_)) {
-                    // Hopefully part of a path.
-                    ty_params = none[vec[ast.def_id]];
-                }
-
-                case (_) {
-                    // FIXME: handle other names.
-                    fcx.ccx.sess.unimpl("definition variant for: "
-                                        + _str.connect(pth.node.idents, "."));
-                    fail;
-                }
-            }
-
-            // Substitute type parameters if the user provided some.
-            auto ty_substs_opt;
-            auto ty_substs_len = _vec.len[@ast.ty](pth.node.types);
-            if (ty_substs_len > 0u) {
-                let vec[@ty.t] ty_substs = vec();
-                auto i = 0u;
-                while (i < ty_substs_len) {
-                    ty_substs += vec(ast_ty_to_ty_crate(fcx.ccx,
-                                                        pth.node.types.(i)));
-                    i += 1u;
-                }
-                ty_substs_opt = some[vec[@ty.t]](ty_substs);
-
-                alt (ty_params) {
-                    case (none[vec[ast.def_id]]) {
-                        fcx.ccx.sess.span_err(expr.span, "this kind of " +
-                                              "item may not take type " +
-                                              "parameters");
-                        fail;
-                    }
-                    case (some[vec[ast.def_id]](?tps)) {
-                        t = substitute_ty_params(fcx.ccx, t, tps, ty_substs,
-                                                 expr.span);
-                    }
-                }
-            } else {
-                ty_substs_opt = none[vec[@ty.t]];
-
-                alt (ty_params) {
-                    case (none[vec[ast.def_id]]) {  /* nothing */ }
-                    case (some[vec[ast.def_id]](_)) {
-                        // We will acquire the type parameters through
-                        // unification.
-                        t = generalize_ty(fcx.ccx, t);
-                    }
-                }
-            }
-
-            auto ann = ast.ann_type(t, ty_substs_opt);
+            auto defn = option.get[ast.def](defopt);
+            auto ann = instantiate_path(fcx, pth, defn, expr.span);
             ret @fold.respan[ast.expr_](expr.span,
                                         ast.expr_path(pth, defopt, ann));
         }