@@ -283,6 +283,7 @@ enum type_err {
283
283
terr_mode_mismatch( mode , mode ) ,
284
284
terr_constr_len( uint , uint ) ,
285
285
terr_constr_mismatch( @type_constr , @type_constr ) ,
286
+ terr_regions_differ,
286
287
}
287
288
288
289
enum param_bound {
@@ -1885,6 +1886,45 @@ mod unify {
1885
1886
}
1886
1887
}
1887
1888
}
1889
+ fn unify_regions ( cx : @uctxt , e_region : region , a_region : region ,
1890
+ variance : variance ) -> option < region > {
1891
+ let sub, super ;
1892
+ alt variance {
1893
+ covariant { super = e_region; sub = a_region; }
1894
+ contravariant { super = a_region; sub = e_region; }
1895
+ invariant {
1896
+ ret if e_region == a_region { some( e_region) } else { none } ;
1897
+ }
1898
+ }
1899
+
1900
+ alt ( super , sub) {
1901
+ ( re_caller ( _) , re_caller ( _) ) {
1902
+ // FIXME: This is wrong w/r/t nested functions.
1903
+ ret some ( super ) ;
1904
+ }
1905
+ ( re_caller ( _) , re_named ( _) ) | ( re_named ( _) , re_caller ( _) ) {
1906
+ ret none;
1907
+ }
1908
+ ( re_named ( a) , re_named ( b) ) {
1909
+ ret if a == b { some ( super ) } else { none }
1910
+ }
1911
+ ( re_caller ( _) , re_block ( _) ) | ( re_named ( _) , re_block ( _) ) {
1912
+ // FIXME: This is wrong w/r/t nested functions.
1913
+ ret some ( super ) ;
1914
+ }
1915
+ ( re_block ( _) , re_caller ( _) ) | ( re_block ( _) , re_named ( _) ) {
1916
+ ret none;
1917
+ }
1918
+ ( re_block ( superblock) , re_block ( subblock) ) {
1919
+ if region:: block_contains ( cx. tcx . region_map , superblock,
1920
+ subblock) {
1921
+ ret some ( super ) ;
1922
+ } else {
1923
+ ret none;
1924
+ }
1925
+ }
1926
+ }
1927
+ }
1888
1928
1889
1929
fn unify_step ( cx : @uctxt , expected : t , actual : t ,
1890
1930
variance : variance ) -> result {
@@ -1943,9 +1983,13 @@ mod unify {
1943
1983
unify_mt ( cx, e_mt, a_mt, variance, terr_ptr_mutability, mk_ptr)
1944
1984
}
1945
1985
( ty_rptr ( e_region, e_mt) , ty_rptr ( a_region, a_mt) ) {
1946
- // TODO: Unify regions. Take covariance/invariance into account.
1947
- unify_mt ( cx, e_mt, a_mt, variance, terr_ref_mutability,
1948
- bind mk_rptr ( _, re_block ( 0 ) , _) )
1986
+ alt unify_regions ( cx, e_region, a_region, variance) {
1987
+ none { ures_err( terr_regions_differ) }
1988
+ some ( r_region) {
1989
+ unify_mt ( cx, e_mt, a_mt, variance, terr_ref_mutability,
1990
+ bind mk_rptr ( _, r_region, _) )
1991
+ }
1992
+ }
1949
1993
}
1950
1994
( ty_res ( e_id, e_inner, e_tps) , ty_res ( a_id, a_inner, a_tps) )
1951
1995
if e_id == a_id {
@@ -2154,6 +2198,9 @@ fn type_err_to_str(err: type_err) -> str {
2154
2198
" but found one with constraint " +
2155
2199
ty_constr_to_str ( a_constr) ;
2156
2200
}
2201
+ terr_regions_differ {
2202
+ ret "inconsistent pointer lifetimes"
2203
+ }
2157
2204
}
2158
2205
}
2159
2206
0 commit comments