@@ -1010,9 +1010,11 @@ fn type_kind(cx: ctxt, ty: t) -> ast::kind {
1010
1010
// here yet, leading to weirdness around closure.
1011
1011
ty_fn ( proto, _, _, _, _) {
1012
1012
result = alt proto {
1013
+ ast : : proto_iter. { ast:: kind_shared }
1013
1014
ast:: proto_block. { ast:: kind_pinned }
1014
1015
ast:: proto_closure. { ast:: kind_shared }
1015
- _ { ast : : kind_unique }
1016
+ ast:: proto_fn. { ast:: kind_shared }
1017
+ ast:: proto_bare. { ast:: kind_unique }
1016
1018
} ;
1017
1019
}
1018
1020
// Those with refcounts-to-inner raise pinned to shared,
@@ -2018,14 +2020,67 @@ mod unify {
2018
2020
_ { ret fn_common_res_err( result) ; }
2019
2021
}
2020
2022
}
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
+ }
2021
2071
fn unify_fn ( cx : @ctxt , e_proto : ast:: proto , a_proto : ast:: proto ,
2022
2072
expected : t , actual : t , expected_inputs : [ arg ] ,
2023
2073
expected_output : t , actual_inputs : [ arg ] , actual_output : t ,
2024
2074
expected_cf : ret_style , actual_cf : ret_style ,
2025
2075
_expected_constrs : [ @constr ] , actual_constrs : [ @constr ] ,
2026
2076
variance : variance ) ->
2027
2077
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
+
2029
2084
if actual_cf != ast:: noreturn && actual_cf != expected_cf {
2030
2085
/* even though typestate checking is mostly
2031
2086
responsible for checking control flow annotations,
0 commit comments