@@ -19,7 +19,7 @@ use hir_def::{
1919 lang_item:: LangItem ,
2020 resolver:: { HasResolver , TypeNs } ,
2121 type_ref:: { TraitBoundModifier , TypeRef } ,
22- ConstParamId , EnumId , EnumVariantId , FunctionId , GenericDefId , ItemContainerId ,
22+ ConstParamId , EnumId , EnumVariantId , FunctionId , GenericDefId , GenericParamId , ItemContainerId ,
2323 LifetimeParamId , Lookup , OpaqueInternableThing , TraitId , TypeAliasId , TypeOrConstParamId ,
2424 TypeParamId ,
2525} ;
@@ -311,10 +311,48 @@ impl Generics {
311311 } )
312312 }
313313
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+
314352 /// Returns total number of generic parameters in scope, including those from parent.
315353 pub ( crate ) fn len ( & self ) -> usize {
316354 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 ( ) ;
318356 parent + child
319357 }
320358
@@ -396,11 +434,16 @@ impl Generics {
396434 ) -> Substitution {
397435 Substitution :: from_iter (
398436 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)
402439 . to_const ( Interner , db. const_param_ty ( id) )
403440 . 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+ }
404447 } ) ,
405448 )
406449 }
0 commit comments