Skip to content

Commit 66fc41c

Browse files
committed
---
yaml --- r: 5878 b: refs/heads/master c: 8136b92 h: refs/heads/master v: v3
1 parent 29304ff commit 66fc41c

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
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: ed985b61d5c1e35b10a135ec8872aec2fbf66531
2+
refs/heads/master: 8136b92ee8e47fc460e64eb7ab65bc59f33efb71

trunk/src/comp/middle/ty.rs

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,9 +1010,11 @@ fn type_kind(cx: ctxt, ty: t) -> ast::kind {
10101010
// here yet, leading to weirdness around closure.
10111011
ty_fn(proto, _, _, _, _) {
10121012
result = alt proto {
1013+
ast::proto_iter. { ast::kind_shared }
10131014
ast::proto_block. { ast::kind_pinned }
10141015
ast::proto_closure. { ast::kind_shared }
1015-
_ { ast::kind_unique }
1016+
ast::proto_fn. { ast::kind_shared }
1017+
ast::proto_bare. { ast::kind_unique }
10161018
};
10171019
}
10181020
// Those with refcounts-to-inner raise pinned to shared,
@@ -2018,14 +2020,67 @@ mod unify {
20182020
_ { ret fn_common_res_err(result); }
20192021
}
20202022
}
2023+
fn unify_fn_proto(e_proto: ast::proto, a_proto: ast::proto,
2024+
variance: variance) -> option::t<result> {
2025+
fn gt(e_proto: ast::proto, a_proto: ast::proto) -> bool {
2026+
alt e_proto {
2027+
ast::proto_block. {
2028+
// Every function type is a subtype of block
2029+
false
2030+
}
2031+
ast::proto_closure. | ast::proto_fn. {
2032+
a_proto == ast::proto_block
2033+
}
2034+
ast::proto_bare. {
2035+
a_proto != ast::proto_bare
2036+
}
2037+
}
2038+
}
2039+
2040+
ret if (e_proto == ast::proto_iter
2041+
|| a_proto == ast::proto_iter) {
2042+
if e_proto != a_proto {
2043+
some(ures_err(terr_mismatch))
2044+
} else {
2045+
none
2046+
}
2047+
} else if e_proto == a_proto {
2048+
none
2049+
} else if variance == invariant {
2050+
if e_proto != a_proto {
2051+
some(ures_err(terr_mismatch))
2052+
} else {
2053+
fail
2054+
}
2055+
} else if variance == covariant {
2056+
if gt(e_proto, a_proto) {
2057+
some(ures_err(terr_mismatch))
2058+
} else {
2059+
none
2060+
}
2061+
} else if variance == contravariant {
2062+
if gt(a_proto, e_proto) {
2063+
some(ures_err(terr_mismatch))
2064+
} else {
2065+
none
2066+
}
2067+
} else {
2068+
fail
2069+
}
2070+
}
20212071
fn unify_fn(cx: @ctxt, e_proto: ast::proto, a_proto: ast::proto,
20222072
expected: t, actual: t, expected_inputs: [arg],
20232073
expected_output: t, actual_inputs: [arg], actual_output: t,
20242074
expected_cf: ret_style, actual_cf: ret_style,
20252075
_expected_constrs: [@constr], actual_constrs: [@constr],
20262076
variance: variance) ->
20272077
result {
2028-
if e_proto != a_proto { ret ures_err(terr_mismatch); }
2078+
2079+
alt unify_fn_proto(e_proto, a_proto, variance) {
2080+
some(err) { ret err; }
2081+
none. { /* fall through */ }
2082+
}
2083+
20292084
if actual_cf != ast::noreturn && actual_cf != expected_cf {
20302085
/* even though typestate checking is mostly
20312086
responsible for checking control flow annotations,
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
type r = {
2+
field: fn@()
3+
};
4+
5+
fn main() {
6+
let i: r = {field: fn#() { }};
7+
}

0 commit comments

Comments
 (0)