about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorRafael Ávila de Espíndola <respindola@mozilla.com>2011-02-23 11:59:07 -0500
committerRafael Ávila de Espíndola <respindola@mozilla.com>2011-02-23 11:59:07 -0500
commit6849abcf7df583f58f390eb55c7b0e84dfb1bd25 (patch)
treea959a4936231e978e4a29a8af3ba0f9c660cba8d /src/comp
parent3b7e9dc393c7b015bb06a8cc1213c25b8911362f (diff)
downloadrust-6849abcf7df583f58f390eb55c7b0e84dfb1bd25.tar.gz
rust-6849abcf7df583f58f390eb55c7b0e84dfb1bd25.zip
Handle the new ty_native_fn in type check.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/ty.rs107
-rw-r--r--src/comp/middle/typeck.rs14
2 files changed, 96 insertions, 25 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 68c2114078c..0f277329d1b 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -346,6 +346,14 @@ fn fold_ty(ty_fold fld, @t ty) -> @t {
             }
             ret rewrap(ty, ty_fn(proto, new_args, fold_ty(fld, ret_ty)));
         }
+        case (ty_native_fn(?args, ?ret_ty)) {
+            let vec[arg] new_args = vec();
+            for (arg a in args) {
+                auto new_ty = fold_ty(fld, a.ty);
+                new_args += vec(rec(mode=a.mode, ty=new_ty));
+            }
+            ret rewrap(ty, ty_native_fn(new_args, fold_ty(fld, ret_ty)));
+        }
         case (ty_obj(?methods)) {
             let vec[method] new_methods = vec();
             for (method m in methods) {
@@ -588,6 +596,7 @@ fn count_ty_params(@t ty) -> uint {
 fn ty_fn_args(@t fty) -> vec[arg] {
     alt (fty.struct) {
         case (ty.ty_fn(_, ?a, _)) { ret a; }
+        case (ty.ty_native_fn(?a, _)) { ret a; }
     }
 }
 
@@ -600,12 +609,14 @@ fn ty_fn_proto(@t fty) -> ast.proto {
 fn ty_fn_ret(@t fty) -> @t {
     alt (fty.struct) {
         case (ty.ty_fn(_, _, ?r)) { ret r; }
+        case (ty.ty_native_fn(_, ?r)) { ret r; }
     }
 }
 
 fn is_fn_ty(@t fty) -> bool {
     alt (fty.struct) {
         case (ty.ty_fn(_, _, _)) { ret true; }
+        case (ty.ty_native_fn(_, _)) { ret true; }
         case (_) { ret false; }
     }
     ret false;
@@ -826,24 +837,23 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
         ret ures_err(terr_mismatch, expected, actual);
     }
 
-    fn unify_fn(@hashmap[int,@ty.t] bindings,
-                ast.proto e_proto,
-                ast.proto a_proto,
-                @ty.t expected,
-                @ty.t actual,
-                &unify_handler handler,
-                vec[arg] expected_inputs, @t expected_output,
-                vec[arg] actual_inputs, @t actual_output)
-        -> unify_result {
-
-        if (e_proto != a_proto) {
-            ret ures_err(terr_mismatch, expected, actual);
-        }
+    tag fn_common_res {
+        fn_common_res_err(unify_result);
+        fn_common_res_ok(vec[arg], @t);
+    }
 
+    fn unify_fn_common(@hashmap[int,@ty.t] bindings,
+                       @ty.t expected,
+                       @ty.t actual,
+                       &unify_handler handler,
+                       vec[arg] expected_inputs, @t expected_output,
+                       vec[arg] actual_inputs, @t actual_output)
+        -> fn_common_res {
         auto expected_len = _vec.len[arg](expected_inputs);
         auto actual_len = _vec.len[arg](actual_inputs);
         if (expected_len != actual_len) {
-            ret ures_err(terr_arg_count, expected, actual);
+            ret fn_common_res_err(ures_err(terr_arg_count,
+                                           expected, actual));
         }
 
         // TODO: as above, we should have an iter2 iterator.
@@ -874,7 +884,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
                 }
 
                 case (_) {
-                    ret result;
+                    ret fn_common_res_err(result);
                 }
             }
 
@@ -882,24 +892,67 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
         }
 
         // Check the output.
-        auto result_out;
         auto result = unify_step(bindings,
                                  expected_output,
                                  actual_output,
                                  handler);
         alt (result) {
             case (ures_ok(?rty)) {
-                result_out = rty;
+                ret fn_common_res_ok(result_ins, rty);
             }
 
             case (_) {
-                ret result;
+                ret fn_common_res_err(result);
             }
         }
+    }
 
-        auto t = plain_ty(ty.ty_fn(e_proto, result_ins, result_out));
-        ret ures_ok(t);
+    fn unify_fn(@hashmap[int,@ty.t] bindings,
+                ast.proto e_proto,
+                ast.proto a_proto,
+                @ty.t expected,
+                @ty.t actual,
+                &unify_handler handler,
+                vec[arg] expected_inputs, @t expected_output,
+                vec[arg] actual_inputs, @t actual_output)
+        -> unify_result {
 
+        if (e_proto != a_proto) {
+            ret ures_err(terr_mismatch, expected, actual);
+        }
+        auto t = unify_fn_common(bindings, expected, actual,
+                                 handler, expected_inputs, expected_output,
+                                 actual_inputs, actual_output);
+        alt (t) {
+            case (fn_common_res_err(?r)) {
+                ret r;
+            }
+            case (fn_common_res_ok(?result_ins, ?result_out)) {
+                auto t2 = plain_ty(ty.ty_fn(e_proto, result_ins, result_out));
+                ret ures_ok(t2);
+            }
+        }
+    }
+
+    fn unify_native_fn(@hashmap[int,@ty.t] bindings,
+                       @ty.t expected,
+                       @ty.t actual,
+                       &unify_handler handler,
+                       vec[arg] expected_inputs, @t expected_output,
+                       vec[arg] actual_inputs, @t actual_output)
+        -> unify_result {
+        auto t = unify_fn_common(bindings, expected, actual,
+                                 handler, expected_inputs, expected_output,
+                                 actual_inputs, actual_output);
+        alt (t) {
+            case (fn_common_res_err(?r)) {
+                ret r;
+            }
+            case (fn_common_res_ok(?result_ins, ?result_out)) {
+                auto t2 = plain_ty(ty.ty_native_fn(result_ins, result_out));
+                ret ures_ok(t2);
+            }
+        }
     }
 
     fn unify_obj(@hashmap[int,@ty.t] bindings,
@@ -1258,6 +1311,20 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
                 }
             }
 
+            case (ty.ty_native_fn(?expected_inputs, ?expected_output)) {
+                alt (actual.struct) {
+                    case (ty.ty_native_fn(?actual_inputs, ?actual_output)) {
+                        ret unify_native_fn(bindings,
+                                            expected, actual, handler,
+                                            expected_inputs, expected_output,
+                                            actual_inputs, actual_output);
+                    }
+                    case (_) {
+                        ret ures_err(terr_mismatch, expected, actual);
+                    }
+                }
+            }
+
             case (ty.ty_obj(?expected_meths)) {
                 alt (actual.struct) {
                     case (ty.ty_obj(?actual_meths)) {
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 8f19e3ad4d1..0d583c5e418 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -1336,18 +1336,21 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
             }
         }
 
-        auto proto_0 = ast.proto_fn;    // FIXME: typestate botch
+        auto rt_0 = next_ty_var(fcx.ccx);
+        auto t_0 = plain_ty(ty.ty_uint); // FIXME: typestate botch
         alt (expr_ty(f_0).struct) {
-            case (ty.ty_fn(?proto, _, _))   { proto_0 = proto; }
+            case (ty.ty_fn(?proto, _, _))   {
+                t_0 = plain_ty(ty.ty_fn(proto, arg_tys_0, rt_0));
+            }
+            case (ty.ty_native_fn(_, _))   {
+                t_0 = plain_ty(ty.ty_native_fn(arg_tys_0, rt_0));
+            }
             case (_) {
                 log "check_call_or_bind(): fn expr doesn't have fn type";
                 fail;
             }
         }
 
-        auto rt_0 = next_ty_var(fcx.ccx);
-        auto t_0 = plain_ty(ty.ty_fn(proto_0, arg_tys_0, rt_0));
-
         // Unify and write back to the function.
         auto f_1 = demand_expr(fcx, t_0, f_0);
 
@@ -1824,6 +1827,7 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
             auto rt_1 = plain_ty(ty.ty_nil);    // FIXME: typestate botch
             alt (expr_ty(result._0).struct) {
                 case (ty.ty_fn(_,_,?rt))    { rt_1 = rt; }
+                case (ty.ty_native_fn(_,?rt))    { rt_1 = rt; }
                 case (_) {
                     log "LHS of call expr didn't have a function type?!";
                     fail;