@@ -25,7 +25,7 @@ use middle::stability;
25
25
use ty:: subst:: Substs ;
26
26
use traits;
27
27
use ty:: { self , TraitRef , Ty , TypeAndMut } ;
28
- use ty:: { TyS , TypeVariants } ;
28
+ use ty:: { TyS , TypeVariants , Slice } ;
29
29
use ty:: { AdtKind , AdtDef , ClosureSubsts , Region } ;
30
30
use hir:: FreevarMap ;
31
31
use ty:: { BareFnTy , InferTy , ParamTy , ProjectionTy , TraitObject } ;
@@ -92,7 +92,7 @@ pub struct CtxtInterners<'tcx> {
92
92
/// Specifically use a speedy hash algorithm for these hash sets,
93
93
/// they're accessed quite often.
94
94
type_ : RefCell < FnvHashSet < Interned < ' tcx , TyS < ' tcx > > > > ,
95
- type_list : RefCell < FnvHashSet < Interned < ' tcx , [ Ty < ' tcx > ] > > > ,
95
+ type_list : RefCell < FnvHashSet < Interned < ' tcx , Slice < Ty < ' tcx > > > > > ,
96
96
substs : RefCell < FnvHashSet < Interned < ' tcx , Substs < ' tcx > > > > ,
97
97
bare_fn : RefCell < FnvHashSet < Interned < ' tcx , BareFnTy < ' tcx > > > > ,
98
98
region : RefCell < FnvHashSet < Interned < ' tcx , Region > > > ,
@@ -847,10 +847,11 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Region {
847
847
}
848
848
}
849
849
850
- impl < ' a , ' tcx > Lift < ' tcx > for & ' a [ Ty < ' a > ] {
851
- type Lifted = & ' tcx [ Ty < ' tcx > ] ;
852
- fn lift_to_tcx < ' b , ' gcx > ( & self , tcx : TyCtxt < ' b , ' gcx , ' tcx > ) -> Option < & ' tcx [ Ty < ' tcx > ] > {
853
- if let Some ( & Interned ( list) ) = tcx. interners . type_list . borrow ( ) . get ( * self ) {
850
+ impl < ' a , ' tcx > Lift < ' tcx > for & ' a Slice < Ty < ' a > > {
851
+ type Lifted = & ' tcx Slice < Ty < ' tcx > > ;
852
+ fn lift_to_tcx < ' b , ' gcx > ( & self , tcx : TyCtxt < ' b , ' gcx , ' tcx > )
853
+ -> Option < & ' tcx Slice < Ty < ' tcx > > > {
854
+ if let Some ( & Interned ( list) ) = tcx. interners . type_list . borrow ( ) . get ( & self [ ..] ) {
854
855
if * self as * const _ == list as * const _ {
855
856
return Some ( list) ;
856
857
}
@@ -1067,9 +1068,24 @@ impl<'tcx: 'lcx, 'lcx> Borrow<TypeVariants<'lcx>> for Interned<'tcx, TyS<'tcx>>
1067
1068
}
1068
1069
}
1069
1070
1070
- impl < ' tcx : ' lcx , ' lcx > Borrow < [ Ty < ' lcx > ] > for Interned < ' tcx , [ Ty < ' tcx > ] > {
1071
+ // NB: An Interned<Slice<T>> compares and hashes as its elements.
1072
+ impl < ' tcx , T : PartialEq > PartialEq for Interned < ' tcx , Slice < T > > {
1073
+ fn eq ( & self , other : & Interned < ' tcx , Slice < T > > ) -> bool {
1074
+ self . 0 [ ..] == other. 0 [ ..]
1075
+ }
1076
+ }
1077
+
1078
+ impl < ' tcx , T : Eq > Eq for Interned < ' tcx , Slice < T > > { }
1079
+
1080
+ impl < ' tcx , T : Hash > Hash for Interned < ' tcx , Slice < T > > {
1081
+ fn hash < H : Hasher > ( & self , s : & mut H ) {
1082
+ self . 0 [ ..] . hash ( s)
1083
+ }
1084
+ }
1085
+
1086
+ impl < ' tcx : ' lcx , ' lcx > Borrow < [ Ty < ' lcx > ] > for Interned < ' tcx , Slice < Ty < ' tcx > > > {
1071
1087
fn borrow < ' a > ( & ' a self ) -> & ' a [ Ty < ' lcx > ] {
1072
- self . 0
1088
+ & self . 0 [ .. ]
1073
1089
}
1074
1090
}
1075
1091
@@ -1091,32 +1107,23 @@ impl<'tcx> Borrow<Region> for Interned<'tcx, Region> {
1091
1107
}
1092
1108
}
1093
1109
1094
- macro_rules! items { ( $( $item: item) +) => ( $( $item) +) }
1095
- macro_rules! impl_interners {
1096
- ( $lt_tcx: tt, $( $name: ident: $method: ident( $alloc: ty, $needs_infer: expr) -> $ty: ty) ,+) => {
1097
- items!( $( impl <$lt_tcx> PartialEq for Interned <$lt_tcx, $ty> {
1098
- fn eq( & self , other: & Self ) -> bool {
1099
- self . 0 == other. 0
1100
- }
1101
- }
1102
-
1103
- impl <$lt_tcx> Eq for Interned <$lt_tcx, $ty> { }
1104
-
1105
- impl <$lt_tcx> Hash for Interned <$lt_tcx, $ty> {
1106
- fn hash<H : Hasher >( & self , s: & mut H ) {
1107
- self . 0 . hash( s)
1108
- }
1109
- }
1110
-
1110
+ macro_rules! intern_method {
1111
+ ( $lt_tcx: tt, $name: ident: $method: ident( $alloc: ty,
1112
+ $alloc_to_key: expr,
1113
+ $alloc_to_ret: expr,
1114
+ $needs_infer: expr) -> $ty: ty) => {
1111
1115
impl <' a, ' gcx, $lt_tcx> TyCtxt <' a, ' gcx, $lt_tcx> {
1112
1116
pub fn $method( self , v: $alloc) -> & $lt_tcx $ty {
1113
- if let Some ( i) = self . interners. $name. borrow( ) . get:: <$ty>( & v) {
1114
- return i. 0 ;
1115
- }
1116
- if !self . is_global( ) {
1117
- if let Some ( i) = self . global_interners. $name. borrow( ) . get:: <$ty>( & v) {
1117
+ {
1118
+ let key = ( $alloc_to_key) ( & v) ;
1119
+ if let Some ( i) = self . interners. $name. borrow( ) . get( key) {
1118
1120
return i. 0 ;
1119
1121
}
1122
+ if !self . is_global( ) {
1123
+ if let Some ( i) = self . global_interners. $name. borrow( ) . get( key) {
1124
+ return i. 0 ;
1125
+ }
1126
+ }
1120
1127
}
1121
1128
1122
1129
// HACK(eddyb) Depend on flags being accurate to
@@ -1127,7 +1134,7 @@ macro_rules! impl_interners {
1127
1134
let v = unsafe {
1128
1135
mem:: transmute( v)
1129
1136
} ;
1130
- let i = self . global_interners. arenas. $name. alloc( v) ;
1137
+ let i = ( $alloc_to_ret ) ( self . global_interners. arenas. $name. alloc( v) ) ;
1131
1138
self . global_interners. $name. borrow_mut( ) . insert( Interned ( i) ) ;
1132
1139
return i;
1133
1140
}
@@ -1141,34 +1148,59 @@ macro_rules! impl_interners {
1141
1148
}
1142
1149
}
1143
1150
1144
- let i = self . interners. arenas. $name. alloc( v) ;
1151
+ let i = ( $alloc_to_ret ) ( self . interners. arenas. $name. alloc( v) ) ;
1145
1152
self . interners. $name. borrow_mut( ) . insert( Interned ( i) ) ;
1146
1153
i
1147
1154
}
1148
- } ) +) ;
1155
+ }
1156
+ }
1157
+ }
1158
+
1159
+ macro_rules! direct_interners {
1160
+ ( $lt_tcx: tt, $( $name: ident: $method: ident( $needs_infer: expr) -> $ty: ty) ,+) => {
1161
+ $( impl <$lt_tcx> PartialEq for Interned <$lt_tcx, $ty> {
1162
+ fn eq( & self , other: & Self ) -> bool {
1163
+ self . 0 == other. 0
1164
+ }
1165
+ }
1166
+
1167
+ impl <$lt_tcx> Eq for Interned <$lt_tcx, $ty> { }
1168
+
1169
+ impl <$lt_tcx> Hash for Interned <$lt_tcx, $ty> {
1170
+ fn hash<H : Hasher >( & self , s: & mut H ) {
1171
+ self . 0 . hash( s)
1172
+ }
1173
+ }
1174
+
1175
+ intern_method!( $lt_tcx, $name: $method( $ty, |x| x, |x| x, $needs_infer) -> $ty) ; ) +
1149
1176
}
1150
1177
}
1151
1178
1152
1179
fn keep_local < ' tcx , T : ty:: TypeFoldable < ' tcx > > ( x : & T ) -> bool {
1153
1180
x. has_type_flags ( ty:: TypeFlags :: KEEP_IN_LOCAL_TCX )
1154
1181
}
1155
1182
1156
- impl_interners ! ( ' tcx,
1157
- type_list: mk_type_list( Vec <Ty <' tcx>>, keep_local) -> [ Ty <' tcx>] ,
1158
- substs: mk_substs( Substs <' tcx>, |substs: & Substs | {
1183
+ direct_interners ! ( ' tcx,
1184
+ substs: mk_substs( |substs: & Substs | {
1159
1185
substs. params( ) . iter( ) . any( keep_local)
1160
1186
} ) -> Substs <' tcx>,
1161
- bare_fn: mk_bare_fn( BareFnTy < ' tcx> , |fty: & BareFnTy | {
1187
+ bare_fn: mk_bare_fn( |fty: & BareFnTy | {
1162
1188
keep_local( & fty. sig)
1163
1189
} ) -> BareFnTy <' tcx>,
1164
- region: mk_region( Region , |r| {
1190
+ region: mk_region( |r| {
1165
1191
match r {
1166
1192
& ty:: ReVar ( _) | & ty:: ReSkolemized ( ..) => true ,
1167
1193
_ => false
1168
1194
}
1169
1195
} ) -> Region
1170
1196
) ;
1171
1197
1198
+ intern_method ! ( ' tcx,
1199
+ type_list: mk_type_list( Vec <Ty <' tcx>>, Deref :: deref, |xs: & [ Ty ] | -> & Slice <Ty > {
1200
+ unsafe { mem:: transmute( xs) }
1201
+ } , keep_local) -> Slice <Ty <' tcx>>
1202
+ ) ;
1203
+
1172
1204
impl < ' a , ' gcx , ' tcx > TyCtxt < ' a , ' gcx , ' tcx > {
1173
1205
/// Create an unsafe fn ty based on a safe fn ty.
1174
1206
pub fn safe_to_unsafe_fn_ty ( self , bare_fn : & BareFnTy < ' tcx > ) -> Ty < ' tcx > {
0 commit comments