@@ -19,7 +19,7 @@ use hir_def::{
19
19
lang_item:: LangItem ,
20
20
resolver:: { HasResolver , TypeNs } ,
21
21
type_ref:: { TraitBoundModifier , TypeRef } ,
22
- ConstParamId , EnumId , EnumVariantId , FunctionId , GenericDefId , ItemContainerId ,
22
+ ConstParamId , EnumId , EnumVariantId , FunctionId , GenericDefId , GenericParamId , ItemContainerId ,
23
23
LifetimeParamId , Lookup , OpaqueInternableThing , TraitId , TypeAliasId , TypeOrConstParamId ,
24
24
TypeParamId ,
25
25
} ;
@@ -311,10 +311,48 @@ impl Generics {
311
311
} )
312
312
}
313
313
314
+ pub ( crate ) fn iter_id_with_lt ( & self ) -> impl Iterator < Item = GenericParamId > + ' _ {
315
+ let toc_iter = self . iter ( ) . map ( |( id, data) | match data {
316
+ TypeOrConstParamData :: TypeParamData ( _) => {
317
+ GenericParamId :: TypeParamId ( TypeParamId :: from_unchecked ( id) )
318
+ }
319
+ TypeOrConstParamData :: ConstParamData ( _) => {
320
+ GenericParamId :: ConstParamId ( ConstParamId :: from_unchecked ( id) )
321
+ }
322
+ } ) ;
323
+ let lt_iter = self . iter_lt ( ) . map ( |( id, _) | GenericParamId :: LifetimeParamId ( id) ) ;
324
+
325
+ toc_iter. chain ( lt_iter)
326
+ }
327
+
328
+ pub ( crate ) fn iter_lt < ' a > (
329
+ & ' a self ,
330
+ ) -> impl DoubleEndedIterator < Item = ( LifetimeParamId , & ' a LifetimeParamData ) > + ' a {
331
+ self . iter_lt_self ( ) . chain ( self . iter_lt_parent ( ) )
332
+ }
333
+
334
+ fn iter_lt_self < ' a > (
335
+ & ' a self ,
336
+ ) -> impl DoubleEndedIterator < Item = ( LifetimeParamId , & ' a LifetimeParamData ) > + ' a {
337
+ let to_id = |it : & ' a Generics | {
338
+ move |( local_id, p) | ( LifetimeParamId { parent : it. def , local_id } , p)
339
+ } ;
340
+ self . params . iter_lt ( ) . map ( to_id ( self ) )
341
+ }
342
+
343
+ fn iter_lt_parent (
344
+ & self ,
345
+ ) -> impl DoubleEndedIterator < Item = ( LifetimeParamId , & LifetimeParamData ) > {
346
+ self . parent_generics ( ) . into_iter ( ) . flat_map ( |it| {
347
+ let to_id = move |( local_id, p) | ( LifetimeParamId { parent : it. def , local_id } , p) ;
348
+ it. params . iter_lt ( ) . map ( to_id)
349
+ } )
350
+ }
351
+
314
352
/// Returns total number of generic parameters in scope, including those from parent.
315
353
pub ( crate ) fn len ( & self ) -> usize {
316
354
let parent = self . parent_generics ( ) . map_or ( 0 , Generics :: len) ;
317
- let child = self . params . type_or_consts . len ( ) ;
355
+ let child = self . params . type_or_consts . len ( ) + self . params . lifetimes . len ( ) ;
318
356
parent + child
319
357
}
320
358
@@ -396,11 +434,16 @@ impl Generics {
396
434
) -> Substitution {
397
435
Substitution :: from_iter (
398
436
Interner ,
399
- self . iter_id ( ) . enumerate ( ) . map ( |( idx, id) | match id {
400
- Either :: Left ( _) => BoundVar :: new ( debruijn, idx) . to_ty ( Interner ) . cast ( Interner ) ,
401
- Either :: Right ( id) => BoundVar :: new ( debruijn, idx)
437
+ self . iter_id_with_lt ( ) . enumerate ( ) . map ( |( idx, id) | match id {
438
+ GenericParamId :: ConstParamId ( id) => BoundVar :: new ( debruijn, idx)
402
439
. to_const ( Interner , db. const_param_ty ( id) )
403
440
. cast ( Interner ) ,
441
+ GenericParamId :: TypeParamId ( _) => {
442
+ BoundVar :: new ( debruijn, idx) . to_ty ( Interner ) . cast ( Interner )
443
+ }
444
+ GenericParamId :: LifetimeParamId ( _) => {
445
+ BoundVar :: new ( debruijn, idx) . to_lifetime ( Interner ) . cast ( Interner )
446
+ }
404
447
} ) ,
405
448
)
406
449
}
0 commit comments