@@ -15,7 +15,6 @@ use middle::ty_fold;
15
15
use middle:: ty_fold:: { TypeFoldable , TypeFolder } ;
16
16
use util:: ppaux:: Repr ;
17
17
18
- use std:: iter:: Chain ;
19
18
use std:: mem;
20
19
use std:: raw;
21
20
use std:: slice:: { Items , MutItems } ;
@@ -191,8 +190,8 @@ impl Substs {
191
190
}
192
191
193
192
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 ) ) )
196
195
}
197
196
198
197
pub fn with_method ( self ,
@@ -261,19 +260,44 @@ impl ParamSpace {
261
260
*/
262
261
#[ deriving( PartialEq , Eq , Clone , Hash , Encodable , Decodable ) ]
263
262
pub 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 > ,
265
276
}
266
277
267
278
impl < T : Clone > VecPerParamSpace < T > {
268
279
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
+ }
270
284
}
271
285
}
272
286
273
287
impl < 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
+
274
296
pub fn empty ( ) -> VecPerParamSpace < T > {
275
297
VecPerParamSpace {
276
- vecs : ( Vec :: new ( ) , Vec :: new ( ) , Vec :: new ( ) )
298
+ type_limit : 0 ,
299
+ self_limit : 0 ,
300
+ content : Vec :: new ( )
277
301
}
278
302
}
279
303
@@ -282,8 +306,15 @@ impl<T> VecPerParamSpace<T> {
282
306
}
283
307
284
308
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) ;
285
314
VecPerParamSpace {
286
- vecs : ( t, s, f)
315
+ type_limit : type_limit,
316
+ self_limit : self_limit,
317
+ content : content,
287
318
}
288
319
}
289
320
@@ -295,75 +326,98 @@ impl<T> VecPerParamSpace<T> {
295
326
result
296
327
}
297
328
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).
298
333
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) ;
300
341
}
301
342
302
343
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
+ }
304
355
}
305
356
306
357
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
+ }
308
362
}
309
363
310
364
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
+ }
312
370
}
313
371
314
372
pub fn get_self < ' a > ( & ' a self ) -> Option < & ' a T > {
315
- let v = self . get_vec ( SelfSpace ) ;
373
+ let v = self . get_slice ( SelfSpace ) ;
316
374
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 ] ) }
318
376
}
319
377
320
378
pub fn len ( & self , space : ParamSpace ) -> uint {
321
- self . get_vec ( space) . len ( )
379
+ self . get_slice ( space) . len ( )
322
380
}
323
381
324
382
pub fn is_empty_in ( & self , space : ParamSpace ) -> bool {
325
- self . get_vec ( space ) . len ( ) == 0
383
+ self . len ( space ) == 0
326
384
}
327
385
328
386
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)
334
389
}
335
390
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)
338
394
}
339
395
340
396
pub fn opt_get < ' a > ( & ' a self ,
341
397
space : ParamSpace ,
342
398
index : uint )
343
399
-> 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 }
346
402
}
347
403
348
404
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]
350
406
}
351
407
352
408
pub fn get_mut < ' a > ( & ' a mut self ,
353
409
space : ParamSpace ,
354
410
index : uint ) -> & ' a mut T {
355
- self . get_mut_vec ( space) . get_mut ( index)
411
+ & mut self . get_mut_slice ( space) [ index]
356
412
}
357
413
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 ( )
363
416
}
364
417
365
418
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) ) } )
367
421
}
368
422
369
423
pub fn all ( & self , pred: |& T | -> bool) -> bool {
@@ -379,9 +433,13 @@ impl<T> VecPerParamSpace<T> {
379
433
}
380
434
381
435
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 ( ) )
385
443
}
386
444
387
445
pub fn map_rev < U > ( & self , pred: |& T | -> U ) -> VecPerParamSpace < U > {
@@ -394,29 +452,46 @@ impl<T> VecPerParamSpace<T> {
394
452
* can be run to a fixed point
395
453
*/
396
454
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 ( ) ;
398
456
399
457
// NB: Calling foo.rev().map().rev() causes the calls to map
400
458
// to occur in the wrong order. This was somewhat surprising
401
459
// to me, though it makes total sense.
402
460
fns. reverse ( ) ;
403
461
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 ( ) ;
405
463
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 ( ) ;
407
465
tys. reverse ( ) ;
408
466
VecPerParamSpace :: new ( tys, selfs, fns)
409
467
}
410
468
411
469
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)
413
488
}
414
489
415
490
pub fn with_vec ( mut self , space : ParamSpace , vec : Vec < T > )
416
491
-> VecPerParamSpace < T >
417
492
{
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) ;
420
495
self
421
496
}
422
497
}
0 commit comments