@@ -112,17 +112,17 @@ impl Substs {
112
112
r : Vec < ty:: Region > )
113
113
-> Substs
114
114
{
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 ( ) ) )
117
117
}
118
118
119
119
pub fn new_trait ( t : Vec < ty:: t > ,
120
120
r : Vec < ty:: Region > ,
121
121
s : ty:: t )
122
122
-> Substs
123
123
{
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 ( ) ) )
126
126
}
127
127
128
128
pub fn erased ( t : VecPerParamSpace < ty:: t > ) -> Substs
@@ -226,29 +226,32 @@ impl RegionSubsts {
226
226
#[ deriving( PartialOrd , Ord , PartialEq , Eq ,
227
227
Clone , Hash , Encodable , Decodable , Show ) ]
228
228
pub 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
232
233
}
233
234
234
235
impl ParamSpace {
235
- pub fn all ( ) -> [ ParamSpace , ..3 ] {
236
- [ TypeSpace , SelfSpace , FnSpace ]
236
+ pub fn all ( ) -> [ ParamSpace , ..4 ] {
237
+ [ TypeSpace , SelfSpace , AssocSpace , FnSpace ]
237
238
}
238
239
239
240
pub fn to_uint ( self ) -> uint {
240
241
match self {
241
242
TypeSpace => 0 ,
242
243
SelfSpace => 1 ,
243
- FnSpace => 2 ,
244
+ AssocSpace => 2 ,
245
+ FnSpace => 3 ,
244
246
}
245
247
}
246
248
247
249
pub fn from_uint ( u : uint ) -> ParamSpace {
248
250
match u {
249
251
0 => TypeSpace ,
250
252
1 => SelfSpace ,
251
- 2 => FnSpace ,
253
+ 2 => AssocSpace ,
254
+ 3 => FnSpace ,
252
255
_ => panic ! ( "Invalid ParamSpace: {}" , u)
253
256
}
254
257
}
@@ -268,11 +271,13 @@ pub struct VecPerParamSpace<T> {
268
271
// Here is how the representation corresponds to the abstraction
269
272
// i.e. the "abstraction function" AF:
270
273
//
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..])
274
278
type_limit : uint ,
275
279
self_limit : uint ,
280
+ assoc_limit : uint ,
276
281
content : Vec < T > ,
277
282
}
278
283
@@ -292,14 +297,16 @@ impl<T> VecPerParamSpace<T> {
292
297
match space {
293
298
TypeSpace => ( 0 , self . type_limit ) ,
294
299
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 ( ) ) ,
296
302
}
297
303
}
298
304
299
305
pub fn empty ( ) -> VecPerParamSpace < T > {
300
306
VecPerParamSpace {
301
307
type_limit : 0 ,
302
308
self_limit : 0 ,
309
+ assoc_limit : 0 ,
303
310
content : Vec :: new ( )
304
311
}
305
312
}
@@ -310,26 +317,33 @@ impl<T> VecPerParamSpace<T> {
310
317
311
318
/// `t` is the type space.
312
319
/// `s` is the self space.
320
+ /// `a` is the assoc space.
313
321
/// `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 > {
315
323
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
+
317
327
let mut content = t;
318
328
content. extend ( s. into_iter ( ) ) ;
329
+ content. extend ( a. into_iter ( ) ) ;
319
330
content. extend ( f. into_iter ( ) ) ;
331
+
320
332
VecPerParamSpace {
321
333
type_limit : type_limit,
322
334
self_limit : self_limit,
335
+ assoc_limit : assoc_limit,
323
336
content : content,
324
337
}
325
338
}
326
339
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 )
328
341
-> VecPerParamSpace < T >
329
342
{
330
343
VecPerParamSpace {
331
344
type_limit : type_limit,
332
345
self_limit : self_limit,
346
+ assoc_limit : assoc_limit,
333
347
content : content,
334
348
}
335
349
}
@@ -341,9 +355,10 @@ impl<T> VecPerParamSpace<T> {
341
355
pub fn push ( & mut self , space : ParamSpace , value : T ) {
342
356
let ( _, limit) = self . limits ( space) ;
343
357
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 => { }
347
362
}
348
363
self . content . insert ( limit, value) ;
349
364
}
@@ -354,9 +369,10 @@ impl<T> VecPerParamSpace<T> {
354
369
None
355
370
} else {
356
371
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 => { }
360
376
}
361
377
self . content . remove ( limit - 1 )
362
378
}
@@ -442,35 +458,29 @@ impl<T> VecPerParamSpace<T> {
442
458
let result = self . iter ( ) . map ( pred) . collect ( ) ;
443
459
VecPerParamSpace :: new_internal ( result,
444
460
self . type_limit ,
445
- self . self_limit )
461
+ self . self_limit ,
462
+ self . assoc_limit )
446
463
}
447
464
448
465
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 ( ) ;
450
467
VecPerParamSpace :: new ( t. into_iter ( ) . map ( |p| pred ( p) ) . collect ( ) ,
451
468
s. into_iter ( ) . map ( |p| pred ( p) ) . collect ( ) ,
469
+ a. into_iter ( ) . map ( |p| pred ( p) ) . collect ( ) ,
452
470
f. into_iter ( ) . map ( |p| pred ( p) ) . collect ( ) )
453
471
}
454
472
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 ( ) ;
465
477
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 ( ) ;
472
482
473
- ( type_vec , self_vec , fn_vec )
483
+ ( types , selfs , assocs , fns )
474
484
}
475
485
476
486
pub fn with_vec ( mut self , space : ParamSpace , vec : Vec < T > )
@@ -616,12 +626,13 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
616
626
this. tcx ( ) . sess . span_bug (
617
627
span,
618
628
format ! ( "Type parameter `{}` ({}/{}/{}) out of range \
619
- when substituting (root type={})",
629
+ when substituting (root type={}) substs={} ",
620
630
p. repr( this. tcx( ) ) ,
621
631
source_ty. repr( this. tcx( ) ) ,
622
632
space,
623
633
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 ( ) ) ;
625
636
}
626
637
}
627
638
}
0 commit comments