Skip to content

Commit 6849abc

Browse files
committed
Handle the new ty_native_fn in type check.
1 parent 3b7e9dc commit 6849abc

File tree

2 files changed

+96
-25
lines changed

2 files changed

+96
-25
lines changed

src/comp/middle/ty.rs

Lines changed: 87 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,14 @@ fn fold_ty(ty_fold fld, @t ty) -> @t {
346346
}
347347
ret rewrap(ty, ty_fn(proto, new_args, fold_ty(fld, ret_ty)));
348348
}
349+
case (ty_native_fn(?args, ?ret_ty)) {
350+
let vec[arg] new_args = vec();
351+
for (arg a in args) {
352+
auto new_ty = fold_ty(fld, a.ty);
353+
new_args += vec(rec(mode=a.mode, ty=new_ty));
354+
}
355+
ret rewrap(ty, ty_native_fn(new_args, fold_ty(fld, ret_ty)));
356+
}
349357
case (ty_obj(?methods)) {
350358
let vec[method] new_methods = vec();
351359
for (method m in methods) {
@@ -588,6 +596,7 @@ fn count_ty_params(@t ty) -> uint {
588596
fn ty_fn_args(@t fty) -> vec[arg] {
589597
alt (fty.struct) {
590598
case (ty.ty_fn(_, ?a, _)) { ret a; }
599+
case (ty.ty_native_fn(?a, _)) { ret a; }
591600
}
592601
}
593602

@@ -600,12 +609,14 @@ fn ty_fn_proto(@t fty) -> ast.proto {
600609
fn ty_fn_ret(@t fty) -> @t {
601610
alt (fty.struct) {
602611
case (ty.ty_fn(_, _, ?r)) { ret r; }
612+
case (ty.ty_native_fn(_, ?r)) { ret r; }
603613
}
604614
}
605615

606616
fn is_fn_ty(@t fty) -> bool {
607617
alt (fty.struct) {
608618
case (ty.ty_fn(_, _, _)) { ret true; }
619+
case (ty.ty_native_fn(_, _)) { ret true; }
609620
case (_) { ret false; }
610621
}
611622
ret false;
@@ -826,24 +837,23 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
826837
ret ures_err(terr_mismatch, expected, actual);
827838
}
828839

829-
fn unify_fn(@hashmap[int,@ty.t] bindings,
830-
ast.proto e_proto,
831-
ast.proto a_proto,
832-
@ty.t expected,
833-
@ty.t actual,
834-
&unify_handler handler,
835-
vec[arg] expected_inputs, @t expected_output,
836-
vec[arg] actual_inputs, @t actual_output)
837-
-> unify_result {
838-
839-
if (e_proto != a_proto) {
840-
ret ures_err(terr_mismatch, expected, actual);
841-
}
840+
tag fn_common_res {
841+
fn_common_res_err(unify_result);
842+
fn_common_res_ok(vec[arg], @t);
843+
}
842844

845+
fn unify_fn_common(@hashmap[int,@ty.t] bindings,
846+
@ty.t expected,
847+
@ty.t actual,
848+
&unify_handler handler,
849+
vec[arg] expected_inputs, @t expected_output,
850+
vec[arg] actual_inputs, @t actual_output)
851+
-> fn_common_res {
843852
auto expected_len = _vec.len[arg](expected_inputs);
844853
auto actual_len = _vec.len[arg](actual_inputs);
845854
if (expected_len != actual_len) {
846-
ret ures_err(terr_arg_count, expected, actual);
855+
ret fn_common_res_err(ures_err(terr_arg_count,
856+
expected, actual));
847857
}
848858

849859
// TODO: as above, we should have an iter2 iterator.
@@ -874,32 +884,75 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
874884
}
875885

876886
case (_) {
877-
ret result;
887+
ret fn_common_res_err(result);
878888
}
879889
}
880890

881891
i += 1u;
882892
}
883893

884894
// Check the output.
885-
auto result_out;
886895
auto result = unify_step(bindings,
887896
expected_output,
888897
actual_output,
889898
handler);
890899
alt (result) {
891900
case (ures_ok(?rty)) {
892-
result_out = rty;
901+
ret fn_common_res_ok(result_ins, rty);
893902
}
894903

895904
case (_) {
896-
ret result;
905+
ret fn_common_res_err(result);
897906
}
898907
}
908+
}
899909

900-
auto t = plain_ty(ty.ty_fn(e_proto, result_ins, result_out));
901-
ret ures_ok(t);
910+
fn unify_fn(@hashmap[int,@ty.t] bindings,
911+
ast.proto e_proto,
912+
ast.proto a_proto,
913+
@ty.t expected,
914+
@ty.t actual,
915+
&unify_handler handler,
916+
vec[arg] expected_inputs, @t expected_output,
917+
vec[arg] actual_inputs, @t actual_output)
918+
-> unify_result {
902919

920+
if (e_proto != a_proto) {
921+
ret ures_err(terr_mismatch, expected, actual);
922+
}
923+
auto t = unify_fn_common(bindings, expected, actual,
924+
handler, expected_inputs, expected_output,
925+
actual_inputs, actual_output);
926+
alt (t) {
927+
case (fn_common_res_err(?r)) {
928+
ret r;
929+
}
930+
case (fn_common_res_ok(?result_ins, ?result_out)) {
931+
auto t2 = plain_ty(ty.ty_fn(e_proto, result_ins, result_out));
932+
ret ures_ok(t2);
933+
}
934+
}
935+
}
936+
937+
fn unify_native_fn(@hashmap[int,@ty.t] bindings,
938+
@ty.t expected,
939+
@ty.t actual,
940+
&unify_handler handler,
941+
vec[arg] expected_inputs, @t expected_output,
942+
vec[arg] actual_inputs, @t actual_output)
943+
-> unify_result {
944+
auto t = unify_fn_common(bindings, expected, actual,
945+
handler, expected_inputs, expected_output,
946+
actual_inputs, actual_output);
947+
alt (t) {
948+
case (fn_common_res_err(?r)) {
949+
ret r;
950+
}
951+
case (fn_common_res_ok(?result_ins, ?result_out)) {
952+
auto t2 = plain_ty(ty.ty_native_fn(result_ins, result_out));
953+
ret ures_ok(t2);
954+
}
955+
}
903956
}
904957

905958
fn unify_obj(@hashmap[int,@ty.t] bindings,
@@ -1258,6 +1311,20 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
12581311
}
12591312
}
12601313

1314+
case (ty.ty_native_fn(?expected_inputs, ?expected_output)) {
1315+
alt (actual.struct) {
1316+
case (ty.ty_native_fn(?actual_inputs, ?actual_output)) {
1317+
ret unify_native_fn(bindings,
1318+
expected, actual, handler,
1319+
expected_inputs, expected_output,
1320+
actual_inputs, actual_output);
1321+
}
1322+
case (_) {
1323+
ret ures_err(terr_mismatch, expected, actual);
1324+
}
1325+
}
1326+
}
1327+
12611328
case (ty.ty_obj(?expected_meths)) {
12621329
alt (actual.struct) {
12631330
case (ty.ty_obj(?actual_meths)) {

src/comp/middle/typeck.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,18 +1336,21 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
13361336
}
13371337
}
13381338

1339-
auto proto_0 = ast.proto_fn; // FIXME: typestate botch
1339+
auto rt_0 = next_ty_var(fcx.ccx);
1340+
auto t_0 = plain_ty(ty.ty_uint); // FIXME: typestate botch
13401341
alt (expr_ty(f_0).struct) {
1341-
case (ty.ty_fn(?proto, _, _)) { proto_0 = proto; }
1342+
case (ty.ty_fn(?proto, _, _)) {
1343+
t_0 = plain_ty(ty.ty_fn(proto, arg_tys_0, rt_0));
1344+
}
1345+
case (ty.ty_native_fn(_, _)) {
1346+
t_0 = plain_ty(ty.ty_native_fn(arg_tys_0, rt_0));
1347+
}
13421348
case (_) {
13431349
log "check_call_or_bind(): fn expr doesn't have fn type";
13441350
fail;
13451351
}
13461352
}
13471353

1348-
auto rt_0 = next_ty_var(fcx.ccx);
1349-
auto t_0 = plain_ty(ty.ty_fn(proto_0, arg_tys_0, rt_0));
1350-
13511354
// Unify and write back to the function.
13521355
auto f_1 = demand_expr(fcx, t_0, f_0);
13531356

@@ -1824,6 +1827,7 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
18241827
auto rt_1 = plain_ty(ty.ty_nil); // FIXME: typestate botch
18251828
alt (expr_ty(result._0).struct) {
18261829
case (ty.ty_fn(_,_,?rt)) { rt_1 = rt; }
1830+
case (ty.ty_native_fn(_,?rt)) { rt_1 = rt; }
18271831
case (_) {
18281832
log "LHS of call expr didn't have a function type?!";
18291833
fail;

0 commit comments

Comments
 (0)