Skip to content

Commit 67e560b

Browse files
committed
---
yaml --- r: 5835 b: refs/heads/master c: d661338 h: refs/heads/master i: 5833: f7444a6 5831: e5b2cb4 v: v3
1 parent 5136fa3 commit 67e560b

File tree

2 files changed

+48
-23
lines changed

2 files changed

+48
-23
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: b61578e1cd8c6f7c872fb843c85234486b4c060c
2+
refs/heads/master: d6613384fdd3b942981e517320708f813e1ad8b6

trunk/src/comp/middle/ty.rs

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,7 +1807,8 @@ mod unify {
18071807
}
18081808

18091809
// 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 {
18111812
ufind::grow(cx.vb.sets, uint::max(set_a, set_b) + 1u);
18121813
let root_a = ufind::find(cx.vb.sets, set_a);
18131814
let root_b = ufind::find(cx.vb.sets, set_b);
@@ -1831,7 +1832,7 @@ mod unify {
18311832
alt smallintmap::find(cx.vb.types, root_b) {
18321833
none. { replace_type(cx, t_a); ret unres_ok; }
18331834
some(t_b) {
1834-
alt unify_step(cx, t_a, t_b) {
1835+
alt unify_step(cx, t_a, t_b, variance) {
18351836
ures_ok(t_c) { replace_type(cx, t_c); ret unres_ok; }
18361837
ures_err(terr) { ret unres_err(terr); }
18371838
}
@@ -1842,20 +1843,20 @@ mod unify {
18421843
}
18431844

18441845
fn record_var_binding_for_expected(
1845-
cx: @ctxt, key: int, typ: t) -> result {
1846+
cx: @ctxt, key: int, typ: t, variance: variance) -> result {
18461847
record_var_binding(
18471848
cx, key, typ,
18481849
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)
18501851
})
18511852
}
18521853

18531854
fn record_var_binding_for_actual(
1854-
cx: @ctxt, key: int, typ: t) -> result {
1855+
cx: @ctxt, key: int, typ: t, variance: variance) -> result {
18551856
record_var_binding(
18561857
cx, key, typ,
18571858
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)
18591860
})
18601861
}
18611862

@@ -1960,7 +1961,8 @@ mod unify {
19601961
}
19611962
fn unify_fn_common(cx: @ctxt, _expected: t, _actual: t,
19621963
expected_inputs: [arg], expected_output: t,
1963-
actual_inputs: [arg], actual_output: t) ->
1964+
actual_inputs: [arg], actual_output: t,
1965+
variance: variance) ->
19641966
fn_common_res {
19651967
let expected_len = vec::len::<arg>(expected_inputs);
19661968
let actual_len = vec::len::<arg>(actual_inputs);
@@ -1985,7 +1987,8 @@ mod unify {
19851987
(ures_err(terr_mode_mismatch(expected_input.mode,
19861988
actual_input.mode)));
19871989
} 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);
19891992
alt result {
19901993
ures_ok(rty) { result_ins += [{mode: result_mode, ty: rty}]; }
19911994
_ { ret fn_common_res_err(result); }
@@ -1994,7 +1997,7 @@ mod unify {
19941997
}
19951998
// Check the output.
19961999

1997-
let result = unify_step(cx, expected_output, actual_output);
2000+
let result = unify_step(cx, expected_output, actual_output, variance);
19982001
alt result {
19992002
ures_ok(rty) { ret fn_common_res_ok(result_ins, rty); }
20002003
_ { ret fn_common_res_err(result); }
@@ -2095,7 +2098,19 @@ mod unify {
20952098
_ { ret fix_ok(typ); }
20962099
}
20972100
}
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 {
20992114
// TODO: rewrite this using tuple pattern matching when available, to
21002115
// avoid all this rightward drift and spikiness.
21012116

@@ -2187,7 +2202,8 @@ mod unify {
21872202
while i < expected_len {
21882203
let expected_tp = expected_tps[i];
21892204
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);
21912207
alt result {
21922208
ures_ok(rty) { result_tps += [rty]; }
21932209
_ { ret result; }
@@ -2208,7 +2224,8 @@ mod unify {
22082224
none. { ret ures_err(terr_box_mutability); }
22092225
some(m) { mut = m; }
22102226
}
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);
22122229
alt result {
22132230
ures_ok(result_sub) {
22142231
let mt = {ty: result_sub, mut: mut};
@@ -2228,7 +2245,8 @@ mod unify {
22282245
none. { ret ures_err(terr_box_mutability); }
22292246
some(m) { mut = m; }
22302247
}
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);
22322250
alt result {
22332251
ures_ok(result_mt) {
22342252
let mt = {ty: result_mt, mut: mut};
@@ -2248,7 +2266,8 @@ mod unify {
22482266
none. { ret ures_err(terr_vec_mutability); }
22492267
some(m) { mut = m; }
22502268
}
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);
22522271
alt result {
22532272
ures_ok(result_sub) {
22542273
let mt = {ty: result_sub, mut: mut};
@@ -2268,7 +2287,8 @@ mod unify {
22682287
none. { ret ures_err(terr_vec_mutability); }
22692288
some(m) { mut = m; }
22702289
}
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);
22722292
alt result {
22732293
ures_ok(result_sub) {
22742294
let mt = {ty: result_sub, mut: mut};
@@ -2286,13 +2306,15 @@ mod unify {
22862306
if ex_id.crate != act_id.crate || ex_id.node != act_id.node {
22872307
ret ures_err(terr_mismatch);
22882308
}
2289-
let result = unify_step(cx, ex_inner, act_inner);
2309+
let result = unify_step(
2310+
cx, ex_inner, act_inner, variance);
22902311
alt result {
22912312
ures_ok(res_inner) {
22922313
let i = 0u;
22932314
let res_tps = [];
22942315
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);
22962318
alt result {
22972319
ures_ok(rty) { res_tps += [rty]; }
22982320
_ { ret result; }
@@ -2338,7 +2360,7 @@ mod unify {
23382360
}
23392361
let result =
23402362
unify_step(cx, expected_field.mt.ty,
2341-
actual_field.mt.ty);
2363+
actual_field.mt.ty, variance);
23422364
alt result {
23432365
ures_ok(rty) {
23442366
let mt = {ty: rty, mut: mut};
@@ -2370,7 +2392,8 @@ mod unify {
23702392
while i < expected_len {
23712393
let expected_elem = expected_elems[i];
23722394
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);
23742397
alt result {
23752398
ures_ok(rty) { result_elems += [rty]; }
23762399
_ { ret result; }
@@ -2419,7 +2442,8 @@ mod unify {
24192442
// unify the base types...
24202443
alt struct(cx.tcx, actual) {
24212444
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);
24232447
alt rslt {
24242448
ures_ok(rty) {
24252449
// FIXME: probably too restrictive --
@@ -2435,7 +2459,8 @@ mod unify {
24352459
// If the actual type is *not* a constrained type,
24362460
// then we go ahead and just ignore the constraints on
24372461
// 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);
24392464
}
24402465
}
24412466
}
@@ -2444,7 +2469,7 @@ mod unify {
24442469
fn unify(expected: t, actual: t, vb: @var_bindings, tcx: ty_ctxt) ->
24452470
result {
24462471
let cx = @{vb: vb, tcx: tcx};
2447-
ret unify_step(cx, expected, actual);
2472+
ret unify_step(cx, expected, actual, covariant);
24482473
}
24492474
fn dump_var_bindings(tcx: ty_ctxt, vb: @var_bindings) {
24502475
let i = 0u;

0 commit comments

Comments
 (0)