1
+ import std:: int;
1
2
import std:: str;
2
3
import std:: uint;
3
4
import std:: vec;
@@ -1878,18 +1879,48 @@ mod unify {
1878
1879
ures_err( type_err, t, t) ;
1879
1880
}
1880
1881
1882
+ tag set_result {
1883
+ usr_ok( vec[ t] ) ;
1884
+ usr_err ( type_err, t, t) ;
1885
+ }
1886
+
1881
1887
type bindings [ T ] = rec ( ufind:: ufind sets,
1882
1888
hashmap[ T , uint] ids,
1883
- mutable vec[ mutable vec [ t] ] types) ;
1889
+ mutable vec[ mutable option :: t [ t] ] types) ;
1884
1890
1885
1891
fn mk_bindings[ T ] ( map:: hashfn[ T ] hasher, map:: eqfn[ T ] eqer)
1886
1892
-> @bindings[ T ] {
1887
- let vec[ mutable vec [ t] ] types = [ mutable] ;
1893
+ let vec[ mutable option :: t [ t] ] types = [ mutable] ;
1888
1894
ret @rec( sets=ufind:: make ( ) ,
1889
1895
ids=map:: mk_hashmap[ T , uint] ( hasher, eqer) ,
1890
1896
mutable types=types) ;
1891
1897
}
1892
1898
1899
+ fn record_binding[ T ] ( & @ctxt cx, & @bindings[ T ] bindings, & T key, t typ)
1900
+ -> result {
1901
+ auto n = get_or_create_set[ T ] ( bindings, key) ;
1902
+
1903
+ auto result_type = typ;
1904
+ if ( n < vec:: len[ option:: t[ t] ] ( bindings. types ) ) {
1905
+ alt ( bindings. types . ( n) ) {
1906
+ case ( some[ t] ( ?old_type) ) {
1907
+ alt ( unify_step ( cx, old_type, typ) ) {
1908
+ case ( ures_ok ( ?unified_type) ) {
1909
+ result_type = unified_type;
1910
+ }
1911
+ case ( ?res) { ret res; }
1912
+ }
1913
+ }
1914
+ case ( none[ t] ) { /* fall through */ }
1915
+ }
1916
+ }
1917
+
1918
+ vec:: grow_set[ option:: t[ t] ] ( bindings. types , n, none[ t] ,
1919
+ some[ t] ( result_type) ) ;
1920
+
1921
+ ret ures_ok( typ) ;
1922
+ }
1923
+
1893
1924
type ctxt = rec ( @bindings[ int] bindings ,
1894
1925
unify_handler handler,
1895
1926
ty_ctxt tcx) ;
@@ -2091,12 +2122,12 @@ mod unify {
2091
2122
ret ures_ok( t) ;
2092
2123
}
2093
2124
2094
- fn get_or_create_set ( & @ctxt cx , int id ) -> uint {
2125
+ fn get_or_create_set[ T ] ( & @bindings [ T ] bindings , & T key ) -> uint {
2095
2126
auto set_num;
2096
- alt ( cx . bindings . ids . find ( id ) ) {
2127
+ alt ( bindings. ids . find ( key ) ) {
2097
2128
case ( none[ uint] ) {
2098
- set_num = ufind:: make_set ( cx . bindings . sets ) ;
2099
- cx . bindings . ids . insert ( id , set_num) ;
2129
+ set_num = ufind:: make_set ( bindings. sets ) ;
2130
+ bindings. ids . insert ( key , set_num) ;
2100
2131
}
2101
2132
case ( some[ uint] ( ?n) ) { set_num = n; }
2102
2133
}
@@ -2117,21 +2148,21 @@ mod unify {
2117
2148
// If the RHS is a variable type, then just do the appropriate
2118
2149
// binding.
2119
2150
case ( ty:: ty_var ( ?actual_id) ) {
2120
- auto actual_n = get_or_create_set ( cx, actual_id) ;
2151
+ auto actual_n = get_or_create_set[ int] ( cx. bindings ,
2152
+ actual_id) ;
2121
2153
alt ( struct ( cx. tcx , expected) ) {
2122
2154
case ( ty:: ty_var ( ?expected_id) ) {
2123
- auto expected_n = get_or_create_set ( cx, expected_id) ;
2155
+ auto expected_n = get_or_create_set[ int] ( cx. bindings ,
2156
+ expected_id) ;
2124
2157
ufind:: union ( cx. bindings . sets , expected_n, actual_n) ;
2125
2158
}
2126
2159
2127
2160
case ( _) {
2128
2161
// Just bind the type variable to the expected type.
2129
- auto vlen = vec:: len[ vec[ t] ] ( cx. bindings . types ) ;
2130
- if ( actual_n < vlen) {
2131
- cx. bindings . types . ( actual_n) += [ expected] ;
2132
- } else {
2133
- assert ( actual_n == vlen) ;
2134
- cx. bindings . types += [ mutable [ expected] ] ;
2162
+ alt ( record_binding[ int] ( cx, cx. bindings , actual_id,
2163
+ expected) ) {
2164
+ case ( ures_ok ( _) ) { /* fall through */ }
2165
+ case ( ?res) { ret res; }
2135
2166
}
2136
2167
}
2137
2168
}
@@ -2493,14 +2524,11 @@ mod unify {
2493
2524
}
2494
2525
2495
2526
case ( ty:: ty_var ( ?expected_id) ) {
2496
- // Add a binding.
2497
- auto expected_n = get_or_create_set ( cx, expected_id) ;
2498
- auto vlen = vec:: len[ vec[ t] ] ( cx. bindings . types ) ;
2499
- if ( expected_n < vlen) {
2500
- cx. bindings . types . ( expected_n) += [ actual] ;
2501
- } else {
2502
- assert ( expected_n == vlen) ;
2503
- cx. bindings . types += [ mutable [ actual] ] ;
2527
+ // Add a binding. (`actual` can't actually be a var here.)
2528
+ alt ( record_binding[ int] ( cx, cx. bindings , expected_id,
2529
+ actual) ) {
2530
+ case ( ures_ok ( _) ) { /* fall through */ }
2531
+ case ( ?res) { ret res; }
2504
2532
}
2505
2533
ret ures_ok( expected) ;
2506
2534
}
@@ -2562,32 +2590,63 @@ mod unify {
2562
2590
ret fold_ty( tcx, f, typ) ;
2563
2591
}
2564
2592
2565
- fn unify_sets[ T ] ( & @bindings[ T ] bindings) -> vec[ t] {
2566
- let vec[ mutable vec[ t] ] set_types = [ mutable] ;
2567
-
2568
- for ( ufind:: node node in bindings. sets. nodes) {
2569
- let vec[ t] v = [ ] ;
2570
- set_types += [ mutable v] ;
2593
+ fn unify_sets[ T ] ( & ty_ctxt tcx, & @bindings[ T ] bindings) -> set_result {
2594
+ obj handler( ) {
2595
+ fn resolve_local( ast:: def_id id) -> option:: t[ t] {
2596
+ log_err "resolve_local in unify_sets" ;
2597
+ fail;
2598
+ }
2599
+ fn record_local ( ast:: def_id id, t ty ) {
2600
+ log_err "record_local in unify_sets" ;
2601
+ fail;
2602
+ }
2603
+ fn record_param ( uint index , t binding ) -> unify:: result {
2604
+ log_err "record_param in unify_sets" ;
2605
+ fail;
2606
+ }
2571
2607
}
2572
2608
2609
+ auto node_count = vec:: len[ option:: t[ t] ] ( bindings. types ) ;
2610
+
2611
+ let vec[ option:: t[ t] ] results =
2612
+ vec:: init_elt[ option:: t[ t] ] ( none[ t] , node_count) ;
2613
+
2573
2614
auto i = 0 u;
2574
- while ( i < vec :: len [ vec [ t ] ] ( set_types ) ) {
2615
+ while ( i < node_count ) {
2575
2616
auto root = ufind:: find ( bindings. sets , i) ;
2576
- set_types. ( root) += bindings. types . ( i) ;
2617
+ alt ( bindings. types . ( i) ) {
2618
+ case ( none[ t] ) { /* nothing to do */ }
2619
+ case ( some[ t] ( ?actual) ) {
2620
+ alt ( results. ( root) ) {
2621
+ case ( none[ t] ) { results. ( root) = some[ t] ( actual) ; }
2622
+ case ( some[ t] ( ?expected) ) {
2623
+ // FIXME: Is this right?
2624
+ auto bindings = mk_bindings[ int] ( int:: hash,
2625
+ int:: eq_alias) ;
2626
+ alt ( unify ( expected, actual, handler ( ) , bindings,
2627
+ tcx) ) {
2628
+ case ( ures_ok ( ?result_ty) ) {
2629
+ results. ( i) = some[ t] ( result_ty) ;
2630
+ }
2631
+ case ( ures_err ( ?e, ?t_a, ?t_b) ) {
2632
+ ret usr_err ( e, t_a, t_b) ;
2633
+ }
2634
+ }
2635
+ }
2636
+ }
2637
+ }
2638
+ }
2577
2639
i += 1 u;
2578
2640
}
2579
2641
2580
- let vec[ t] result = [ ] ;
2581
- for ( vec[ t] types in set_types) {
2582
- if ( vec:: len[ t] ( types) > 1 u) {
2583
- log_err "unification of > 1 types in a type set is " +
2584
- "unimplemented" ;
2585
- fail;
2586
- }
2587
- result += [ types. ( 0 ) ] ;
2642
+ // FIXME: This is equivalent to map(option::get, results) but it
2643
+ // causes an assertion in typeck at the moment.
2644
+ let vec[ t] real_results = [ ] ;
2645
+ for ( option:: t[ t] typ in results) {
2646
+ real_results += [ option:: get[ t] ( typ) ] ;
2588
2647
}
2589
2648
2590
- ret result ;
2649
+ ret usr_ok ( real_results ) ;
2591
2650
}
2592
2651
2593
2652
fn unify ( & t expected ,
@@ -2599,9 +2658,13 @@ mod unify {
2599
2658
ret unify_step( cx, expected, actual) ;
2600
2659
}
2601
2660
2602
- fn fixup ( & ty_ctxt tcx, & @bindings[ int] bindings , t typ ) -> t {
2603
- auto set_types = unify_sets[ int] ( bindings) ;
2604
- ret substitute ( tcx, bindings, set_types, typ) ;
2661
+ fn fixup ( & ty_ctxt tcx, & @bindings[ int] bindings , t typ ) -> result {
2662
+ alt ( unify_sets[ int] ( tcx, bindings) ) {
2663
+ case ( usr_ok ( ?set_types) ) {
2664
+ ret ures_ok ( substitute ( tcx, bindings, set_types, typ) ) ;
2665
+ }
2666
+ case ( usr_err ( ?terr, ?t0, ?t1) ) { ret ures_err ( terr, t0, t1) ; }
2667
+ }
2605
2668
}
2606
2669
}
2607
2670
0 commit comments