@@ -136,6 +136,7 @@ export ty_uint;
136
136
export ty_uniq;
137
137
export ty_var;
138
138
export ty_named;
139
+ export same_type, same_method;
139
140
export ty_var_id;
140
141
export ty_param_substs_opt_and_ty_to_monotype;
141
142
export ty_fn_args;
@@ -1683,7 +1684,7 @@ mod unify {
1683
1684
type var_bindings =
1684
1685
{ sets: ufind:: ufind, types: smallintmap:: smallintmap<t>} ;
1685
1686
1686
- type ctxt = { vb : @var_bindings , tcx : ty_ctxt } ;
1687
+ type ctxt = { vb : option :: t < @var_bindings > , tcx : ty_ctxt } ;
1687
1688
1688
1689
fn mk_var_bindings ( ) -> @var_bindings {
1689
1690
ret @{ sets : ufind:: make ( ) , types : smallintmap:: mk :: < t > ( ) } ;
@@ -1692,31 +1693,32 @@ mod unify {
1692
1693
// Unifies two sets.
1693
1694
fn union ( cx : @ctxt , set_a : uint , set_b : uint ,
1694
1695
variance : variance ) -> union_result {
1695
- ufind:: grow ( cx. vb . sets , float:: max ( set_a, set_b) + 1 u) ;
1696
- let root_a = ufind:: find ( cx. vb . sets , set_a) ;
1697
- let root_b = ufind:: find ( cx. vb . sets , set_b) ;
1696
+ let vb = option:: get ( cx. vb ) ;
1697
+ ufind:: grow ( vb. sets , float:: max ( set_a, set_b) + 1 u) ;
1698
+ let root_a = ufind:: find ( vb. sets , set_a) ;
1699
+ let root_b = ufind:: find ( vb. sets , set_b) ;
1698
1700
1699
1701
let replace_type =
1700
- bind fn ( cx : @ctxt , t: t, set_a: uint, set_b: uint) {
1701
- ufind:: union ( cx . vb . sets , set_a, set_b) ;
1702
- let root_c: uint = ufind:: find ( cx . vb . sets , set_a) ;
1703
- smallintmap:: insert :: < t > ( cx . vb . types , root_c, t) ;
1702
+ bind fn ( vb : @var_bindings , t: t, set_a: uint, set_b: uint) {
1703
+ ufind:: union ( vb. sets , set_a, set_b) ;
1704
+ let root_c: uint = ufind:: find ( vb. sets , set_a) ;
1705
+ smallintmap:: insert :: < t > ( vb. types , root_c, t) ;
1704
1706
} ( _, _, set_a, set_b) ;
1705
1707
1706
1708
1707
- alt smallintmap:: find ( cx . vb . types , root_a) {
1709
+ alt smallintmap:: find ( vb. types , root_a) {
1708
1710
none. {
1709
- alt smallintmap :: find( cx . vb . types , root_b) {
1710
- none. { ufind:: union ( cx . vb . sets , set_a, set_b) ; ret unres_ok; }
1711
- some ( t_b) { replace_type ( cx , t_b) ; ret unres_ok; }
1711
+ alt smallintmap :: find( vb. types , root_b) {
1712
+ none. { ufind:: union ( vb. sets , set_a, set_b) ; ret unres_ok; }
1713
+ some ( t_b) { replace_type ( vb , t_b) ; ret unres_ok; }
1712
1714
}
1713
1715
}
1714
1716
some ( t_a) {
1715
- alt smallintmap:: find ( cx . vb . types , root_b) {
1716
- none. { replace_type ( cx , t_a) ; ret unres_ok; }
1717
+ alt smallintmap:: find ( vb. types , root_b) {
1718
+ none. { replace_type ( vb , t_a) ; ret unres_ok; }
1717
1719
some ( t_b) {
1718
1720
alt unify_step ( cx, t_a, t_b, variance) {
1719
- ures_ok ( t_c) { replace_type ( cx , t_c) ; ret unres_ok; }
1721
+ ures_ok ( t_c) { replace_type ( vb , t_c) ; ret unres_ok; }
1720
1722
ures_err ( terr) { ret unres_err ( terr) ; }
1721
1723
}
1722
1724
}
@@ -1741,10 +1743,11 @@ mod unify {
1741
1743
fn record_var_binding (
1742
1744
cx : @ctxt , key : int , typ : t , variance : variance ) -> result {
1743
1745
1744
- ufind:: grow ( cx. vb . sets , ( key as uint ) + 1 u) ;
1745
- let root = ufind:: find ( cx. vb . sets , key as uint ) ;
1746
+ let vb = option:: get ( cx. vb ) ;
1747
+ ufind:: grow ( vb. sets , ( key as uint ) + 1 u) ;
1748
+ let root = ufind:: find ( vb. sets , key as uint ) ;
1746
1749
let result_type = typ;
1747
- alt smallintmap:: find :: < t > ( cx . vb . types , root) {
1750
+ alt smallintmap:: find ( vb. types , root) {
1748
1751
some ( old_type) {
1749
1752
alt unify_step ( cx, old_type, typ, variance) {
1750
1753
ures_ok ( unified_type) { result_type = unified_type; }
@@ -1753,7 +1756,7 @@ mod unify {
1753
1756
}
1754
1757
none. { /* fall through */ }
1755
1758
}
1756
- smallintmap:: insert :: < t > ( cx . vb . types , root, result_type) ;
1759
+ smallintmap:: insert :: < t > ( vb. types , root, result_type) ;
1757
1760
ret ures_ok( typ) ;
1758
1761
}
1759
1762
@@ -2090,6 +2093,7 @@ mod unify {
2090
2093
// If the RHS is a variable type, then just do the
2091
2094
// appropriate binding.
2092
2095
ty:: ty_var ( actual_id) {
2096
+ assert option:: is_some ( cx. vb ) ;
2093
2097
let actual_n = actual_id as uint ;
2094
2098
alt struct( cx. tcx , expected) {
2095
2099
ty:: ty_var ( expected_id) {
@@ -2114,8 +2118,8 @@ mod unify {
2114
2118
}
2115
2119
alt struct ( cx. tcx , expected) {
2116
2120
ty:: ty_var ( expected_id) {
2121
+ assert option:: is_some ( cx. vb ) ;
2117
2122
// Add a binding. (`actual` can't actually be a var here.)
2118
-
2119
2123
alt record_var_binding_for_expected (
2120
2124
cx, expected_id, actual,
2121
2125
variance) {
@@ -2431,8 +2435,8 @@ mod unify {
2431
2435
}
2432
2436
}
2433
2437
}
2434
- fn unify ( expected : t , actual : t , vb : @var_bindings , tcx : ty_ctxt ) ->
2435
- result {
2438
+ fn unify ( expected : t , actual : t , vb : option :: t < @var_bindings > ,
2439
+ tcx : ty_ctxt ) -> result {
2436
2440
let cx = @{ vb: vb, tcx: tcx} ;
2437
2441
ret unify_step( cx, expected, actual, covariant) ;
2438
2442
}
@@ -2505,6 +2509,19 @@ mod unify {
2505
2509
}
2506
2510
}
2507
2511
2512
+ fn same_type ( cx : ctxt , a : t , b : t ) -> bool {
2513
+ alt unify:: unify ( a, b, none, cx) {
2514
+ unify:: ures_ok ( _) { true }
2515
+ _ { false }
2516
+ }
2517
+ }
2518
+ fn same_method ( cx : ctxt , a : method , b : method ) -> bool {
2519
+ a. proto == b. proto && a. ident == b. ident &&
2520
+ vec:: all2 ( a. inputs , b. inputs ,
2521
+ { |a, b| a. mode == b. mode && same_type ( cx, a. ty , b. ty ) } ) &&
2522
+ same_type ( cx, a. output , b. output ) && a. cf == b. cf
2523
+ }
2524
+
2508
2525
fn type_err_to_str ( err : ty:: type_err ) -> str {
2509
2526
alt err {
2510
2527
terr_mismatch. { ret "types differ" ; }
0 commit comments