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,81 @@ 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+ & self
262254 }
263255
264256 #[ inline]
265257 pub fn types ( & ' a self ) -> impl DoubleEndedIterator < Item =Ty < ' tcx > > + ' a {
266- self . params . iter ( ) . filter_map ( |k| k. as_type ( ) )
258+ self . iter ( ) . filter_map ( |k| k. as_type ( ) )
267259 }
268260
269261 #[ inline]
270262 pub fn regions ( & ' a self ) -> impl DoubleEndedIterator < Item =& ' tcx ty:: Region > + ' a {
271- self . params . iter ( ) . filter_map ( |k| k. as_region ( ) )
263+ self . iter ( ) . filter_map ( |k| k. as_region ( ) )
272264 }
273265
274266 #[ inline]
275267 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 ) ;
268+ self [ i] . as_type ( ) . unwrap_or_else ( || {
269+ bug ! ( "expected type for param #{} in {:?}" , i, self ) ;
278270 } )
279271 }
280272
281273 #[ inline]
282274 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 ) ;
275+ self [ i] . as_region ( ) . unwrap_or_else ( || {
276+ bug ! ( "expected region for param #{} in {:?}" , i, self ) ;
285277 } )
286278 }
287279
@@ -305,27 +297,22 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
305297 target_substs : & Substs < ' tcx > )
306298 -> & ' tcx Substs < ' tcx > {
307299 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- } )
300+ Substs :: new ( tcx, target_substs. iter ( ) . chain ( & self [ defs. own_count ( ) ..] ) . cloned ( ) )
312301 }
313302}
314303
315304impl < ' tcx > TypeFoldable < ' tcx > for & ' tcx Substs < ' tcx > {
316305 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- } )
306+ let params = self . iter ( ) . map ( |k| k. fold_with ( folder) ) . collect ( ) ;
307+ folder. tcx ( ) . mk_substs ( params)
321308 }
322309
323310 fn fold_with < ' gcx : ' tcx , F : TypeFolder < ' gcx , ' tcx > > ( & self , folder : & mut F ) -> Self {
324311 folder. fold_substs ( self )
325312 }
326313
327314 fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
328- self . params . visit_with ( visitor)
315+ self . iter ( ) . any ( |t| t . visit_with ( visitor) )
329316 }
330317}
331318
@@ -340,19 +327,19 @@ impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Substs<'tcx> {}
340327
341328pub trait Subst < ' tcx > : Sized {
342329 fn subst < ' a , ' gcx > ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
343- substs : & Substs < ' tcx > ) -> Self {
330+ substs : & [ Kind < ' tcx > ] ) -> Self {
344331 self . subst_spanned ( tcx, substs, None )
345332 }
346333
347334 fn subst_spanned < ' a , ' gcx > ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
348- substs : & Substs < ' tcx > ,
335+ substs : & [ Kind < ' tcx > ] ,
349336 span : Option < Span > )
350337 -> Self ;
351338}
352339
353340impl < ' tcx , T : TypeFoldable < ' tcx > > Subst < ' tcx > for T {
354341 fn subst_spanned < ' a , ' gcx > ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
355- substs : & Substs < ' tcx > ,
342+ substs : & [ Kind < ' tcx > ] ,
356343 span : Option < Span > )
357344 -> T
358345 {
@@ -371,7 +358,7 @@ impl<'tcx, T:TypeFoldable<'tcx>> Subst<'tcx> for T {
371358
372359struct SubstFolder < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
373360 tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
374- substs : & ' a Substs < ' tcx > ,
361+ substs : & ' a [ Kind < ' tcx > ] ,
375362
376363 // The location for which the substitution is performed, if available.
377364 span : Option < Span > ,
@@ -404,7 +391,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
404391 // the specialized routine `ty::replace_late_regions()`.
405392 match * r {
406393 ty:: ReEarlyBound ( data) => {
407- let r = self . substs . params . get ( data. index as usize )
394+ let r = self . substs . get ( data. index as usize )
408395 . and_then ( |k| k. as_region ( ) ) ;
409396 match r {
410397 Some ( r) => {
@@ -461,7 +448,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
461448impl < ' a , ' gcx , ' tcx > SubstFolder < ' a , ' gcx , ' tcx > {
462449 fn ty_for_param ( & self , p : ty:: ParamTy , source_ty : Ty < ' tcx > ) -> Ty < ' tcx > {
463450 // 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 )
451+ let opt_ty = self . substs . get ( p. idx as usize )
465452 . and_then ( |k| k. as_type ( ) ) ;
466453 let ty = match opt_ty {
467454 Some ( t) => t,
@@ -475,7 +462,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
475462 source_ty,
476463 p. idx,
477464 self . root_ty,
478- self . substs. params ) ;
465+ self . substs) ;
479466 }
480467 } ;
481468
@@ -552,7 +539,7 @@ impl<'a, 'gcx, 'tcx> ty::TraitRef<'tcx> {
552539 -> ty:: TraitRef < ' tcx > {
553540 let defs = tcx. lookup_generics ( trait_id) ;
554541
555- let params = substs. params [ ..defs. own_count ( ) ] . iter ( ) . cloned ( ) ;
542+ let params = substs[ ..defs. own_count ( ) ] . iter ( ) . cloned ( ) ;
556543 ty:: TraitRef {
557544 def_id : trait_id,
558545 substs : Substs :: new ( tcx, params)
@@ -567,7 +554,7 @@ impl<'a, 'gcx, 'tcx> ty::ExistentialTraitRef<'tcx> {
567554 // Assert there is a Self.
568555 trait_ref. substs . type_at ( 0 ) ;
569556
570- let params = trait_ref. substs . params [ 1 ..] . iter ( ) . cloned ( ) ;
557+ let params = trait_ref. substs [ 1 ..] . iter ( ) . cloned ( ) ;
571558 ty:: ExistentialTraitRef {
572559 def_id : trait_ref. def_id ,
573560 substs : Substs :: new ( tcx, params)
@@ -587,7 +574,7 @@ impl<'a, 'gcx, 'tcx> ty::PolyExistentialTraitRef<'tcx> {
587574 assert ! ( !self_ty. has_escaping_regions( ) ) ;
588575
589576 self . map_bound ( |trait_ref| {
590- let params = trait_ref. substs . params . iter ( ) . cloned ( ) ;
577+ let params = trait_ref. substs . iter ( ) . cloned ( ) ;
591578 let params = iter:: once ( Kind :: from ( self_ty) ) . chain ( params) ;
592579 ty:: TraitRef {
593580 def_id : trait_ref. def_id ,
0 commit comments