@@ -15,7 +15,6 @@ use middle::ty_fold;
1515use middle:: ty_fold:: { TypeFoldable , TypeFolder } ;
1616use util:: ppaux:: Repr ;
1717
18- use std:: iter:: Chain ;
1918use std:: mem;
2019use std:: raw;
2120use std:: slice:: { Items , MutItems } ;
@@ -191,8 +190,8 @@ impl Substs {
191190 }
192191
193192 pub fn with_method_from ( self , substs : & Substs ) -> Substs {
194- self . with_method ( ( * substs. types . get_vec ( FnSpace ) ) . clone ( ) ,
195- ( * substs. regions ( ) . get_vec ( FnSpace ) ) . clone ( ) )
193+ self . with_method ( Vec :: from_slice ( substs. types . get_slice ( FnSpace ) ) ,
194+ Vec :: from_slice ( substs. regions ( ) . get_slice ( FnSpace ) ) )
196195 }
197196
198197 pub fn with_method ( self ,
@@ -261,19 +260,44 @@ impl ParamSpace {
261260 */
262261#[ deriving( PartialEq , Eq , Clone , Hash , Encodable , Decodable ) ]
263262pub struct VecPerParamSpace < T > {
264- vecs : ( Vec < T > , Vec < T > , Vec < T > )
263+ // This was originally represented as a tuple with one Vec<T> for
264+ // each variant of ParamSpace, and that remains the abstraction
265+ // that it provides to its clients.
266+ //
267+ // Here is how the representation corresponds to the abstraction
268+ // i.e. the "abstraction function" AF:
269+ //
270+ // AF(self) = (self.content.slice_to(self.type_limit),
271+ // self.content.slice(self.type_limit, self.self_limit),
272+ // self.content.slice_from(self.self_limit))
273+ type_limit : uint ,
274+ self_limit : uint ,
275+ content : Vec < T > ,
265276}
266277
267278impl < T : Clone > VecPerParamSpace < T > {
268279 pub fn push_all ( & mut self , space : ParamSpace , values : & [ T ] ) {
269- self . get_mut_vec ( space) . push_all ( values) ;
280+ // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
281+ for t in values. iter ( ) {
282+ self . push ( space, t. clone ( ) ) ;
283+ }
270284 }
271285}
272286
273287impl < T > VecPerParamSpace < T > {
288+ fn limits ( & self , space : ParamSpace ) -> ( uint , uint ) {
289+ match space {
290+ TypeSpace => ( 0 , self . type_limit ) ,
291+ SelfSpace => ( self . type_limit , self . self_limit ) ,
292+ FnSpace => ( self . self_limit , self . content . len ( ) ) ,
293+ }
294+ }
295+
274296 pub fn empty ( ) -> VecPerParamSpace < T > {
275297 VecPerParamSpace {
276- vecs : ( Vec :: new ( ) , Vec :: new ( ) , Vec :: new ( ) )
298+ type_limit : 0 ,
299+ self_limit : 0 ,
300+ content : Vec :: new ( )
277301 }
278302 }
279303
@@ -282,8 +306,15 @@ impl<T> VecPerParamSpace<T> {
282306 }
283307
284308 pub fn new ( t : Vec < T > , s : Vec < T > , f : Vec < T > ) -> VecPerParamSpace < T > {
309+ let type_limit = t. len ( ) ;
310+ let self_limit = t. len ( ) + s. len ( ) ;
311+ let mut content = t;
312+ content. push_all_move ( s) ;
313+ content. push_all_move ( f) ;
285314 VecPerParamSpace {
286- vecs : ( t, s, f)
315+ type_limit : type_limit,
316+ self_limit : self_limit,
317+ content : content,
287318 }
288319 }
289320
@@ -295,75 +326,98 @@ impl<T> VecPerParamSpace<T> {
295326 result
296327 }
297328
329+ /// Appends `value` to the vector associated with `space`.
330+ ///
331+ /// Unlike the `push` method in `Vec`, this should not be assumed
332+ /// to be a cheap operation (even when amortized over many calls).
298333 pub fn push ( & mut self , space : ParamSpace , value : T ) {
299- self . get_mut_vec ( space) . push ( value) ;
334+ let ( _, limit) = self . limits ( space) ;
335+ match space {
336+ TypeSpace => { self . type_limit += 1 ; self . self_limit += 1 ; }
337+ SelfSpace => { self . self_limit += 1 ; }
338+ FnSpace => { }
339+ }
340+ self . content . insert ( limit, value) ;
300341 }
301342
302343 pub fn pop ( & mut self , space : ParamSpace ) -> Option < T > {
303- self . get_mut_vec ( space) . pop ( )
344+ let ( start, limit) = self . limits ( space) ;
345+ if start == limit {
346+ None
347+ } else {
348+ match space {
349+ TypeSpace => { self . type_limit -= 1 ; self . self_limit -= 1 ; }
350+ SelfSpace => { self . self_limit -= 1 ; }
351+ FnSpace => { }
352+ }
353+ self . content . remove ( limit - 1 )
354+ }
304355 }
305356
306357 pub fn truncate ( & mut self , space : ParamSpace , len : uint ) {
307- self . get_mut_vec ( space) . truncate ( len)
358+ // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
359+ while self . len ( space) > len {
360+ self . pop ( space) ;
361+ }
308362 }
309363
310364 pub fn replace ( & mut self , space : ParamSpace , elems : Vec < T > ) {
311- * self . get_mut_vec ( space) = elems;
365+ // FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
366+ self . truncate ( space, 0 ) ;
367+ for t in elems. move_iter ( ) {
368+ self . push ( space, t) ;
369+ }
312370 }
313371
314372 pub fn get_self < ' a > ( & ' a self ) -> Option < & ' a T > {
315- let v = self . get_vec ( SelfSpace ) ;
373+ let v = self . get_slice ( SelfSpace ) ;
316374 assert ! ( v. len( ) <= 1 ) ;
317- if v. len ( ) == 0 { None } else { Some ( v . get ( 0 ) ) }
375+ if v. len ( ) == 0 { None } else { Some ( & v [ 0 ] ) }
318376 }
319377
320378 pub fn len ( & self , space : ParamSpace ) -> uint {
321- self . get_vec ( space) . len ( )
379+ self . get_slice ( space) . len ( )
322380 }
323381
324382 pub fn is_empty_in ( & self , space : ParamSpace ) -> bool {
325- self . get_vec ( space ) . len ( ) == 0
383+ self . len ( space ) == 0
326384 }
327385
328386 pub fn get_slice < ' a > ( & ' a self , space : ParamSpace ) -> & ' a [ T ] {
329- self . get_vec ( space) . as_slice ( )
330- }
331-
332- fn get_vec < ' a > ( & ' a self , space : ParamSpace ) -> & ' a Vec < T > {
333- self . vecs . get ( space as uint ) . unwrap ( )
387+ let ( start, limit) = self . limits ( space) ;
388+ self . content . slice ( start, limit)
334389 }
335390
336- fn get_mut_vec < ' a > ( & ' a mut self , space : ParamSpace ) -> & ' a mut Vec < T > {
337- self . vecs . get_mut ( space as uint ) . unwrap ( )
391+ fn get_mut_slice < ' a > ( & ' a mut self , space : ParamSpace ) -> & ' a mut [ T ] {
392+ let ( start, limit) = self . limits ( space) ;
393+ self . content . mut_slice ( start, limit)
338394 }
339395
340396 pub fn opt_get < ' a > ( & ' a self ,
341397 space : ParamSpace ,
342398 index : uint )
343399 -> Option < & ' a T > {
344- let v = self . get_vec ( space) ;
345- if index < v. len ( ) { Some ( v . get ( index) ) } else { None }
400+ let v = self . get_slice ( space) ;
401+ if index < v. len ( ) { Some ( & v [ index] ) } else { None }
346402 }
347403
348404 pub fn get < ' a > ( & ' a self , space : ParamSpace , index : uint ) -> & ' a T {
349- self . get_vec ( space) . get ( index)
405+ & self . get_slice ( space) [ index]
350406 }
351407
352408 pub fn get_mut < ' a > ( & ' a mut self ,
353409 space : ParamSpace ,
354410 index : uint ) -> & ' a mut T {
355- self . get_mut_vec ( space) . get_mut ( index)
411+ & mut self . get_mut_slice ( space) [ index]
356412 }
357413
358- pub fn iter < ' a > ( & ' a self ) -> Chain < Items < ' a , T > ,
359- Chain < Items < ' a , T > ,
360- Items < ' a , T > > > {
361- let ( ref r, ref s, ref f) = self . vecs ;
362- r. iter ( ) . chain ( s. iter ( ) . chain ( f. iter ( ) ) )
414+ pub fn iter < ' a > ( & ' a self ) -> Items < ' a , T > {
415+ self . content . iter ( )
363416 }
364417
365418 pub fn all_vecs ( & self , pred: |& [ T ] | -> bool) -> bool {
366- self . vecs . iter ( ) . map ( |v|v. as_slice ( ) ) . all ( pred)
419+ let spaces = [ TypeSpace , SelfSpace , FnSpace ] ;
420+ spaces. iter ( ) . all ( |& space| { pred ( self . get_slice ( space) ) } )
367421 }
368422
369423 pub fn all ( & self , pred: |& T | -> bool) -> bool {
@@ -379,9 +433,13 @@ impl<T> VecPerParamSpace<T> {
379433 }
380434
381435 pub fn map < U > ( & self , pred: |& T | -> U ) -> VecPerParamSpace < U > {
382- VecPerParamSpace :: new ( self . vecs . ref0 ( ) . iter ( ) . map ( |p| pred ( p) ) . collect ( ) ,
383- self . vecs . ref1 ( ) . iter ( ) . map ( |p| pred ( p) ) . collect ( ) ,
384- self . vecs . ref2 ( ) . iter ( ) . map ( |p| pred ( p) ) . collect ( ) )
436+ // FIXME (#15418): this could avoid allocating the intermediate
437+ // Vec's, but note that the values of type_limit and self_limit
438+ // also need to be kept in sync during construction.
439+ VecPerParamSpace :: new (
440+ self . get_slice ( TypeSpace ) . iter ( ) . map ( |p| pred ( p) ) . collect ( ) ,
441+ self . get_slice ( SelfSpace ) . iter ( ) . map ( |p| pred ( p) ) . collect ( ) ,
442+ self . get_slice ( FnSpace ) . iter ( ) . map ( |p| pred ( p) ) . collect ( ) )
385443 }
386444
387445 pub fn map_rev < U > ( & self , pred: |& T | -> U ) -> VecPerParamSpace < U > {
@@ -394,29 +452,46 @@ impl<T> VecPerParamSpace<T> {
394452 * can be run to a fixed point
395453 */
396454
397- let mut fns: Vec < U > = self . vecs . ref2 ( ) . iter ( ) . rev ( ) . map ( |p| pred ( p) ) . collect ( ) ;
455+ let mut fns: Vec < U > = self . get_slice ( FnSpace ) . iter ( ) . rev ( ) . map ( |p| pred ( p) ) . collect ( ) ;
398456
399457 // NB: Calling foo.rev().map().rev() causes the calls to map
400458 // to occur in the wrong order. This was somewhat surprising
401459 // to me, though it makes total sense.
402460 fns. reverse ( ) ;
403461
404- let mut selfs: Vec < U > = self . vecs . ref1 ( ) . iter ( ) . rev ( ) . map ( |p| pred ( p) ) . collect ( ) ;
462+ let mut selfs: Vec < U > = self . get_slice ( SelfSpace ) . iter ( ) . rev ( ) . map ( |p| pred ( p) ) . collect ( ) ;
405463 selfs. reverse ( ) ;
406- let mut tys: Vec < U > = self . vecs . ref0 ( ) . iter ( ) . rev ( ) . map ( |p| pred ( p) ) . collect ( ) ;
464+ let mut tys: Vec < U > = self . get_slice ( TypeSpace ) . iter ( ) . rev ( ) . map ( |p| pred ( p) ) . collect ( ) ;
407465 tys. reverse ( ) ;
408466 VecPerParamSpace :: new ( tys, selfs, fns)
409467 }
410468
411469 pub fn split ( self ) -> ( Vec < T > , Vec < T > , Vec < T > ) {
412- self . vecs
470+ // FIXME (#15418): this does two traversals when in principle
471+ // one would suffice. i.e. change to use `move_iter`.
472+ let VecPerParamSpace { type_limit, self_limit, content } = self ;
473+ let mut i = 0 ;
474+ let ( prefix, fn_vec) = content. partition ( |_| {
475+ let on_left = i < self_limit;
476+ i += 1 ;
477+ on_left
478+ } ) ;
479+
480+ let mut i = 0 ;
481+ let ( type_vec, self_vec) = prefix. partition ( |_| {
482+ let on_left = i < type_limit;
483+ i += 1 ;
484+ on_left
485+ } ) ;
486+
487+ ( type_vec, self_vec, fn_vec)
413488 }
414489
415490 pub fn with_vec ( mut self , space : ParamSpace , vec : Vec < T > )
416491 -> VecPerParamSpace < T >
417492 {
418- assert ! ( self . get_vec ( space) . is_empty ( ) ) ;
419- * self . get_mut_vec ( space) = vec;
493+ assert ! ( self . is_empty_in ( space) ) ;
494+ self . replace ( space, vec) ;
420495 self
421496 }
422497}
0 commit comments