@@ -1846,7 +1846,7 @@ mod unify {
1846
1846
cx : @ctxt , key : int , typ : t , variance : variance ) -> result {
1847
1847
record_var_binding (
1848
1848
cx, key, typ,
1849
- fn ( cx: @ctxt, old_type: t, new_type: t) -> result {
1849
+ lambda ( cx: @ctxt, old_type: t, new_type: t) -> result {
1850
1850
unify_step( cx, old_type, new_type, variance)
1851
1851
} )
1852
1852
}
@@ -1855,7 +1855,7 @@ mod unify {
1855
1855
cx : @ctxt , key : int , typ : t , variance : variance ) -> result {
1856
1856
record_var_binding (
1857
1857
cx, key, typ,
1858
- fn ( cx: @ctxt, old_type: t, new_type: t) -> result {
1858
+ lambda ( cx: @ctxt, old_type: t, new_type: t) -> result {
1859
1859
unify_step( cx, new_type, old_type, variance)
1860
1860
} )
1861
1861
}
@@ -2007,7 +2007,8 @@ mod unify {
2007
2007
expected : t , actual : t , expected_inputs : [ arg ] ,
2008
2008
expected_output : t , actual_inputs : [ arg ] , actual_output : t ,
2009
2009
expected_cf : ret_style , actual_cf : ret_style ,
2010
- _expected_constrs : [ @constr ] , actual_constrs : [ @constr ] ) ->
2010
+ _expected_constrs : [ @constr ] , actual_constrs : [ @constr ] ,
2011
+ variance : variance ) ->
2011
2012
result {
2012
2013
if e_proto != a_proto { ret ures_err ( terr_mismatch) ; }
2013
2014
if actual_cf != ast:: noreturn && actual_cf != expected_cf {
@@ -2020,7 +2021,8 @@ mod unify {
2020
2021
}
2021
2022
let t =
2022
2023
unify_fn_common ( cx, expected, actual, expected_inputs,
2023
- expected_output, actual_inputs, actual_output) ;
2024
+ expected_output, actual_inputs, actual_output,
2025
+ variance) ;
2024
2026
alt t {
2025
2027
fn_common_res_err( r) { ret r; }
2026
2028
fn_common_res_ok ( result_ins, result_out) {
@@ -2034,11 +2036,13 @@ mod unify {
2034
2036
fn unify_native_fn ( cx : @ctxt , e_abi : ast:: native_abi ,
2035
2037
a_abi : ast:: native_abi , expected : t , actual : t ,
2036
2038
expected_inputs : [ arg ] , expected_output : t ,
2037
- actual_inputs : [ arg ] , actual_output : t ) -> result {
2039
+ actual_inputs : [ arg ] , actual_output : t ,
2040
+ variance : variance ) -> result {
2038
2041
if e_abi != a_abi { ret ures_err ( terr_mismatch) ; }
2039
2042
let t =
2040
2043
unify_fn_common ( cx, expected, actual, expected_inputs,
2041
- expected_output, actual_inputs, actual_output) ;
2044
+ expected_output, actual_inputs, actual_output,
2045
+ variance) ;
2042
2046
alt t {
2043
2047
fn_common_res_err( r) { ret r; }
2044
2048
fn_common_res_ok ( result_ins, result_out) {
@@ -2048,7 +2052,7 @@ mod unify {
2048
2052
}
2049
2053
}
2050
2054
fn unify_obj ( cx : @ctxt , expected : t , actual : t , expected_meths : [ method ] ,
2051
- actual_meths : [ method ] ) -> result {
2055
+ actual_meths : [ method ] , variance : variance ) -> result {
2052
2056
let result_meths: [ method ] = [ ] ;
2053
2057
let i: uint = 0 u;
2054
2058
let expected_len: uint = vec:: len :: < method > ( expected_meths) ;
@@ -2064,7 +2068,7 @@ mod unify {
2064
2068
unify_fn ( cx, e_meth. proto , a_meth. proto , expected, actual,
2065
2069
e_meth. inputs , e_meth. output , a_meth. inputs ,
2066
2070
a_meth. output , e_meth. cf , a_meth. cf , e_meth. constrs ,
2067
- a_meth. constrs ) ;
2071
+ a_meth. constrs , variance ) ;
2068
2072
alt r {
2069
2073
ures_ok( tfn) {
2070
2074
alt struct( cx. tcx , tfn) {
@@ -2109,6 +2113,38 @@ mod unify {
2109
2113
invariant;
2110
2114
}
2111
2115
2116
+ // The calculation for recursive variance
2117
+ // "Taming the Wildcards: Combining Definition- and Use-Site Variance"
2118
+ // by John Altidor, et. al.
2119
+ //
2120
+ // I'm just copying the table from figure 1 - haven't actually
2121
+ // read the paper (yet).
2122
+ fn variance_transform ( a : variance , b : variance ) -> variance {
2123
+ alt a {
2124
+ covariant. {
2125
+ alt b {
2126
+ covariant. { covariant }
2127
+ contravariant. { contravariant }
2128
+ invariant. { invariant }
2129
+ }
2130
+ }
2131
+ contravariant. {
2132
+ alt b {
2133
+ covariant. { contravariant }
2134
+ contravariant. { covariant }
2135
+ invariant. { invariant }
2136
+ }
2137
+ }
2138
+ invariant. {
2139
+ alt b {
2140
+ covariant. { invariant }
2141
+ contravariant. { invariant }
2142
+ invariant. { invariant }
2143
+ }
2144
+ }
2145
+ }
2146
+ }
2147
+
2112
2148
fn unify_step ( cx : @ctxt , expected : t , actual : t ,
2113
2149
variance : variance ) -> result {
2114
2150
// TODO: rewrite this using tuple pattern matching when available, to
@@ -2128,14 +2164,15 @@ mod unify {
2128
2164
alt struct( cx. tcx , expected) {
2129
2165
ty:: ty_var ( expected_id) {
2130
2166
let expected_n = expected_id as uint ;
2131
- alt union( cx, expected_n, actual_n) {
2167
+ alt union( cx, expected_n, actual_n, variance ) {
2132
2168
unres_ok. { /* fall through */ }
2133
2169
unres_err ( t_e) { ret ures_err ( t_e) ; }
2134
2170
}
2135
2171
}
2136
2172
_ {
2137
2173
// Just bind the type variable to the expected type.
2138
- alt record_var_binding_for_actual( cx, actual_id, expected) {
2174
+ alt record_var_binding_for_actual(
2175
+ cx, actual_id, expected, variance) {
2139
2176
ures_ok( _) { /* fall through */ }
2140
2177
rs { ret rs; }
2141
2178
}
@@ -2149,7 +2186,9 @@ mod unify {
2149
2186
ty:: ty_var ( expected_id) {
2150
2187
// Add a binding. (`actual` can't actually be a var here.)
2151
2188
2152
- alt record_var_binding_for_expected ( cx, expected_id, actual) {
2189
+ alt record_var_binding_for_expected (
2190
+ cx, expected_id, actual,
2191
+ variance) {
2153
2192
ures_ok ( _) { /* fall through */ }
2154
2193
rs { ret rs; }
2155
2194
}
@@ -2413,7 +2452,7 @@ mod unify {
2413
2452
ret unify_fn ( cx, ep, ap, expected, actual, expected_inputs,
2414
2453
expected_output, actual_inputs, actual_output,
2415
2454
expected_cf, actual_cf, expected_constrs,
2416
- actual_constrs) ;
2455
+ actual_constrs, variance ) ;
2417
2456
}
2418
2457
_ { ret ures_err( terr_mismatch) ; }
2419
2458
}
@@ -2423,7 +2462,7 @@ mod unify {
2423
2462
ty:: ty_native_fn ( a_abi, actual_inputs, actual_output) {
2424
2463
ret unify_native_fn ( cx, e_abi, a_abi, expected, actual,
2425
2464
expected_inputs, expected_output,
2426
- actual_inputs, actual_output) ;
2465
+ actual_inputs, actual_output, variance ) ;
2427
2466
}
2428
2467
_ { ret ures_err( terr_mismatch) ; }
2429
2468
}
@@ -2432,7 +2471,7 @@ mod unify {
2432
2471
alt struct( cx. tcx , actual) {
2433
2472
ty:: ty_obj ( actual_meths) {
2434
2473
ret unify_obj ( cx, expected, actual, expected_meths,
2435
- actual_meths) ;
2474
+ actual_meths, variance ) ;
2436
2475
}
2437
2476
_ { ret ures_err( terr_mismatch) ; }
2438
2477
}
0 commit comments