@@ -157,6 +157,7 @@ import check::regionmanip::{replace_bound_regions_in_fn_ty};
157
157
import driver:: session:: session;
158
158
import util:: common:: { indent, indenter} ;
159
159
import ast:: { unsafe_fn, impure_fn, pure_fn, crust_fn} ;
160
+ import ast:: { m_const, m_imm, m_mutbl} ;
160
161
161
162
export infer_ctxt;
162
163
export new_infer_ctxt;
@@ -961,24 +962,27 @@ impl methods for resolve_state {
961
962
// we just fall back to requiring that a <: b.
962
963
//
963
964
// Assuming we have a bound from both sides, we will then examine
964
- // these bounds and see if they have the form (@MT_a, &rb.MT_b)
965
- // (resp. ~MT_a). If they do not, we fall back to subtyping.
965
+ // these bounds and see if they have the form (@M_a T_a, &rb.M_b T_b)
966
+ // (resp. ~M_a T_a, [M_a T_a], etc). If they do not, we fall back to
967
+ // subtyping.
966
968
//
967
969
// If they *do*, then we know that the two types could never be
968
- // subtypes of one another. We will then construct a type @MT_b and
969
- // ensure that type a is a subtype of that. This allows for the
970
+ // subtypes of one another. We will then construct a type @const T_b
971
+ // and ensure that type a is a subtype of that. This allows for the
970
972
// possibility of assigning from a type like (say) @[mut T1] to a type
971
- // &[const T2] where T1 <: T2. Basically we would require that @[mut
972
- // T1] <: @[const T2]. Next we require that the region for the
973
- // enclosing scope be a superregion of the region r. These two checks
974
- // together guarantee that the type A would be a subtype of the type B
975
- // if the @ were converted to a region r.
973
+ // &[T2] where T1 <: T2. This might seem surprising, since the `@`
974
+ // points at mutable memory but the `&` points at immutable memory.
975
+ // This would in fact be unsound, except for the borrowck, which comes
976
+ // later and guarantees that such mutability conversions are safe.
977
+ // See borrowck for more details. Next we require that the region for
978
+ // the enclosing scope be a superregion of the region r.
976
979
//
977
- // You might wonder why we don't just make the type &e.MT_a where e is
978
- // the enclosing region and check that &e.MT_a <: B. The reason is
979
- // that the type @MT_a is (generally) just a *lower-bound*, so this
980
- // would be imposing @MT_a also as the upper-bound on type A. But
981
- // this upper-bound might be stricter than what is truly needed.
980
+ // You might wonder why we don't make the type &e.const T_a where e is
981
+ // the enclosing region and check that &e.const T_a <: B. The reason
982
+ // is that the type of A is (generally) just a *lower-bound*, so this
983
+ // would be imposing that lower-bound also as the upper-bound on type
984
+ // A. But this upper-bound might be stricter than what is truly
985
+ // needed.
982
986
983
987
impl assignment for infer_ctxt {
984
988
fn assign_tys( anmnt : assignment, a : ty:: t, b : ty:: t) -> ures {
@@ -1051,35 +1055,39 @@ impl assignment for infer_ctxt {
1051
1055
( some( a_bnd) , some( b_bnd) ) {
1052
1056
alt ( ty:: get( a_bnd) . struct , ty:: get( b_bnd) . struct ) {
1053
1057
( ty:: ty_box( mt_a) , ty:: ty_rptr( r_b, mt_b) ) {
1054
- let nr_b = ty:: mk_box( self . tcx, mt_b) ;
1055
- self . crosspollinate( anmnt, a, nr_b, r_b)
1058
+ let nr_b = ty:: mk_box( self . tcx, { ty: mt_b. ty,
1059
+ mutbl: m_const} ) ;
1060
+ self . crosspollinate( anmnt, a, nr_b, mt_b. mutbl, r_b)
1056
1061
}
1057
1062
( ty:: ty_uniq( mt_a) , ty:: ty_rptr( r_b, mt_b) ) {
1058
- let nr_b = ty:: mk_uniq( self . tcx, mt_b) ;
1059
- self . crosspollinate( anmnt, a, nr_b, r_b)
1063
+ let nr_b = ty:: mk_uniq( self . tcx, { ty: mt_b. ty,
1064
+ mutbl: m_const} ) ;
1065
+ self . crosspollinate( anmnt, a, nr_b, mt_b. mutbl, r_b)
1060
1066
}
1061
1067
( ty:: ty_estr( vs_a) ,
1062
1068
ty:: ty_estr( ty:: vstore_slice( r_b) ) )
1063
1069
if is_borrowable( vs_a) {
1064
1070
let nr_b = ty:: mk_estr( self . tcx, vs_a) ;
1065
- self . crosspollinate( anmnt, a, nr_b, r_b)
1071
+ self . crosspollinate( anmnt, a, nr_b, m_imm , r_b)
1066
1072
}
1067
1073
( ty:: ty_str,
1068
1074
ty:: ty_estr( ty:: vstore_slice( r_b) ) ) {
1069
1075
let nr_b = ty:: mk_str( self . tcx) ;
1070
- self . crosspollinate( anmnt, a, nr_b, r_b)
1076
+ self . crosspollinate( anmnt, a, nr_b, m_imm , r_b)
1071
1077
}
1072
1078
1073
1079
( ty:: ty_evec( mt_a, vs_a) ,
1074
1080
ty:: ty_evec( mt_b, ty:: vstore_slice( r_b) ) )
1075
1081
if is_borrowable( vs_a) {
1076
- let nr_b = ty:: mk_evec( self . tcx, mt_b, vs_a) ;
1077
- self . crosspollinate( anmnt, a, nr_b, r_b)
1082
+ let nr_b = ty:: mk_evec( self . tcx, { ty: mt_b. ty,
1083
+ mutbl: m_const} , vs_a) ;
1084
+ self . crosspollinate( anmnt, a, nr_b, mt_b. mutbl, r_b)
1078
1085
}
1079
1086
( ty:: ty_vec( mt_a) ,
1080
1087
ty:: ty_evec( mt_b, ty:: vstore_slice( r_b) ) ) {
1081
- let nr_b = ty:: mk_vec( self . tcx, mt_b) ;
1082
- self . crosspollinate( anmnt, a, nr_b, r_b)
1088
+ let nr_b = ty:: mk_vec( self . tcx, { ty: mt_b. ty,
1089
+ mutbl: m_const} ) ;
1090
+ self . crosspollinate( anmnt, a, nr_b, mt_b. mutbl, r_b)
1083
1091
}
1084
1092
_ {
1085
1093
self . sub_tys( a, b)
@@ -1093,9 +1101,10 @@ impl assignment for infer_ctxt {
1093
1101
}
1094
1102
1095
1103
fn crosspollinate( anmnt: assignment,
1096
- a: ty:: t,
1097
- nr_b: ty:: t,
1098
- r_b: ty:: region) -> ures {
1104
+ a: ty:: t,
1105
+ nr_b: ty:: t,
1106
+ m: ast:: mutability,
1107
+ r_b: ty:: region) -> ures {
1099
1108
1100
1109
#debug[ "crosspollinate(anmnt=%?, a=%s, nr_b=%s, r_b=%s)" ,
1101
1110
anmnt, a. to_str( self ) , nr_b. to_str( self ) ,
@@ -1109,8 +1118,9 @@ impl assignment for infer_ctxt {
1109
1118
// if successful, add an entry indicating that
1110
1119
// borrowing occurred
1111
1120
#debug[ "borrowing expression #%?" , anmnt] ;
1112
- self . tcx. borrowings. insert( anmnt. expr_id,
1113
- anmnt. borrow_scope) ;
1121
+ let borrow = { scope_id: anmnt. borrow_scope,
1122
+ mutbl: m} ;
1123
+ self . tcx. borrowings. insert( anmnt. expr_id, borrow) ;
1114
1124
uok( )
1115
1125
}
1116
1126
}
@@ -1561,17 +1571,17 @@ impl of combine for sub {
1561
1571
fn mts( a: ty:: mt, b: ty:: mt) -> cres < ty:: mt > {
1562
1572
#debug( "mts(%s <: %s)" , a. to_str( * self ) , b. to_str( * self ) ) ;
1563
1573
1564
- if a. mutbl != b. mutbl && b. mutbl != ast :: m_const {
1574
+ if a. mutbl != b. mutbl && b. mutbl != m_const {
1565
1575
ret err( ty:: terr_mutability) ;
1566
1576
}
1567
1577
1568
1578
alt b. mutbl {
1569
- ast : : m_mutbl {
1579
+ m_mutbl {
1570
1580
// If supertype is mut, subtype must match exactly
1571
1581
// (i.e., invariant if mut):
1572
1582
self. infcx( ) . eq_tys( a. ty, b. ty) . then { || ok( a) }
1573
1583
}
1574
- ast :: m_imm | ast :: m_const {
1584
+ m_imm | m_const {
1575
1585
// Otherwise we can be covariant:
1576
1586
self. tys( a. ty, b. ty) . chain { |_t | ok( a) }
1577
1587
}
@@ -1710,24 +1720,24 @@ impl of combine for lub {
1710
1720
let m = if a. mutbl == b. mutbl {
1711
1721
a. mutbl
1712
1722
} else {
1713
- ast :: m_const
1723
+ m_const
1714
1724
} ;
1715
1725
1716
1726
alt m {
1717
- ast : : m_imm | ast :: m_const {
1727
+ m_imm | m_const {
1718
1728
self. tys( a. ty, b. ty) . chain { |t |
1719
1729
ok ( { ty : t, mutbl : m} )
1720
1730
}
1721
1731
}
1722
1732
1723
- ast :: m_mutbl {
1733
+ m_mutbl {
1724
1734
self . infcx( ) . try { ||
1725
1735
self . infcx( ) . eq_tys( a. ty, b. ty) . then { ||
1726
1736
ok( { ty: a. ty, mutbl: m} )
1727
1737
}
1728
1738
} . chain_err { |_e|
1729
1739
self . tys( a. ty, b. ty) . chain { |t|
1730
- ok ( { ty : t, mutbl : ast :: m_const} )
1740
+ ok ( { ty : t, mutbl : m_const} )
1731
1741
}
1732
1742
}
1733
1743
}
@@ -1893,43 +1903,43 @@ impl of combine for glb {
1893
1903
alt ( a. mutbl, b. mutbl) {
1894
1904
// If one side or both is mut, then the GLB must use
1895
1905
// the precise type from the mut side.
1896
- ( ast :: m_mutbl, ast :: m_const) {
1906
+ ( m_mutbl, m_const) {
1897
1907
sub( * self ) . tys( a. ty, b. ty) . chain { |_t|
1898
- ok ( { ty : a. ty, mutbl : ast :: m_mutbl} )
1908
+ ok ( { ty : a. ty, mutbl : m_mutbl} )
1899
1909
}
1900
1910
}
1901
- ( ast :: m_const, ast :: m_mutbl) {
1911
+ ( m_const, m_mutbl) {
1902
1912
sub( * self ) . tys( b. ty, a. ty) . chain { |_t|
1903
- ok ( { ty : b. ty, mutbl : ast :: m_mutbl} )
1913
+ ok ( { ty : b. ty, mutbl : m_mutbl} )
1904
1914
}
1905
1915
}
1906
- ( ast :: m_mutbl, ast :: m_mutbl) {
1916
+ ( m_mutbl, m_mutbl) {
1907
1917
self . infcx( ) . eq_tys( a. ty, b. ty) . then { ||
1908
- ok( { ty: a. ty, mutbl: ast :: m_mutbl} )
1918
+ ok( { ty: a. ty, mutbl: m_mutbl} )
1909
1919
}
1910
1920
}
1911
1921
1912
1922
// If one side or both is immutable, we can use the GLB of
1913
1923
// both sides but mutbl must be `m_imm`.
1914
- ( ast :: m_imm, ast :: m_const) |
1915
- ( ast :: m_const, ast :: m_imm) |
1916
- ( ast :: m_imm, ast :: m_imm) {
1924
+ ( m_imm, m_const) |
1925
+ ( m_const, m_imm) |
1926
+ ( m_imm, m_imm) {
1917
1927
self . tys( a. ty, b. ty) . chain { |t|
1918
- ok ( { ty : t, mutbl : ast :: m_imm} )
1928
+ ok ( { ty : t, mutbl : m_imm} )
1919
1929
}
1920
1930
}
1921
1931
1922
1932
// If both sides are const, then we can use GLB of both
1923
1933
// sides and mutbl of only `m_const`.
1924
- ( ast :: m_const, ast :: m_const) {
1934
+ ( m_const, m_const) {
1925
1935
self . tys( a. ty, b. ty) . chain { |t|
1926
- ok ( { ty : t, mutbl : ast :: m_const} )
1936
+ ok ( { ty : t, mutbl : m_const} )
1927
1937
}
1928
1938
}
1929
1939
1930
1940
// There is no mutual subtype of these combinations.
1931
- ( ast :: m_mutbl, ast :: m_imm) |
1932
- ( ast :: m_imm, ast :: m_mutbl) {
1941
+ ( m_mutbl, m_imm) |
1942
+ ( m_imm, m_mutbl) {
1933
1943
err( ty:: terr_mutability)
1934
1944
}
1935
1945
}
0 commit comments