@@ -1807,7 +1807,8 @@ mod unify {
1807
1807
}
1808
1808
1809
1809
// Unifies two sets.
1810
- fn union ( cx : @ctxt , set_a : uint , set_b : uint ) -> union_result {
1810
+ fn union ( cx : @ctxt , set_a : uint , set_b : uint ,
1811
+ variance : variance ) -> union_result {
1811
1812
ufind:: grow ( cx. vb . sets , uint:: max ( set_a, set_b) + 1 u) ;
1812
1813
let root_a = ufind:: find ( cx. vb . sets , set_a) ;
1813
1814
let root_b = ufind:: find ( cx. vb . sets , set_b) ;
@@ -1831,7 +1832,7 @@ mod unify {
1831
1832
alt smallintmap:: find ( cx. vb . types , root_b) {
1832
1833
none. { replace_type ( cx, t_a) ; ret unres_ok; }
1833
1834
some ( t_b) {
1834
- alt unify_step ( cx, t_a, t_b) {
1835
+ alt unify_step ( cx, t_a, t_b, variance ) {
1835
1836
ures_ok ( t_c) { replace_type ( cx, t_c) ; ret unres_ok; }
1836
1837
ures_err ( terr) { ret unres_err ( terr) ; }
1837
1838
}
@@ -1842,20 +1843,20 @@ mod unify {
1842
1843
}
1843
1844
1844
1845
fn record_var_binding_for_expected (
1845
- cx : @ctxt , key : int , typ : t ) -> result {
1846
+ cx : @ctxt , key : int , typ : t , variance : variance ) -> result {
1846
1847
record_var_binding (
1847
1848
cx, key, typ,
1848
1849
fn ( cx: @ctxt, old_type: t, new_type: t) -> result {
1849
- unify_step( cx, old_type, new_type)
1850
+ unify_step( cx, old_type, new_type, variance )
1850
1851
} )
1851
1852
}
1852
1853
1853
1854
fn record_var_binding_for_actual (
1854
- cx : @ctxt , key : int , typ : t ) -> result {
1855
+ cx : @ctxt , key : int , typ : t , variance : variance ) -> result {
1855
1856
record_var_binding (
1856
1857
cx, key, typ,
1857
1858
fn ( cx: @ctxt, old_type: t, new_type: t) -> result {
1858
- unify_step( cx, new_type, old_type)
1859
+ unify_step( cx, new_type, old_type, variance )
1859
1860
} )
1860
1861
}
1861
1862
@@ -1960,7 +1961,8 @@ mod unify {
1960
1961
}
1961
1962
fn unify_fn_common ( cx : @ctxt , _expected : t , _actual : t ,
1962
1963
expected_inputs : [ arg ] , expected_output : t ,
1963
- actual_inputs : [ arg ] , actual_output : t ) ->
1964
+ actual_inputs : [ arg ] , actual_output : t ,
1965
+ variance : variance ) ->
1964
1966
fn_common_res {
1965
1967
let expected_len = vec:: len :: < arg > ( expected_inputs) ;
1966
1968
let actual_len = vec:: len :: < arg > ( actual_inputs) ;
@@ -1985,7 +1987,8 @@ mod unify {
1985
1987
( ures_err ( terr_mode_mismatch ( expected_input. mode ,
1986
1988
actual_input. mode ) ) ) ;
1987
1989
} else { expected_input. mode } ;
1988
- let result = unify_step ( cx, expected_input. ty , actual_input. ty ) ;
1990
+ let result = unify_step (
1991
+ cx, expected_input. ty , actual_input. ty , variance) ;
1989
1992
alt result {
1990
1993
ures_ok( rty) { result_ins += [ { mode: result_mode, ty: rty} ] ; }
1991
1994
_ { ret fn_common_res_err( result) ; }
@@ -1994,7 +1997,7 @@ mod unify {
1994
1997
}
1995
1998
// Check the output.
1996
1999
1997
- let result = unify_step ( cx, expected_output, actual_output) ;
2000
+ let result = unify_step ( cx, expected_output, actual_output, variance ) ;
1998
2001
alt result {
1999
2002
ures_ok( rty) { ret fn_common_res_ok ( result_ins, rty) ; }
2000
2003
_ { ret fn_common_res_err( result) ; }
@@ -2095,7 +2098,19 @@ mod unify {
2095
2098
_ { ret fix_ok( typ) ; }
2096
2099
}
2097
2100
}
2098
- fn unify_step ( cx : @ctxt , expected : t , actual : t ) -> result {
2101
+
2102
+ // Specifies the allowable subtyping between expected and actual types
2103
+ tag variance {
2104
+ // Actual may be a subtype of expected
2105
+ covariant;
2106
+ // Actual may be a supertype of expected
2107
+ contravariant;
2108
+ // Actual must be the same type as expected
2109
+ invariant;
2110
+ }
2111
+
2112
+ fn unify_step ( cx : @ctxt , expected : t , actual : t ,
2113
+ variance : variance ) -> result {
2099
2114
// TODO: rewrite this using tuple pattern matching when available, to
2100
2115
// avoid all this rightward drift and spikiness.
2101
2116
@@ -2187,7 +2202,8 @@ mod unify {
2187
2202
while i < expected_len {
2188
2203
let expected_tp = expected_tps[ i] ;
2189
2204
let actual_tp = actual_tps[ i] ;
2190
- let result = unify_step ( cx, expected_tp, actual_tp) ;
2205
+ let result = unify_step (
2206
+ cx, expected_tp, actual_tp, variance) ;
2191
2207
alt result {
2192
2208
ures_ok( rty) { result_tps += [ rty] ; }
2193
2209
_ { ret result; }
@@ -2208,7 +2224,8 @@ mod unify {
2208
2224
none. { ret ures_err ( terr_box_mutability) ; }
2209
2225
some ( m) { mut = m; }
2210
2226
}
2211
- let result = unify_step ( cx, expected_mt. ty , actual_mt. ty ) ;
2227
+ let result = unify_step (
2228
+ cx, expected_mt. ty , actual_mt. ty , variance) ;
2212
2229
alt result {
2213
2230
ures_ok( result_sub) {
2214
2231
let mt = { ty: result_sub, mut : mut } ;
@@ -2228,7 +2245,8 @@ mod unify {
2228
2245
none. { ret ures_err ( terr_box_mutability) ; }
2229
2246
some ( m) { mut = m; }
2230
2247
}
2231
- let result = unify_step ( cx, expected_mt. ty , actual_mt. ty ) ;
2248
+ let result = unify_step (
2249
+ cx, expected_mt. ty , actual_mt. ty , variance) ;
2232
2250
alt result {
2233
2251
ures_ok( result_mt) {
2234
2252
let mt = { ty: result_mt, mut : mut } ;
@@ -2248,7 +2266,8 @@ mod unify {
2248
2266
none. { ret ures_err ( terr_vec_mutability) ; }
2249
2267
some ( m) { mut = m; }
2250
2268
}
2251
- let result = unify_step ( cx, expected_mt. ty , actual_mt. ty ) ;
2269
+ let result = unify_step (
2270
+ cx, expected_mt. ty , actual_mt. ty , variance) ;
2252
2271
alt result {
2253
2272
ures_ok( result_sub) {
2254
2273
let mt = { ty: result_sub, mut : mut } ;
@@ -2268,7 +2287,8 @@ mod unify {
2268
2287
none. { ret ures_err ( terr_vec_mutability) ; }
2269
2288
some ( m) { mut = m; }
2270
2289
}
2271
- let result = unify_step ( cx, expected_mt. ty , actual_mt. ty ) ;
2290
+ let result = unify_step (
2291
+ cx, expected_mt. ty , actual_mt. ty , variance) ;
2272
2292
alt result {
2273
2293
ures_ok( result_sub) {
2274
2294
let mt = { ty: result_sub, mut : mut } ;
@@ -2286,13 +2306,15 @@ mod unify {
2286
2306
if ex_id. crate != act_id. crate || ex_id. node != act_id. node {
2287
2307
ret ures_err ( terr_mismatch) ;
2288
2308
}
2289
- let result = unify_step ( cx, ex_inner, act_inner) ;
2309
+ let result = unify_step (
2310
+ cx, ex_inner, act_inner, variance) ;
2290
2311
alt result {
2291
2312
ures_ok( res_inner) {
2292
2313
let i = 0 u;
2293
2314
let res_tps = [ ] ;
2294
2315
for ex_tp: t in ex_tps {
2295
- let result = unify_step ( cx, ex_tp, act_tps[ i] ) ;
2316
+ let result = unify_step (
2317
+ cx, ex_tp, act_tps[ i] , variance) ;
2296
2318
alt result {
2297
2319
ures_ok( rty) { res_tps += [ rty] ; }
2298
2320
_ { ret result; }
@@ -2338,7 +2360,7 @@ mod unify {
2338
2360
}
2339
2361
let result =
2340
2362
unify_step ( cx, expected_field. mt . ty ,
2341
- actual_field. mt . ty ) ;
2363
+ actual_field. mt . ty , variance ) ;
2342
2364
alt result {
2343
2365
ures_ok( rty) {
2344
2366
let mt = { ty: rty, mut : mut } ;
@@ -2370,7 +2392,8 @@ mod unify {
2370
2392
while i < expected_len {
2371
2393
let expected_elem = expected_elems[ i] ;
2372
2394
let actual_elem = actual_elems[ i] ;
2373
- let result = unify_step ( cx, expected_elem, actual_elem) ;
2395
+ let result = unify_step (
2396
+ cx, expected_elem, actual_elem, variance) ;
2374
2397
alt result {
2375
2398
ures_ok( rty) { result_elems += [ rty] ; }
2376
2399
_ { ret result; }
@@ -2419,7 +2442,8 @@ mod unify {
2419
2442
// unify the base types...
2420
2443
alt struct( cx. tcx , actual) {
2421
2444
ty:: ty_constr ( actual_t, actual_constrs) {
2422
- let rslt = unify_step ( cx, expected_t, actual_t) ;
2445
+ let rslt = unify_step (
2446
+ cx, expected_t, actual_t, variance) ;
2423
2447
alt rslt {
2424
2448
ures_ok( rty) {
2425
2449
// FIXME: probably too restrictive --
@@ -2435,7 +2459,8 @@ mod unify {
2435
2459
// If the actual type is *not* a constrained type,
2436
2460
// then we go ahead and just ignore the constraints on
2437
2461
// the expected type. typestate handles the rest.
2438
- ret unify_step( cx, expected_t, actual) ;
2462
+ ret unify_step(
2463
+ cx, expected_t, actual, variance) ;
2439
2464
}
2440
2465
}
2441
2466
}
@@ -2444,7 +2469,7 @@ mod unify {
2444
2469
fn unify ( expected : t , actual : t , vb : @var_bindings , tcx : ty_ctxt ) ->
2445
2470
result {
2446
2471
let cx = @{ vb: vb, tcx: tcx} ;
2447
- ret unify_step( cx, expected, actual) ;
2472
+ ret unify_step( cx, expected, actual, covariant ) ;
2448
2473
}
2449
2474
fn dump_var_bindings ( tcx : ty_ctxt , vb : @var_bindings ) {
2450
2475
let i = 0 u;
0 commit comments