@@ -655,6 +655,75 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
655
655
ret ures_err( terr_mismatch, expected, actual) ;
656
656
}
657
657
658
+ fn unify_fn( & hashmap[ int, @ty. t] bindings,
659
+ @ty. t expected,
660
+ @ty. t actual,
661
+ & unify_handler handler,
662
+ vec[ arg] expected_inputs, @t expected_output,
663
+ vec[ arg] actual_inputs, @t actual_output)
664
+ -> unify_result {
665
+ auto expected_len = _vec. len[ arg] ( expected_inputs) ;
666
+ auto actual_len = _vec. len[ arg] ( actual_inputs) ;
667
+ if ( expected_len != actual_len) {
668
+ ret ures_err( terr_arg_count, expected, actual) ;
669
+ }
670
+
671
+ // TODO: as above, we should have an iter2 iterator.
672
+ let vec[ arg] result_ins = vec( ) ;
673
+ auto i = 0 u;
674
+ while ( i < expected_len) {
675
+ auto expected_input = expected_inputs. ( i) ;
676
+ auto actual_input = actual_inputs. ( i) ;
677
+
678
+ // This should be safe, I think?
679
+ auto result_mode;
680
+ if ( mode_is_alias( expected_input. mode) ||
681
+ mode_is_alias( actual_input. mode) ) {
682
+ result_mode = ast. alias;
683
+ } else {
684
+ result_mode = ast. val;
685
+ }
686
+
687
+ auto result = unify_step( bindings,
688
+ actual_input. ty,
689
+ expected_input. ty,
690
+ handler) ;
691
+
692
+ alt ( result) {
693
+ case ( ures_ok( ?rty) ) {
694
+ result_ins += vec( rec( mode=result_mode,
695
+ ty=rty) ) ;
696
+ }
697
+
698
+ case ( _) {
699
+ ret result;
700
+ }
701
+ }
702
+
703
+ i += 1 u;
704
+ }
705
+
706
+ // Check the output.
707
+ auto result_out;
708
+ auto result = unify_step( bindings,
709
+ expected_output,
710
+ actual_output,
711
+ handler) ;
712
+ alt ( result) {
713
+ case ( ures_ok( ?rty) ) {
714
+ result_out = rty;
715
+ }
716
+
717
+ case ( _) {
718
+ ret result;
719
+ }
720
+ }
721
+
722
+ auto t = plain_ty( ty. ty_fn( result_ins, result_out) ) ;
723
+ ret ures_ok( t) ;
724
+
725
+ }
726
+
658
727
fn unify_step( & hashmap[ int, @ty. t] bindings, @ty. t expected, @ty. t actual,
659
728
& unify_handler handler) -> unify_result {
660
729
// TODO: rewrite this using tuple pattern matching when available, to
@@ -881,65 +950,9 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
881
950
case ( ty. ty_fn( ?expected_inputs, ?expected_output) ) {
882
951
alt ( actual. struct ) {
883
952
case ( ty. ty_fn( ?actual_inputs, ?actual_output) ) {
884
- auto expected_len = _vec. len[ arg] ( expected_inputs) ;
885
- auto actual_len = _vec. len[ arg] ( actual_inputs) ;
886
- if ( expected_len != actual_len) {
887
- ret ures_err( terr_arg_count, expected, actual) ;
888
- }
889
-
890
- // TODO: as above, we should have an iter2 iterator.
891
- let vec[ arg] result_ins = vec( ) ;
892
- auto i = 0 u;
893
- while ( i < expected_len) {
894
- auto expected_input = expected_inputs. ( i) ;
895
- auto actual_input = actual_inputs. ( i) ;
896
-
897
- // This should be safe, I think?
898
- auto result_mode;
899
- if ( mode_is_alias( expected_input. mode) ||
900
- mode_is_alias( actual_input. mode) ) {
901
- result_mode = ast. alias;
902
- } else {
903
- result_mode = ast. val;
904
- }
905
-
906
- auto result = unify_step( bindings,
907
- actual_input. ty,
908
- expected_input. ty,
909
- handler) ;
910
-
911
- alt ( result) {
912
- case ( ures_ok( ?rty) ) {
913
- result_ins += vec( rec( mode=result_mode,
914
- ty=rty) ) ;
915
- }
916
-
917
- case ( _) {
918
- ret result;
919
- }
920
- }
921
-
922
- i += 1 u;
923
- }
924
-
925
- // Check the output.
926
- auto result_out;
927
- auto result = unify_step( bindings,
928
- expected_output,
929
- actual_output,
930
- handler) ;
931
- alt ( result) {
932
- case ( ures_ok( ?rty) ) {
933
- result_out = rty;
934
- }
935
-
936
- case ( _) {
937
- ret result;
938
- }
939
- }
940
-
941
- auto t = plain_ty( ty. ty_fn( result_ins, result_out) ) ;
942
- ret ures_ok( t) ;
953
+ ret unify_fn( bindings, expected, actual, handler,
954
+ expected_inputs, expected_output,
955
+ actual_inputs, actual_output) ;
943
956
}
944
957
945
958
case ( _) {
0 commit comments