11
11
// Type substitutions.
12
12
13
13
use hir:: def_id:: DefId ;
14
- use ty:: { self , Ty , TyCtxt } ;
14
+ use ty:: { self , Slice , Ty , TyCtxt } ;
15
15
use ty:: fold:: { TypeFoldable , TypeFolder , TypeVisitor } ;
16
16
17
17
use serialize:: { self , Encodable , Encoder , Decodable , Decoder } ;
@@ -161,26 +161,19 @@ impl<'tcx> Decodable for Kind<'tcx> {
161
161
}
162
162
163
163
/// 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 > > ;
168
165
169
166
impl < ' a , ' gcx , ' tcx > Substs < ' tcx > {
170
167
pub fn new < I > ( tcx : TyCtxt < ' a , ' gcx , ' tcx > , params : I )
171
168
-> & ' tcx Substs < ' tcx >
172
169
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 ( ) )
176
171
}
177
172
178
173
pub fn maybe_new < I , E > ( tcx : TyCtxt < ' a , ' gcx , ' tcx > , params : I )
179
174
-> Result < & ' tcx Substs < ' tcx > , E >
180
175
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 < _ > , _ > > ( ) ?) )
184
177
}
185
178
186
179
pub fn new_trait ( tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
@@ -193,7 +186,7 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
193
186
}
194
187
195
188
pub fn empty ( tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> & ' tcx Substs < ' tcx > {
196
- Substs :: new ( tcx, vec ! [ ] )
189
+ Substs :: new ( tcx, iter :: empty ( ) )
197
190
}
198
191
199
192
/// Creates a Substs for generic parameter definitions,
@@ -206,82 +199,82 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
206
199
mut mk_region : FR ,
207
200
mut mk_type : FT )
208
201
-> & ' 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 > {
211
204
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 ( ) ) ;
215
206
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) ;
217
208
218
- tcx . mk_substs ( substs)
209
+ Substs :: new ( tcx , substs)
219
210
}
220
211
221
- fn fill_item < FR , FT > ( & mut self ,
212
+ fn fill_item < FR , FT > ( substs : & mut Vec < Kind < ' tcx > > ,
222
213
tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
223
214
defs : & ty:: Generics < ' tcx > ,
224
215
mk_region : & mut FR ,
225
216
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
+
228
220
if let Some ( def_id) = defs. parent {
229
221
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) ;
231
223
}
232
224
233
225
// Handle Self first, before all regions.
234
226
let mut types = defs. types . iter ( ) ;
235
227
if defs. parent . is_none ( ) && defs. has_self {
236
228
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) ) ;
240
232
}
241
233
242
234
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) ) ;
246
238
}
247
239
248
240
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) ) ;
252
244
}
253
245
}
254
246
255
247
pub fn is_noop ( & self ) -> bool {
256
- self . params . is_empty ( )
248
+ self . is_empty ( )
257
249
}
258
250
259
251
#[ inline]
260
252
pub fn params ( & self ) -> & [ Kind < ' tcx > ] {
261
- & self . params
253
+ // FIXME (dikaiosune) this should be removed, and corresponding compilation errors fixed
254
+ self
262
255
}
263
256
264
257
#[ inline]
265
258
pub fn types ( & ' a self ) -> impl DoubleEndedIterator < Item =Ty < ' tcx > > + ' a {
266
- self . params . iter ( ) . filter_map ( |k| k. as_type ( ) )
259
+ self . iter ( ) . filter_map ( |k| k. as_type ( ) )
267
260
}
268
261
269
262
#[ inline]
270
263
pub fn regions ( & ' a self ) -> impl DoubleEndedIterator < Item =& ' tcx ty:: Region > + ' a {
271
- self . params . iter ( ) . filter_map ( |k| k. as_region ( ) )
264
+ self . iter ( ) . filter_map ( |k| k. as_region ( ) )
272
265
}
273
266
274
267
#[ inline]
275
268
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 ) ;
269
+ self [ i] . as_type ( ) . unwrap_or_else ( || {
270
+ bug ! ( "expected type for param #{} in {:?}" , i, self ) ;
278
271
} )
279
272
}
280
273
281
274
#[ inline]
282
275
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 ) ;
276
+ self [ i] . as_region ( ) . unwrap_or_else ( || {
277
+ bug ! ( "expected region for param #{} in {:?}" , i, self ) ;
285
278
} )
286
279
}
287
280
@@ -305,27 +298,22 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
305
298
target_substs : & Substs < ' tcx > )
306
299
-> & ' tcx Substs < ' tcx > {
307
300
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
- } )
301
+ Substs :: new ( tcx, target_substs. iter ( ) . chain ( & self [ defs. own_count ( ) ..] ) . cloned ( ) )
312
302
}
313
303
}
314
304
315
305
impl < ' tcx > TypeFoldable < ' tcx > for & ' tcx Substs < ' tcx > {
316
306
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
- } )
307
+ let params = self . iter ( ) . map ( |k| k. fold_with ( folder) ) . collect ( ) ;
308
+ folder. tcx ( ) . mk_substs ( params)
321
309
}
322
310
323
311
fn fold_with < ' gcx : ' tcx , F : TypeFolder < ' gcx , ' tcx > > ( & self , folder : & mut F ) -> Self {
324
312
folder. fold_substs ( self )
325
313
}
326
314
327
315
fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
328
- self . params . visit_with ( visitor)
316
+ self . iter ( ) . any ( |t| t . visit_with ( visitor) )
329
317
}
330
318
}
331
319
@@ -340,19 +328,19 @@ impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Substs<'tcx> {}
340
328
341
329
pub trait Subst < ' tcx > : Sized {
342
330
fn subst < ' a , ' gcx > ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
343
- substs : & Substs < ' tcx > ) -> Self {
331
+ substs : & [ Kind < ' tcx > ] ) -> Self {
344
332
self . subst_spanned ( tcx, substs, None )
345
333
}
346
334
347
335
fn subst_spanned < ' a , ' gcx > ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
348
- substs : & Substs < ' tcx > ,
336
+ substs : & [ Kind < ' tcx > ] ,
349
337
span : Option < Span > )
350
338
-> Self ;
351
339
}
352
340
353
341
impl < ' tcx , T : TypeFoldable < ' tcx > > Subst < ' tcx > for T {
354
342
fn subst_spanned < ' a , ' gcx > ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
355
- substs : & Substs < ' tcx > ,
343
+ substs : & [ Kind < ' tcx > ] ,
356
344
span : Option < Span > )
357
345
-> T
358
346
{
@@ -371,7 +359,7 @@ impl<'tcx, T:TypeFoldable<'tcx>> Subst<'tcx> for T {
371
359
372
360
struct SubstFolder < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
373
361
tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
374
- substs : & ' a Substs < ' tcx > ,
362
+ substs : & ' a [ Kind < ' tcx > ] ,
375
363
376
364
// The location for which the substitution is performed, if available.
377
365
span : Option < Span > ,
@@ -404,7 +392,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
404
392
// the specialized routine `ty::replace_late_regions()`.
405
393
match * r {
406
394
ty:: ReEarlyBound ( data) => {
407
- let r = self . substs . params . get ( data. index as usize )
395
+ let r = self . substs . get ( data. index as usize )
408
396
. and_then ( |k| k. as_region ( ) ) ;
409
397
match r {
410
398
Some ( r) => {
@@ -461,7 +449,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
461
449
impl < ' a , ' gcx , ' tcx > SubstFolder < ' a , ' gcx , ' tcx > {
462
450
fn ty_for_param ( & self , p : ty:: ParamTy , source_ty : Ty < ' tcx > ) -> Ty < ' tcx > {
463
451
// 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 )
452
+ let opt_ty = self . substs . get ( p. idx as usize )
465
453
. and_then ( |k| k. as_type ( ) ) ;
466
454
let ty = match opt_ty {
467
455
Some ( t) => t,
@@ -475,7 +463,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
475
463
source_ty,
476
464
p. idx,
477
465
self . root_ty,
478
- self . substs. params ) ;
466
+ self . substs) ;
479
467
}
480
468
} ;
481
469
@@ -552,7 +540,7 @@ impl<'a, 'gcx, 'tcx> ty::TraitRef<'tcx> {
552
540
-> ty:: TraitRef < ' tcx > {
553
541
let defs = tcx. lookup_generics ( trait_id) ;
554
542
555
- let params = substs. params [ ..defs. own_count ( ) ] . iter ( ) . cloned ( ) ;
543
+ let params = substs[ ..defs. own_count ( ) ] . iter ( ) . cloned ( ) ;
556
544
ty:: TraitRef {
557
545
def_id : trait_id,
558
546
substs : Substs :: new ( tcx, params)
@@ -567,7 +555,7 @@ impl<'a, 'gcx, 'tcx> ty::ExistentialTraitRef<'tcx> {
567
555
// Assert there is a Self.
568
556
trait_ref. substs . type_at ( 0 ) ;
569
557
570
- let params = trait_ref. substs . params [ 1 ..] . iter ( ) . cloned ( ) ;
558
+ let params = trait_ref. substs [ 1 ..] . iter ( ) . cloned ( ) ;
571
559
ty:: ExistentialTraitRef {
572
560
def_id : trait_ref. def_id ,
573
561
substs : Substs :: new ( tcx, params)
@@ -587,7 +575,7 @@ impl<'a, 'gcx, 'tcx> ty::PolyExistentialTraitRef<'tcx> {
587
575
assert ! ( !self_ty. has_escaping_regions( ) ) ;
588
576
589
577
self . map_bound ( |trait_ref| {
590
- let params = trait_ref. substs . params . iter ( ) . cloned ( ) ;
578
+ let params = trait_ref. substs . iter ( ) . cloned ( ) ;
591
579
let params = iter:: once ( Kind :: from ( self_ty) ) . chain ( params) ;
592
580
ty:: TraitRef {
593
581
def_id : trait_ref. def_id ,
0 commit comments