@@ -112,17 +112,17 @@ impl Substs {
112112 r : Vec < ty:: Region > )
113113 -> Substs
114114 {
115- Substs :: new ( VecPerParamSpace :: new ( t, Vec :: new ( ) , Vec :: new ( ) ) ,
116- VecPerParamSpace :: new ( r, Vec :: new ( ) , Vec :: new ( ) ) )
115+ Substs :: new ( VecPerParamSpace :: new ( t, Vec :: new ( ) , Vec :: new ( ) , Vec :: new ( ) ) ,
116+ VecPerParamSpace :: new ( r, Vec :: new ( ) , Vec :: new ( ) , Vec :: new ( ) ) )
117117 }
118118
119119 pub fn new_trait ( t : Vec < ty:: t > ,
120120 r : Vec < ty:: Region > ,
121121 s : ty:: t )
122122 -> Substs
123123 {
124- Substs :: new ( VecPerParamSpace :: new ( t, vec ! ( s) , Vec :: new ( ) ) ,
125- VecPerParamSpace :: new ( r, Vec :: new ( ) , Vec :: new ( ) ) )
124+ Substs :: new ( VecPerParamSpace :: new ( t, vec ! ( s) , Vec :: new ( ) , Vec :: new ( ) ) ,
125+ VecPerParamSpace :: new ( r, Vec :: new ( ) , Vec :: new ( ) , Vec :: new ( ) ) )
126126 }
127127
128128 pub fn erased ( t : VecPerParamSpace < ty:: t > ) -> Substs
@@ -226,29 +226,32 @@ impl RegionSubsts {
226226#[ deriving( PartialOrd , Ord , PartialEq , Eq ,
227227 Clone , Hash , Encodable , Decodable , Show ) ]
228228pub enum ParamSpace {
229- TypeSpace, // Type parameters attached to a type definition, trait, or impl
230- SelfSpace, // Self parameter on a trait
231- FnSpace, // Type parameters attached to a method or fn
229+ TypeSpace, // Type parameters attached to a type definition, trait, or impl
230+ SelfSpace, // Self parameter on a trait
231+ AssocSpace, // Assoc types defined in a trait/impl
232+ FnSpace, // Type parameters attached to a method or fn
232233}
233234
234235impl ParamSpace {
235- pub fn all ( ) -> [ ParamSpace , ..3 ] {
236- [ TypeSpace , SelfSpace , FnSpace ]
236+ pub fn all ( ) -> [ ParamSpace , ..4 ] {
237+ [ TypeSpace , SelfSpace , AssocSpace , FnSpace ]
237238 }
238239
239240 pub fn to_uint ( self ) -> uint {
240241 match self {
241242 TypeSpace => 0 ,
242243 SelfSpace => 1 ,
243- FnSpace => 2 ,
244+ AssocSpace => 2 ,
245+ FnSpace => 3 ,
244246 }
245247 }
246248
247249 pub fn from_uint ( u : uint ) -> ParamSpace {
248250 match u {
249251 0 => TypeSpace ,
250252 1 => SelfSpace ,
251- 2 => FnSpace ,
253+ 2 => AssocSpace ,
254+ 3 => FnSpace ,
252255 _ => panic ! ( "Invalid ParamSpace: {}" , u)
253256 }
254257 }
@@ -268,11 +271,13 @@ pub struct VecPerParamSpace<T> {
268271 // Here is how the representation corresponds to the abstraction
269272 // i.e. the "abstraction function" AF:
270273 //
271- // AF(self) = (self.content.slice_to(self.type_limit),
272- // self.content.slice(self.type_limit, self.self_limit),
273- // self.content.slice_from(self.self_limit))
274+ // AF(self) = (self.content[..self.type_limit],
275+ // self.content[self.type_limit..self.self_limit],
276+ // self.content[self.self_limit..self.assoc_limit],
277+ // self.content[self.assoc_limit..])
274278 type_limit : uint ,
275279 self_limit : uint ,
280+ assoc_limit : uint ,
276281 content : Vec < T > ,
277282}
278283
@@ -292,14 +297,16 @@ impl<T> VecPerParamSpace<T> {
292297 match space {
293298 TypeSpace => ( 0 , self . type_limit ) ,
294299 SelfSpace => ( self . type_limit , self . self_limit ) ,
295- FnSpace => ( self . self_limit , self . content . len ( ) ) ,
300+ AssocSpace => ( self . self_limit , self . assoc_limit ) ,
301+ FnSpace => ( self . assoc_limit , self . content . len ( ) ) ,
296302 }
297303 }
298304
299305 pub fn empty ( ) -> VecPerParamSpace < T > {
300306 VecPerParamSpace {
301307 type_limit : 0 ,
302308 self_limit : 0 ,
309+ assoc_limit : 0 ,
303310 content : Vec :: new ( )
304311 }
305312 }
@@ -310,26 +317,33 @@ impl<T> VecPerParamSpace<T> {
310317
311318 /// `t` is the type space.
312319 /// `s` is the self space.
320+ /// `a` is the assoc space.
313321 /// `f` is the fn space.
314- pub fn new ( t : Vec < T > , s : Vec < T > , f : Vec < T > ) -> VecPerParamSpace < T > {
322+ pub fn new ( t : Vec < T > , s : Vec < T > , a : Vec < T > , f : Vec < T > ) -> VecPerParamSpace < T > {
315323 let type_limit = t. len ( ) ;
316- let self_limit = t. len ( ) + s. len ( ) ;
324+ let self_limit = type_limit + s. len ( ) ;
325+ let assoc_limit = self_limit + a. len ( ) ;
326+
317327 let mut content = t;
318328 content. extend ( s. into_iter ( ) ) ;
329+ content. extend ( a. into_iter ( ) ) ;
319330 content. extend ( f. into_iter ( ) ) ;
331+
320332 VecPerParamSpace {
321333 type_limit : type_limit,
322334 self_limit : self_limit,
335+ assoc_limit : assoc_limit,
323336 content : content,
324337 }
325338 }
326339
327- fn new_internal ( content : Vec < T > , type_limit : uint , self_limit : uint )
340+ fn new_internal ( content : Vec < T > , type_limit : uint , self_limit : uint , assoc_limit : uint )
328341 -> VecPerParamSpace < T >
329342 {
330343 VecPerParamSpace {
331344 type_limit : type_limit,
332345 self_limit : self_limit,
346+ assoc_limit : assoc_limit,
333347 content : content,
334348 }
335349 }
@@ -341,9 +355,10 @@ impl<T> VecPerParamSpace<T> {
341355 pub fn push ( & mut self , space : ParamSpace , value : T ) {
342356 let ( _, limit) = self . limits ( space) ;
343357 match space {
344- TypeSpace => { self . type_limit += 1 ; self . self_limit += 1 ; }
345- SelfSpace => { self . self_limit += 1 ; }
346- FnSpace => { }
358+ TypeSpace => { self . type_limit += 1 ; self . self_limit += 1 ; self . assoc_limit += 1 ; }
359+ SelfSpace => { self . self_limit += 1 ; self . assoc_limit += 1 ; }
360+ AssocSpace => { self . assoc_limit += 1 ; }
361+ FnSpace => { }
347362 }
348363 self . content . insert ( limit, value) ;
349364 }
@@ -354,9 +369,10 @@ impl<T> VecPerParamSpace<T> {
354369 None
355370 } else {
356371 match space {
357- TypeSpace => { self . type_limit -= 1 ; self . self_limit -= 1 ; }
358- SelfSpace => { self . self_limit -= 1 ; }
359- FnSpace => { }
372+ TypeSpace => { self . type_limit -= 1 ; self . self_limit -= 1 ; self . assoc_limit -= 1 ; }
373+ SelfSpace => { self . self_limit -= 1 ; self . assoc_limit -= 1 ; }
374+ AssocSpace => { self . assoc_limit -= 1 ; }
375+ FnSpace => { }
360376 }
361377 self . content . remove ( limit - 1 )
362378 }
@@ -442,35 +458,29 @@ impl<T> VecPerParamSpace<T> {
442458 let result = self . iter ( ) . map ( pred) . collect ( ) ;
443459 VecPerParamSpace :: new_internal ( result,
444460 self . type_limit ,
445- self . self_limit )
461+ self . self_limit ,
462+ self . assoc_limit )
446463 }
447464
448465 pub fn map_move < U > ( self , pred: |T | -> U ) -> VecPerParamSpace < U > {
449- let ( t, s, f) = self . split ( ) ;
466+ let ( t, s, a , f) = self . split ( ) ;
450467 VecPerParamSpace :: new ( t. into_iter ( ) . map ( |p| pred ( p) ) . collect ( ) ,
451468 s. into_iter ( ) . map ( |p| pred ( p) ) . collect ( ) ,
469+ a. into_iter ( ) . map ( |p| pred ( p) ) . collect ( ) ,
452470 f. into_iter ( ) . map ( |p| pred ( p) ) . collect ( ) )
453471 }
454472
455- pub fn split ( self ) -> ( Vec < T > , Vec < T > , Vec < T > ) {
456- // FIXME (#15418): this does two traversals when in principle
457- // one would suffice. i.e. change to use `move_iter`.
458- let VecPerParamSpace { type_limit, self_limit, content } = self ;
459- let mut i = 0 ;
460- let ( prefix, fn_vec) = content. partition ( |_| {
461- let on_left = i < self_limit;
462- i += 1 ;
463- on_left
464- } ) ;
473+ pub fn split ( self ) -> ( Vec < T > , Vec < T > , Vec < T > , Vec < T > ) {
474+ let VecPerParamSpace { type_limit, self_limit, assoc_limit, content } = self ;
475+
476+ let mut content_iter = content. into_iter ( ) ;
465477
466- let mut i = 0 ;
467- let ( type_vec, self_vec) = prefix. partition ( |_| {
468- let on_left = i < type_limit;
469- i += 1 ;
470- on_left
471- } ) ;
478+ let types = content_iter. by_ref ( ) . take ( type_limit) . collect ( ) ;
479+ let selfs = content_iter. by_ref ( ) . take ( self_limit - type_limit) . collect ( ) ;
480+ let assocs = content_iter. by_ref ( ) . take ( assoc_limit - self_limit) . collect ( ) ;
481+ let fns = content_iter. collect ( ) ;
472482
473- ( type_vec , self_vec , fn_vec )
483+ ( types , selfs , assocs , fns )
474484 }
475485
476486 pub fn with_vec ( mut self , space : ParamSpace , vec : Vec < T > )
@@ -616,12 +626,13 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
616626 this. tcx ( ) . sess . span_bug (
617627 span,
618628 format ! ( "Type parameter `{}` ({}/{}/{}) out of range \
619- when substituting (root type={})",
629+ when substituting (root type={}) substs={} ",
620630 p. repr( this. tcx( ) ) ,
621631 source_ty. repr( this. tcx( ) ) ,
622632 space,
623633 index,
624- this. root_ty. repr( this. tcx( ) ) ) . as_slice ( ) ) ;
634+ this. root_ty. repr( this. tcx( ) ) ,
635+ this. substs. repr( this. tcx( ) ) ) . as_slice ( ) ) ;
625636 }
626637 }
627638 }
0 commit comments