Skip to content

Commit 71a4378

Browse files
committed
---
yaml --- r: 6846 b: refs/heads/master c: 98cbbbb h: refs/heads/master v: v3
1 parent bf66246 commit 71a4378

File tree

4 files changed

+53
-40
lines changed

4 files changed

+53
-40
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: 1bc6e72b97a4e35102ac6b2519dd0a48f5b5db1f
2+
refs/heads/master: 98cbbbb64241ac8fe7f0aeb453a8e4a5f55b081c

trunk/src/comp/middle/ty.rs

Lines changed: 34 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,20 +1918,19 @@ mod unify {
19181918
actual_inputs: [arg], actual_output: t,
19191919
variance: variance) ->
19201920
fn_common_res {
1921-
let expected_len = vec::len::<arg>(expected_inputs);
1922-
let actual_len = vec::len::<arg>(actual_inputs);
1923-
if expected_len != actual_len {
1921+
if !vec::same_length(expected_inputs, actual_inputs) {
19241922
ret fn_common_res_err(ures_err(terr_arg_count));
19251923
}
1926-
// TODO: as above, we should have an iter2 iterator.
19271924

1928-
let result_ins: [arg] = [];
1929-
let i = 0u;
1930-
while i < expected_len {
1925+
// Would use vec::map2(), but for the need to return in case of
1926+
// error:
1927+
let i = 0u, n = vec::len(expected_inputs);
1928+
let result_ins = [];
1929+
while i < n {
19311930
let expected_input = expected_inputs[i];
19321931
let actual_input = actual_inputs[i];
1933-
// Unify the result modes.
19341932

1933+
// Unify the result modes.
19351934
let result_mode = if expected_input.mode == ast::mode_infer {
19361935
actual_input.mode
19371936
} else if actual_input.mode == ast::mode_infer {
@@ -1941,6 +1940,7 @@ mod unify {
19411940
(ures_err(terr_mode_mismatch(expected_input.mode,
19421941
actual_input.mode)));
19431942
} else { expected_input.mode };
1943+
19441944
// The variance changes (flips basically) when descending
19451945
// into arguments of function types
19461946
let result = unify_step(
@@ -1949,11 +1949,11 @@ mod unify {
19491949
alt result {
19501950
ures_ok(rty) { result_ins += [{mode: result_mode, ty: rty}]; }
19511951
_ { ret fn_common_res_err(result); }
1952-
}
1952+
};
19531953
i += 1u;
19541954
}
1955-
// Check the output.
19561955

1956+
// Check the output.
19571957
let result = unify_step(cx, expected_output, actual_output, variance);
19581958
alt result {
19591959
ures_ok(rty) { ret fn_common_res_ok(result_ins, rty); }
@@ -1962,38 +1962,33 @@ mod unify {
19621962
}
19631963
fn unify_fn_proto(e_proto: ast::proto, a_proto: ast::proto,
19641964
variance: variance) -> option::t<result> {
1965-
fn rank(proto: ast::proto) -> int {
1966-
ret alt proto {
1967-
ast::proto_block. { 0 }
1968-
ast::proto_shared(_) { 1 }
1969-
ast::proto_send. { 2 }
1970-
ast::proto_bare. { 3 }
1965+
// Prototypes form a diamond-shaped partial order:
1966+
//
1967+
// block
1968+
// ^ ^
1969+
// shared send
1970+
// ^ ^
1971+
// bare
1972+
//
1973+
// where "^" means "subtype of" (forgive the abuse of the term
1974+
// subtype).
1975+
fn sub_proto(p_sub: ast::proto, p_sup: ast::proto) -> bool {
1976+
ret alt (p_sub, p_sup) {
1977+
(_, ast::proto_block.) { true }
1978+
(ast::proto_bare., _) { true }
1979+
1980+
// Equal prototypes (modulo sugar) are always subprotos:
1981+
(ast::proto_shared(_), ast::proto_shared(_)) { true }
1982+
(_, _) { p_sub == p_sup }
19711983
};
19721984
}
19731985

1974-
fn gt(e_proto: ast::proto, a_proto: ast::proto) -> bool {
1975-
ret rank(e_proto) > rank(a_proto);
1976-
}
1977-
1978-
ret if e_proto == a_proto {
1979-
none
1980-
} else if variance == invariant {
1981-
some(ures_err(terr_mismatch))
1982-
} else if variance == covariant {
1983-
if gt(e_proto, a_proto) {
1984-
some(ures_err(terr_mismatch))
1985-
} else {
1986-
none
1987-
}
1988-
} else if variance == contravariant {
1989-
if gt(a_proto, e_proto) {
1990-
some(ures_err(terr_mismatch))
1991-
} else {
1992-
none
1993-
}
1994-
} else {
1995-
fail
1996-
}
1986+
ret alt variance {
1987+
invariant. when e_proto == a_proto { none }
1988+
covariant. when sub_proto(a_proto, e_proto) { none }
1989+
contravariant. when sub_proto(e_proto, a_proto) { none }
1990+
_ { some(ures_err(terr_mismatch)) }
1991+
};
19971992
}
19981993
fn unify_fn(cx: @ctxt, e_proto: ast::proto, a_proto: ast::proto,
19991994
expected: t, actual: t, expected_inputs: [arg],
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// error-pattern: mismatched types: expected lambda(++uint) -> uint
2+
3+
fn test(f: lambda(uint) -> uint) -> uint {
4+
ret f(22u);
5+
}
6+
7+
fn main() {
8+
let f = sendfn(x: uint) -> uint { ret 4u; };
9+
log test(f);
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn test(f: block(uint) -> uint) -> uint {
2+
ret f(22u);
3+
}
4+
5+
fn main() {
6+
let y = test(sendfn(x: uint) -> uint { ret 4u * x; });
7+
assert y == 88u;
8+
}

0 commit comments

Comments
 (0)