about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRafael Avila de Espindola <espindola@dream.(none)>2011-02-10 18:39:55 -0500
committerGraydon Hoare <graydon@mozilla.com>2011-02-10 16:22:08 -0800
commit0d27eb13415d442a4f643c8cf4c0d839c0460744 (patch)
tree82b085a364409e53b07c8a58f342336d96c5c486
parent2b669008a8bcfcf0d1ed41cecd243e59cded4ded (diff)
downloadrust-0d27eb13415d442a4f643c8cf4c0d839c0460744.tar.gz
rust-0d27eb13415d442a4f643c8cf4c0d839c0460744.zip
Add type checking for native types.
-rw-r--r--src/comp/middle/ty.rs2
-rw-r--r--src/comp/middle/typeck.rs158
2 files changed, 126 insertions, 34 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index c3b0e687545..6dd229fbbb6 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -43,6 +43,7 @@ tag sty {
     ty_local(ast.def_id);                           // type of a local var
     ty_param(ast.def_id);                           // fn type param
     ty_type;
+    ty_native;
     // TODO: ty_fn_arg(@t), for a possibly-aliased function argument
 }
 
@@ -286,6 +287,7 @@ fn fold_ty(ty_fold fld, @t ty) -> @t {
         case (ty_str)           { ret fld.fold_simple_ty(ty); }
         case (ty_tag(_))        { ret fld.fold_simple_ty(ty); }
         case (ty_type)          { ret fld.fold_simple_ty(ty); }
+        case (ty_native)        { ret fld.fold_simple_ty(ty); }
         case (ty_box(?subty)) {
             ret rewrap(ty, ty_box(fold_ty(fld, subty)));
         }
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 4c3903a7139..d21d4ed2a08 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -31,7 +31,13 @@ import std.option.none;
 import std.option.some;
 
 type ty_table = hashmap[ast.def_id, @ty.t];
-type ty_item_table = hashmap[ast.def_id,@ast.item];
+
+tag any_item {
+    any_item_rust(@ast.item);
+    any_item_native(@ast.native_item);
+}
+
+type ty_item_table = hashmap[ast.def_id,any_item];
 
 type crate_ctxt = rec(session.session sess,
                       @ty_table item_types,
@@ -161,6 +167,9 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
                 case (ast.def_ty(?id)) {
                     sty = instantiate(getter, id, path.node.types).struct;
                 }
+                case (ast.def_native_ty(?id)) {
+                    sty = instantiate(getter, id, path.node.types).struct;
+                }
                 case (ast.def_obj(?id))     {
                     sty = instantiate(getter, id, path.node.types).struct;
                 }
@@ -196,23 +205,36 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
     ret @rec(struct=sty, mut=mut, cname=cname);
 }
 
+fn actual_type(@ty.t t, @ast.item item) -> @ty.t {
+    alt (item.node) {
+        case (ast.item_obj(_,_,_,_,_)) {
+            // An obj used as a type name refers to the output type of the
+            // item (constructor).
+            ret middle.ty.ty_fn_ret(t);
+        }
+        case (_) { }
+    }
+
+    ret t;
+}
+
 // A convenience function to use a crate_ctxt to resolve names for
 // ast_ty_to_ty.
 fn ast_ty_to_ty_crate(@crate_ctxt ccx, &@ast.ty ast_ty) -> @ty.t {
     fn getter(@crate_ctxt ccx, ast.def_id id) -> ty_and_params {
         check (ccx.item_items.contains_key(id));
         check (ccx.item_types.contains_key(id));
-        auto item = ccx.item_items.get(id);
+        auto it = ccx.item_items.get(id);
         auto ty = ccx.item_types.get(id);
-        auto params = ty_params_of_item(item);
-
-        alt (item.node) {
-            case (ast.item_obj(_,_,_,_,_)) {
-                // An obj used as a type name refers to the output type of the
-                // item (constructor).
-                ty = middle.ty.ty_fn_ret(ty);
+        auto params;
+        alt (it) {
+            case (any_item_rust(?item)) {
+                ty = actual_type(ty, item);
+                params = ty_params_of_item(item);
             }
-            case (_) { }
+            case (any_item_native(?native_item)) {
+                params = ty_params_of_native_item(native_item);
+           }
         }
 
         ret rec(params = params, ty = ty);
@@ -242,6 +264,18 @@ fn ty_params_of_item(@ast.item item) -> vec[ast.ty_param] {
     }
 }
 
+fn ty_params_of_native_item(@ast.native_item item) -> vec[ast.ty_param] {
+    alt (item.node) {
+        case (ast.native_item_fn(_, _, ?p, _)) {
+            ret p;
+        }
+        case (_) {
+            let vec[ast.ty_param] r = vec();
+            ret r;
+        }
+    }
+}
+
 // Item collection - a pair of bootstrap passes:
 //
 // 1. Collect the IDs of all type items (typedefs) and store them in a table.
@@ -253,6 +287,19 @@ fn ty_params_of_item(@ast.item item) -> vec[ast.ty_param] {
 // We then annotate the AST with the resulting types and return the annotated
 // AST, along with a table mapping item IDs to their types.
 
+fn ty_of_fn_decl(@ty_item_table id_to_ty_item,
+                 @ty_table item_to_ty,
+                 fn(&@ast.ty ast_ty) -> @ty.t convert,
+                 fn(&ast.arg a) -> arg ty_of_arg,
+                 &ast.fn_decl decl,
+                 ast.def_id def_id) -> @ty.t {
+    auto input_tys = _vec.map[ast.arg,arg](ty_of_arg, decl.inputs);
+    auto output_ty = convert(decl.output);
+    auto t_fn = plain_ty(ty.ty_fn(input_tys, output_ty));
+    item_to_ty.insert(def_id, t_fn);
+    ret t_fn;
+}
+
 fn collect_item_types(session.session sess, @ast.crate crate)
     -> tup(@ast.crate, @ty_table, @ty_item_table) {
 
@@ -260,17 +307,20 @@ fn collect_item_types(session.session sess, @ast.crate crate)
               @ty_table item_to_ty,
               ast.def_id id) -> ty_and_params {
         check (id_to_ty_item.contains_key(id));
-        auto item = id_to_ty_item.get(id);
-        auto ty = ty_of_item(id_to_ty_item, item_to_ty, item);
-        auto params = ty_params_of_item(item);
-
-        alt (item.node) {
-            case (ast.item_obj(_,_,_,_,_)) {
-                // An obj used as a type name refers to the output type of the
-                // item (constructor).
-                ty = middle.ty.ty_fn_ret(ty);
+        auto it = id_to_ty_item.get(id);
+        auto ty;
+        auto params;
+        alt (it) {
+            case (any_item_rust(?item)) {
+                ty = ty_of_item(id_to_ty_item, item_to_ty, item);
+                ty = actual_type(ty, item);
+                params = ty_params_of_item(item);
+            }
+            case (any_item_native(?native_item)) {
+                ty = ty_of_native_item(id_to_ty_item, item_to_ty,
+                                       native_item);
+                params = ty_params_of_native_item(native_item);
             }
-            case (_) { }
         }
 
         ret rec(params = params, ty = ty);
@@ -340,16 +390,9 @@ fn collect_item_types(session.session sess, @ast.crate crate)
             }
 
             case (ast.item_fn(?ident, ?fn_info, _, ?def_id, _)) {
-                // TODO: handle ty-params
-
                 auto f = bind ty_of_arg(id_to_ty_item, item_to_ty, _);
-                auto input_tys = _vec.map[ast.arg,arg](f,
-                                                       fn_info.decl.inputs);
-                auto output_ty = convert(fn_info.decl.output);
-
-                auto t_fn = plain_ty(ty.ty_fn(input_tys, output_ty));
-                item_to_ty.insert(def_id, t_fn);
-                ret t_fn;
+                ret ty_of_fn_decl(id_to_ty_item, item_to_ty, convert, f,
+                                  fn_info.decl, def_id);
             }
 
             case (ast.item_obj(?ident, ?obj_info, _, ?def_id, _)) {
@@ -385,6 +428,30 @@ fn collect_item_types(session.session sess, @ast.crate crate)
         }
     }
 
+    fn ty_of_native_item(@ty_item_table id_to_ty_item,
+                         @ty_table item_to_ty,
+                         @ast.native_item it) -> @ty.t {
+        alt (it.node) {
+            case (ast.native_item_fn(?ident, ?fn_decl, ?params, ?def_id)) {
+                auto get = bind getter(id_to_ty_item, item_to_ty, _);
+                auto convert = bind ast_ty_to_ty(get, _);
+                auto f = bind ty_of_arg(id_to_ty_item, item_to_ty, _);
+                ret ty_of_fn_decl(id_to_ty_item, item_to_ty, convert, f,
+                                  fn_decl, def_id);
+            }
+            case (ast.native_item_ty(_, ?def_id)) {
+                if (item_to_ty.contains_key(def_id)) {
+                    // Avoid repeating work.
+                    ret item_to_ty.get(def_id);
+                }
+                auto x =
+                    @rec(struct=ty.ty_native, mut=ast.imm, cname=none[str]);
+                item_to_ty.insert(def_id, x);
+                ret x;
+            }
+        }
+    }
+
     fn get_tag_variant_types(@ty_item_table id_to_ty_item,
                              @ty_table item_to_ty,
                              &ast.def_id tag_id,
@@ -422,25 +489,38 @@ fn collect_item_types(session.session sess, @ast.crate crate)
 
     // First pass: collect all type item IDs.
     auto module = crate.node.module;
-    auto id_to_ty_item = @common.new_def_hash[@ast.item]();
+    auto id_to_ty_item = @common.new_def_hash[any_item]();
     fn collect(&@ty_item_table id_to_ty_item, @ast.item i)
         -> @ty_item_table {
         alt (i.node) {
             case (ast.item_ty(_, _, _, ?def_id, _)) {
-                id_to_ty_item.insert(def_id, i);
+                id_to_ty_item.insert(def_id, any_item_rust(i));
             }
             case (ast.item_tag(_, _, _, ?def_id)) {
-                id_to_ty_item.insert(def_id, i);
+                id_to_ty_item.insert(def_id, any_item_rust(i));
             }
             case (ast.item_obj(_, _, _, ?def_id, _)) {
-                id_to_ty_item.insert(def_id, i);
+                id_to_ty_item.insert(def_id, any_item_rust(i));
             }
             case (_) { /* empty */ }
         }
         ret id_to_ty_item;
     }
+    fn collect_native(&@ty_item_table id_to_ty_item, @ast.native_item i)
+        -> @ty_item_table {
+        alt (i.node) {
+            case (ast.native_item_ty(_, ?def_id)) {
+                id_to_ty_item.insert(def_id, any_item_native(i));
+            }
+            case (ast.native_item_fn(_, _, _, ?def_id)) {
+                id_to_ty_item.insert(def_id, any_item_native(i));
+            }
+        }
+        ret id_to_ty_item;
+    }
     auto fld_1 = fold.new_identity_fold[@ty_item_table]();
-    fld_1 = @rec(update_env_for_item = bind collect(_, _)
+    fld_1 = @rec(update_env_for_item = bind collect(_, _),
+                 update_env_for_native_item = bind collect_native(_, _)
                  with *fld_1);
     fold.fold_crate[@ty_item_table](id_to_ty_item, fld_1, crate);
 
@@ -473,6 +553,11 @@ fn collect_item_types(session.session sess, @ast.crate crate)
         ret e;
     }
 
+    fn convert_native(&@env e, @ast.native_item i) -> @env {
+        ty_of_native_item(e.id_to_ty_item, e.item_to_ty, i);
+        ret e;
+    }
+
     fn fold_item_const(&@env e, &span sp, ast.ident i,
                        @ast.ty t, @ast.expr ex,
                        ast.def_id id, ast.ann a) -> @ast.item {
@@ -575,6 +660,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
     auto fld_2 = fold.new_identity_fold[@env]();
     fld_2 =
         @rec(update_env_for_item = bind convert(_,_),
+             update_env_for_native_item = bind convert_native(_,_),
              fold_item_const = bind fold_item_const(_,_,_,_,_,_,_),
              fold_item_fn    = bind fold_item_fn(_,_,_,_,_,_,_),
              fold_item_obj   = bind fold_item_obj(_,_,_,_,_,_,_),
@@ -1150,6 +1236,10 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
                     check (fcx.ccx.item_types.contains_key(id));
                     t = generalize_ty(fcx.ccx, fcx.ccx.item_types.get(id));
                 }
+                case (ast.def_native_fn(?id)) {
+                    check (fcx.ccx.item_types.contains_key(id));
+                    t = generalize_ty(fcx.ccx, fcx.ccx.item_types.get(id));
+                }
                 case (ast.def_const(?id)) {
                     check (fcx.ccx.item_types.contains_key(id));
                     t = fcx.ccx.item_types.get(id);