1111// Type substitutions.
1212
1313use hir:: def_id:: DefId ;
14- use ty:: { self , Ty , TyCtxt } ;
14+ use ty:: { self , Slice , Ty , TyCtxt } ;
1515use ty:: fold:: { TypeFoldable , TypeFolder , TypeVisitor } ;
1616
1717use serialize:: { self , Encodable , Encoder , Decodable , Decoder } ;
@@ -161,26 +161,19 @@ impl<'tcx> Decodable for Kind<'tcx> {
161161}
162162
163163/// A substitution mapping type/region parameters to new values.
164- #[ derive( Clone , PartialEq , Eq , Debug , Hash , RustcEncodable , RustcDecodable ) ]
165- pub struct Substs < ' tcx > {
166- params : Vec < Kind < ' tcx > >
167- }
164+ pub type Substs < ' tcx > = Slice < Kind < ' tcx > > ;
168165
169166impl < ' a , ' gcx , ' tcx > Substs < ' tcx > {
170167 pub fn new < I > ( tcx : TyCtxt < ' a , ' gcx , ' tcx > , params : I )
171168 -> & ' tcx Substs < ' tcx >
172169 where I : IntoIterator < Item =Kind < ' tcx > > {
173- tcx. mk_substs ( Substs {
174- params : params. into_iter ( ) . collect ( )
175- } )
170+ tcx. mk_substs ( params. into_iter ( ) . collect ( ) )
176171 }
177172
178173 pub fn maybe_new < I , E > ( tcx : TyCtxt < ' a , ' gcx , ' tcx > , params : I )
179174 -> Result < & ' tcx Substs < ' tcx > , E >
180175 where I : IntoIterator < Item =Result < Kind < ' tcx > , E > > {
181- Ok ( tcx. mk_substs ( Substs {
182- params : params. into_iter ( ) . collect :: < Result < _ , _ > > ( ) ?
183- } ) )
176+ Ok ( Substs :: new ( tcx, params. into_iter ( ) . collect :: < Result < Vec < _ > , _ > > ( ) ?) )
184177 }
185178
186179 pub fn new_trait ( tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
@@ -193,7 +186,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
193186 }
194187
195188 pub fn empty ( tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> & ' tcx Substs < ' tcx > {
196- Substs :: new ( tcx, vec ! [ ] )
189+ Substs :: new ( tcx, iter :: empty ( ) )
197190 }
198191
199192 /// Creates a Substs for generic parameter definitions,
@@ -206,82 +199,82 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
206199 mut mk_region : FR ,
207200 mut mk_type : FT )
208201 -> & ' tcx Substs < ' tcx >
209- where FR : FnMut ( & ty:: RegionParameterDef , & Substs < ' tcx > ) -> & ' tcx ty:: Region ,
210- FT : FnMut ( & ty:: TypeParameterDef < ' tcx > , & Substs < ' tcx > ) -> Ty < ' tcx > {
202+ where FR : FnMut ( & ty:: RegionParameterDef , & [ Kind < ' tcx > ] ) -> & ' tcx ty:: Region ,
203+ FT : FnMut ( & ty:: TypeParameterDef < ' tcx > , & [ Kind < ' tcx > ] ) -> Ty < ' tcx > {
211204 let defs = tcx. lookup_generics ( def_id) ;
212- let mut substs = Substs {
213- params : Vec :: with_capacity ( defs. count ( ) )
214- } ;
205+ let mut substs = Vec :: with_capacity ( defs. count ( ) ) ;
215206
216- substs . fill_item ( tcx, defs, & mut mk_region, & mut mk_type) ;
207+ Substs :: fill_item ( & mut substs , tcx, defs, & mut mk_region, & mut mk_type) ;
217208
218- tcx . mk_substs ( substs)
209+ Substs :: new ( tcx , substs)
219210 }
220211
221- fn fill_item < FR , FT > ( & mut self ,
212+ fn fill_item < FR , FT > ( substs : & mut Vec < Kind < ' tcx > > ,
222213 tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
223214 defs : & ty:: Generics < ' tcx > ,
224215 mk_region : & mut FR ,
225216 mk_type : & mut FT )
226- where FR : FnMut ( & ty:: RegionParameterDef , & Substs < ' tcx > ) -> & ' tcx ty:: Region ,
227- FT : FnMut ( & ty:: TypeParameterDef < ' tcx > , & Substs < ' tcx > ) -> Ty < ' tcx > {
217+ where FR : FnMut ( & ty:: RegionParameterDef , & [ Kind < ' tcx > ] ) -> & ' tcx ty:: Region ,
218+ FT : FnMut ( & ty:: TypeParameterDef < ' tcx > , & [ Kind < ' tcx > ] ) -> Ty < ' tcx > {
219+
228220 if let Some ( def_id) = defs. parent {
229221 let parent_defs = tcx. lookup_generics ( def_id) ;
230- self . fill_item ( tcx, parent_defs, mk_region, mk_type) ;
222+ Substs :: fill_item ( substs , tcx, parent_defs, mk_region, mk_type) ;
231223 }
232224
233225 // Handle Self first, before all regions.
234226 let mut types = defs. types . iter ( ) ;
235227 if defs. parent . is_none ( ) && defs. has_self {
236228 let def = types. next ( ) . unwrap ( ) ;
237- let ty = mk_type ( def, self ) ;
238- assert_eq ! ( def. index as usize , self . params . len( ) ) ;
239- self . params . push ( Kind :: from ( ty) ) ;
229+ let ty = mk_type ( def, substs ) ;
230+ assert_eq ! ( def. index as usize , substs . len( ) ) ;
231+ substs . push ( Kind :: from ( ty) ) ;
240232 }
241233
242234 for def in & defs. regions {
243- let region = mk_region ( def, self ) ;
244- assert_eq ! ( def. index as usize , self . params . len( ) ) ;
245- self . params . push ( Kind :: from ( region) ) ;
235+ let region = mk_region ( def, substs ) ;
236+ assert_eq ! ( def. index as usize , substs . len( ) ) ;
237+ substs . push ( Kind :: from ( region) ) ;
246238 }
247239
248240 for def in types {
249- let ty = mk_type ( def, self ) ;
250- assert_eq ! ( def. index as usize , self . params . len( ) ) ;
251- self . params . push ( Kind :: from ( ty) ) ;
241+ let ty = mk_type ( def, substs ) ;
242+ assert_eq ! ( def. index as usize , substs . len( ) ) ;
243+ substs . push ( Kind :: from ( ty) ) ;
252244 }
253245 }
254246
255247 pub fn is_noop ( & self ) -> bool {
256- self . params . is_empty ( )
248+ self . is_empty ( )
257249 }
258250
259251 #[ inline]
260252 pub fn params ( & self ) -> & [ Kind < ' tcx > ] {
261- & self . params
253+ // FIXME (dikaiosune) this should be removed, and corresponding compilation errors fixed
254+ self
262255 }
263256
264257 #[ inline]
265258 pub fn types ( & ' a self ) -> impl DoubleEndedIterator < Item =Ty < ' tcx > > + ' a {
266- self . params . iter ( ) . filter_map ( |k| k. as_type ( ) )
259+ self . iter ( ) . filter_map ( |k| k. as_type ( ) )
267260 }
268261
269262 #[ inline]
270263 pub fn regions ( & ' a self ) -> impl DoubleEndedIterator < Item =& ' tcx ty:: Region > + ' a {
271- self . params . iter ( ) . filter_map ( |k| k. as_region ( ) )
264+ self . iter ( ) . filter_map ( |k| k. as_region ( ) )
272265 }
273266
274267 #[ inline]
275268 pub fn type_at ( & self , i : usize ) -> Ty < ' tcx > {
276- self . params [ i] . as_type ( ) . unwrap_or_else ( || {
277- bug ! ( "expected type for param #{} in {:?}" , i, self . params ) ;
269+ self [ i] . as_type ( ) . unwrap_or_else ( || {
270+ bug ! ( "expected type for param #{} in {:?}" , i, self ) ;
278271 } )
279272 }
280273
281274 #[ inline]
282275 pub fn region_at ( & self , i : usize ) -> & ' tcx ty:: Region {
283- self . params [ i] . as_region ( ) . unwrap_or_else ( || {
284- bug ! ( "expected region for param #{} in {:?}" , i, self . params ) ;
276+ self [ i] . as_region ( ) . unwrap_or_else ( || {
277+ bug ! ( "expected region for param #{} in {:?}" , i, self ) ;
285278 } )
286279 }
287280
@@ -305,27 +298,22 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
305298 target_substs : & Substs < ' tcx > )
306299 -> & ' tcx Substs < ' tcx > {
307300 let defs = tcx. lookup_generics ( source_ancestor) ;
308- tcx. mk_substs ( Substs {
309- params : target_substs. params . iter ( )
310- . chain ( & self . params [ defs. own_count ( ) ..] ) . cloned ( ) . collect ( )
311- } )
301+ Substs :: new ( tcx, target_substs. iter ( ) . chain ( & self [ defs. own_count ( ) ..] ) . cloned ( ) )
312302 }
313303}
314304
315305impl < ' tcx > TypeFoldable < ' tcx > for & ' tcx Substs < ' tcx > {
316306 fn super_fold_with < ' gcx : ' tcx , F : TypeFolder < ' gcx , ' tcx > > ( & self , folder : & mut F ) -> Self {
317- let params = self . params . iter ( ) . map ( |k| k. fold_with ( folder) ) . collect ( ) ;
318- folder. tcx ( ) . mk_substs ( Substs {
319- params : params
320- } )
307+ let params = self . iter ( ) . map ( |k| k. fold_with ( folder) ) . collect ( ) ;
308+ folder. tcx ( ) . mk_substs ( params)
321309 }
322310
323311 fn fold_with < ' gcx : ' tcx , F : TypeFolder < ' gcx , ' tcx > > ( & self , folder : & mut F ) -> Self {
324312 folder. fold_substs ( self )
325313 }
326314
327315 fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
328- self . params . visit_with ( visitor)
316+ self . iter ( ) . any ( |t| t . visit_with ( visitor) )
329317 }
330318}
331319
@@ -340,19 +328,19 @@ impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Substs<'tcx> {}
340328
341329pub trait Subst < ' tcx > : Sized {
342330 fn subst < ' a , ' gcx > ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
343- substs : & Substs < ' tcx > ) -> Self {
331+ substs : & [ Kind < ' tcx > ] ) -> Self {
344332 self . subst_spanned ( tcx, substs, None )
345333 }
346334
347335 fn subst_spanned < ' a , ' gcx > ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
348- substs : & Substs < ' tcx > ,
336+ substs : & [ Kind < ' tcx > ] ,
349337 span : Option < Span > )
350338 -> Self ;
351339}
352340
353341impl < ' tcx , T : TypeFoldable < ' tcx > > Subst < ' tcx > for T {
354342 fn subst_spanned < ' a , ' gcx > ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
355- substs : & Substs < ' tcx > ,
343+ substs : & [ Kind < ' tcx > ] ,
356344 span : Option < Span > )
357345 -> T
358346 {
@@ -371,7 +359,7 @@ impl<'tcx, T:TypeFoldable<'tcx>> Subst<'tcx> for T {
371359
372360struct SubstFolder < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
373361 tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
374- substs : & ' a Substs < ' tcx > ,
362+ substs : & ' a [ Kind < ' tcx > ] ,
375363
376364 // The location for which the substitution is performed, if available.
377365 span : Option < Span > ,
@@ -404,7 +392,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
404392 // the specialized routine `ty::replace_late_regions()`.
405393 match * r {
406394 ty:: ReEarlyBound ( data) => {
407- let r = self . substs . params . get ( data. index as usize )
395+ let r = self . substs . get ( data. index as usize )
408396 . and_then ( |k| k. as_region ( ) ) ;
409397 match r {
410398 Some ( r) => {
@@ -461,7 +449,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
461449impl < ' a , ' gcx , ' tcx > SubstFolder < ' a , ' gcx , ' tcx > {
462450 fn ty_for_param ( & self , p : ty:: ParamTy , source_ty : Ty < ' tcx > ) -> Ty < ' tcx > {
463451 // Look up the type in the substitutions. It really should be in there.
464- let opt_ty = self . substs . params . get ( p. idx as usize )
452+ let opt_ty = self . substs . get ( p. idx as usize )
465453 . and_then ( |k| k. as_type ( ) ) ;
466454 let ty = match opt_ty {
467455 Some ( t) => t,
@@ -475,7 +463,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
475463 source_ty,
476464 p. idx,
477465 self . root_ty,
478- self . substs. params ) ;
466+ self . substs) ;
479467 }
480468 } ;
481469
@@ -552,7 +540,7 @@ impl<'a, 'gcx, 'tcx> ty::TraitRef<'tcx> {
552540 -> ty:: TraitRef < ' tcx > {
553541 let defs = tcx. lookup_generics ( trait_id) ;
554542
555- let params = substs. params [ ..defs. own_count ( ) ] . iter ( ) . cloned ( ) ;
543+ let params = substs[ ..defs. own_count ( ) ] . iter ( ) . cloned ( ) ;
556544 ty:: TraitRef {
557545 def_id : trait_id,
558546 substs : Substs :: new ( tcx, params)
@@ -567,7 +555,7 @@ impl<'a, 'gcx, 'tcx> ty::ExistentialTraitRef<'tcx> {
567555 // Assert there is a Self.
568556 trait_ref. substs . type_at ( 0 ) ;
569557
570- let params = trait_ref. substs . params [ 1 ..] . iter ( ) . cloned ( ) ;
558+ let params = trait_ref. substs [ 1 ..] . iter ( ) . cloned ( ) ;
571559 ty:: ExistentialTraitRef {
572560 def_id : trait_ref. def_id ,
573561 substs : Substs :: new ( tcx, params)
@@ -587,7 +575,7 @@ impl<'a, 'gcx, 'tcx> ty::PolyExistentialTraitRef<'tcx> {
587575 assert ! ( !self_ty. has_escaping_regions( ) ) ;
588576
589577 self . map_bound ( |trait_ref| {
590- let params = trait_ref. substs . params . iter ( ) . cloned ( ) ;
578+ let params = trait_ref. substs . iter ( ) . cloned ( ) ;
591579 let params = iter:: once ( Kind :: from ( self_ty) ) . chain ( params) ;
592580 ty:: TraitRef {
593581 def_id : trait_ref. def_id ,
0 commit comments