@@ -1918,20 +1918,19 @@ mod unify {
1918
1918
actual_inputs : [ arg ] , actual_output : t ,
1919
1919
variance : variance ) ->
1920
1920
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) {
1924
1922
ret fn_common_res_err ( ures_err ( terr_arg_count) ) ;
1925
1923
}
1926
- // TODO: as above, we should have an iter2 iterator.
1927
1924
1928
- let result_ins: [ arg ] = [ ] ;
1929
- let i = 0 u;
1930
- while i < expected_len {
1925
+ // Would use vec::map2(), but for the need to return in case of
1926
+ // error:
1927
+ let i = 0 u, n = vec:: len ( expected_inputs) ;
1928
+ let result_ins = [ ] ;
1929
+ while i < n {
1931
1930
let expected_input = expected_inputs[ i] ;
1932
1931
let actual_input = actual_inputs[ i] ;
1933
- // Unify the result modes.
1934
1932
1933
+ // Unify the result modes.
1935
1934
let result_mode = if expected_input. mode == ast:: mode_infer {
1936
1935
actual_input. mode
1937
1936
} else if actual_input. mode == ast:: mode_infer {
@@ -1941,6 +1940,7 @@ mod unify {
1941
1940
( ures_err ( terr_mode_mismatch ( expected_input. mode ,
1942
1941
actual_input. mode ) ) ) ;
1943
1942
} else { expected_input. mode } ;
1943
+
1944
1944
// The variance changes (flips basically) when descending
1945
1945
// into arguments of function types
1946
1946
let result = unify_step (
@@ -1949,11 +1949,11 @@ mod unify {
1949
1949
alt result {
1950
1950
ures_ok( rty) { result_ins += [ { mode: result_mode, ty: rty} ] ; }
1951
1951
_ { ret fn_common_res_err( result) ; }
1952
- }
1952
+ } ;
1953
1953
i += 1 u;
1954
1954
}
1955
- // Check the output.
1956
1955
1956
+ // Check the output.
1957
1957
let result = unify_step ( cx, expected_output, actual_output, variance) ;
1958
1958
alt result {
1959
1959
ures_ok( rty) { ret fn_common_res_ok ( result_ins, rty) ; }
@@ -1962,38 +1962,33 @@ mod unify {
1962
1962
}
1963
1963
fn unify_fn_proto ( e_proto : ast:: proto , a_proto : ast:: proto ,
1964
1964
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 }
1971
1983
} ;
1972
1984
}
1973
1985
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
+ } ;
1997
1992
}
1998
1993
fn unify_fn ( cx : @ctxt , e_proto : ast:: proto , a_proto : ast:: proto ,
1999
1994
expected : t , actual : t , expected_inputs : [ arg ] ,
0 commit comments