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,81 @@ 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
+ & self
262
254
}
263
255
264
256
#[ inline]
265
257
pub fn types ( & ' a self ) -> impl DoubleEndedIterator < Item =Ty < ' tcx > > + ' a {
266
- self . params . iter ( ) . filter_map ( |k| k. as_type ( ) )
258
+ self . iter ( ) . filter_map ( |k| k. as_type ( ) )
267
259
}
268
260
269
261
#[ inline]
270
262
pub fn regions ( & ' a self ) -> impl DoubleEndedIterator < Item =& ' tcx ty:: Region > + ' a {
271
- self . params . iter ( ) . filter_map ( |k| k. as_region ( ) )
263
+ self . iter ( ) . filter_map ( |k| k. as_region ( ) )
272
264
}
273
265
274
266
#[ inline]
275
267
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 ) ;
268
+ self [ i] . as_type ( ) . unwrap_or_else ( || {
269
+ bug ! ( "expected type for param #{} in {:?}" , i, self ) ;
278
270
} )
279
271
}
280
272
281
273
#[ inline]
282
274
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 ) ;
275
+ self [ i] . as_region ( ) . unwrap_or_else ( || {
276
+ bug ! ( "expected region for param #{} in {:?}" , i, self ) ;
285
277
} )
286
278
}
287
279
@@ -305,27 +297,22 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
305
297
target_substs : & Substs < ' tcx > )
306
298
-> & ' tcx Substs < ' tcx > {
307
299
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
- } )
300
+ Substs :: new ( tcx, target_substs. iter ( ) . chain ( & self [ defs. own_count ( ) ..] ) . cloned ( ) )
312
301
}
313
302
}
314
303
315
304
impl < ' tcx > TypeFoldable < ' tcx > for & ' tcx Substs < ' tcx > {
316
305
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
- } )
306
+ let params = self . iter ( ) . map ( |k| k. fold_with ( folder) ) . collect ( ) ;
307
+ folder. tcx ( ) . mk_substs ( params)
321
308
}
322
309
323
310
fn fold_with < ' gcx : ' tcx , F : TypeFolder < ' gcx , ' tcx > > ( & self , folder : & mut F ) -> Self {
324
311
folder. fold_substs ( self )
325
312
}
326
313
327
314
fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
328
- self . params . visit_with ( visitor)
315
+ self . iter ( ) . any ( |t| t . visit_with ( visitor) )
329
316
}
330
317
}
331
318
@@ -340,19 +327,19 @@ impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Substs<'tcx> {}
340
327
341
328
pub trait Subst < ' tcx > : Sized {
342
329
fn subst < ' a , ' gcx > ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
343
- substs : & Substs < ' tcx > ) -> Self {
330
+ substs : & [ Kind < ' tcx > ] ) -> Self {
344
331
self . subst_spanned ( tcx, substs, None )
345
332
}
346
333
347
334
fn subst_spanned < ' a , ' gcx > ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
348
- substs : & Substs < ' tcx > ,
335
+ substs : & [ Kind < ' tcx > ] ,
349
336
span : Option < Span > )
350
337
-> Self ;
351
338
}
352
339
353
340
impl < ' tcx , T : TypeFoldable < ' tcx > > Subst < ' tcx > for T {
354
341
fn subst_spanned < ' a , ' gcx > ( & self , tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
355
- substs : & Substs < ' tcx > ,
342
+ substs : & [ Kind < ' tcx > ] ,
356
343
span : Option < Span > )
357
344
-> T
358
345
{
@@ -371,7 +358,7 @@ impl<'tcx, T:TypeFoldable<'tcx>> Subst<'tcx> for T {
371
358
372
359
struct SubstFolder < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
373
360
tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
374
- substs : & ' a Substs < ' tcx > ,
361
+ substs : & ' a [ Kind < ' tcx > ] ,
375
362
376
363
// The location for which the substitution is performed, if available.
377
364
span : Option < Span > ,
@@ -404,7 +391,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
404
391
// the specialized routine `ty::replace_late_regions()`.
405
392
match * r {
406
393
ty:: ReEarlyBound ( data) => {
407
- let r = self . substs . params . get ( data. index as usize )
394
+ let r = self . substs . get ( data. index as usize )
408
395
. and_then ( |k| k. as_region ( ) ) ;
409
396
match r {
410
397
Some ( r) => {
@@ -461,7 +448,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
461
448
impl < ' a , ' gcx , ' tcx > SubstFolder < ' a , ' gcx , ' tcx > {
462
449
fn ty_for_param ( & self , p : ty:: ParamTy , source_ty : Ty < ' tcx > ) -> Ty < ' tcx > {
463
450
// 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 )
451
+ let opt_ty = self . substs . get ( p. idx as usize )
465
452
. and_then ( |k| k. as_type ( ) ) ;
466
453
let ty = match opt_ty {
467
454
Some ( t) => t,
@@ -475,7 +462,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
475
462
source_ty,
476
463
p. idx,
477
464
self . root_ty,
478
- self . substs. params ) ;
465
+ self . substs) ;
479
466
}
480
467
} ;
481
468
@@ -552,7 +539,7 @@ impl<'a, 'gcx, 'tcx> ty::TraitRef<'tcx> {
552
539
-> ty:: TraitRef < ' tcx > {
553
540
let defs = tcx. lookup_generics ( trait_id) ;
554
541
555
- let params = substs. params [ ..defs. own_count ( ) ] . iter ( ) . cloned ( ) ;
542
+ let params = substs[ ..defs. own_count ( ) ] . iter ( ) . cloned ( ) ;
556
543
ty:: TraitRef {
557
544
def_id : trait_id,
558
545
substs : Substs :: new ( tcx, params)
@@ -567,7 +554,7 @@ impl<'a, 'gcx, 'tcx> ty::ExistentialTraitRef<'tcx> {
567
554
// Assert there is a Self.
568
555
trait_ref. substs . type_at ( 0 ) ;
569
556
570
- let params = trait_ref. substs . params [ 1 ..] . iter ( ) . cloned ( ) ;
557
+ let params = trait_ref. substs [ 1 ..] . iter ( ) . cloned ( ) ;
571
558
ty:: ExistentialTraitRef {
572
559
def_id : trait_ref. def_id ,
573
560
substs : Substs :: new ( tcx, params)
@@ -587,7 +574,7 @@ impl<'a, 'gcx, 'tcx> ty::PolyExistentialTraitRef<'tcx> {
587
574
assert ! ( !self_ty. has_escaping_regions( ) ) ;
588
575
589
576
self . map_bound ( |trait_ref| {
590
- let params = trait_ref. substs . params . iter ( ) . cloned ( ) ;
577
+ let params = trait_ref. substs . iter ( ) . cloned ( ) ;
591
578
let params = iter:: once ( Kind :: from ( self_ty) ) . chain ( params) ;
592
579
ty:: TraitRef {
593
580
def_id : trait_ref. def_id ,
0 commit comments