@@ -681,23 +681,31 @@ impl<'a> TyLoweringContext<'a> {
681681
682682 let ty_error = GenericArgData :: Ty ( TyKind :: Error . intern ( Interner ) ) . intern ( Interner ) ;
683683
684- for eid in def_generics. iter_id ( ) . take ( parent_params) {
685- match eid {
686- Either :: Left ( _) => substs. push ( ty_error. clone ( ) ) ,
687- Either :: Right ( x) => {
688- substs. push ( unknown_const_as_generic ( self . db . const_param_ty ( x) ) )
684+ let mut def_generic_iter = def_generics. iter_id ( ) ;
685+
686+ for _ in 0 ..parent_params {
687+ if let Some ( eid) = def_generic_iter. next ( ) {
688+ match eid {
689+ Either :: Left ( _) => substs. push ( ty_error. clone ( ) ) ,
690+ Either :: Right ( x) => {
691+ substs. push ( unknown_const_as_generic ( self . db . const_param_ty ( x) ) )
692+ }
689693 }
690694 }
691695 }
692696
693697 let fill_self_params = || {
694- substs. extend (
695- explicit_self_ty
696- . into_iter ( )
697- . map ( |x| GenericArgData :: Ty ( x) . intern ( Interner ) )
698- . chain ( iter:: repeat ( ty_error. clone ( ) ) )
699- . take ( self_params) ,
700- )
698+ for x in explicit_self_ty
699+ . into_iter ( )
700+ . map ( |x| GenericArgData :: Ty ( x) . intern ( Interner ) )
701+ . chain ( iter:: repeat ( ty_error. clone ( ) ) )
702+ . take ( self_params)
703+ {
704+ if let Some ( id) = def_generic_iter. next ( ) {
705+ assert ! ( id. is_left( ) ) ;
706+ substs. push ( x) ;
707+ }
708+ }
701709 } ;
702710 let mut had_explicit_args = false ;
703711
@@ -712,34 +720,38 @@ impl<'a> TyLoweringContext<'a> {
712720 } ;
713721 let skip = if generic_args. has_self_type && self_params == 0 { 1 } else { 0 } ;
714722 // if args are provided, it should be all of them, but we can't rely on that
715- for ( arg, id ) in generic_args
723+ for arg in generic_args
716724 . args
717725 . iter ( )
718726 . filter ( |arg| !matches ! ( arg, GenericArg :: Lifetime ( _) ) )
719727 . skip ( skip)
720728 . take ( expected_num)
721- . zip ( def_generics. iter_id ( ) . skip ( parent_params + skip) )
722729 {
723- if let Some ( x) = generic_arg_to_chalk (
724- self . db ,
725- id,
726- arg,
727- & mut ( ) ,
728- |_, type_ref| self . lower_ty ( type_ref) ,
729- |_, c, ty| {
730- const_or_path_to_chalk (
731- self . db ,
732- & self . resolver ,
733- ty,
734- c,
735- self . type_param_mode ,
736- || self . generics ( ) ,
737- self . in_binders ,
738- )
739- } ,
740- ) {
741- had_explicit_args = true ;
742- substs. push ( x) ;
730+ if let Some ( id) = def_generic_iter. next ( ) {
731+ if let Some ( x) = generic_arg_to_chalk (
732+ self . db ,
733+ id,
734+ arg,
735+ & mut ( ) ,
736+ |_, type_ref| self . lower_ty ( type_ref) ,
737+ |_, c, ty| {
738+ const_or_path_to_chalk (
739+ self . db ,
740+ & self . resolver ,
741+ ty,
742+ c,
743+ self . type_param_mode ,
744+ || self . generics ( ) ,
745+ self . in_binders ,
746+ )
747+ } ,
748+ ) {
749+ had_explicit_args = true ;
750+ substs. push ( x) ;
751+ } else {
752+ // we just filtered them out
753+ never ! ( "Unexpected lifetime argument" ) ;
754+ }
743755 }
744756 }
745757 } else {
@@ -757,21 +769,24 @@ impl<'a> TyLoweringContext<'a> {
757769 for default_ty in defaults. iter ( ) . skip ( substs. len ( ) ) {
758770 // each default can depend on the previous parameters
759771 let substs_so_far = Substitution :: from_iter ( Interner , substs. clone ( ) ) ;
760- substs. push ( default_ty. clone ( ) . substitute ( Interner , & substs_so_far) ) ;
772+ if let Some ( _id) = def_generic_iter. next ( ) {
773+ substs. push ( default_ty. clone ( ) . substitute ( Interner , & substs_so_far) ) ;
774+ }
761775 }
762776 }
763777 }
764778
765779 // add placeholders for args that were not provided
766780 // FIXME: emit diagnostics in contexts where this is not allowed
767- for eid in def_generics . iter_id ( ) . skip ( substs . len ( ) ) {
781+ for eid in def_generic_iter {
768782 match eid {
769783 Either :: Left ( _) => substs. push ( ty_error. clone ( ) ) ,
770784 Either :: Right ( x) => {
771785 substs. push ( unknown_const_as_generic ( self . db . const_param_ty ( x) ) )
772786 }
773787 }
774788 }
789+ // If this assert fails, it means you pushed into subst but didn't call .next() of def_generic_iter
775790 assert_eq ! ( substs. len( ) , total_len) ;
776791
777792 Substitution :: from_iter ( Interner , substs)
@@ -1659,6 +1674,10 @@ pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mut
16591674 }
16601675}
16611676
1677+ /// Checks if the provided generic arg matches its expected kind, then lower them via
1678+ /// provided closures. Use unknown if there was kind mismatch.
1679+ ///
1680+ /// Returns `Some` of the lowered generic arg. `None` if the provided arg is a lifetime.
16621681pub ( crate ) fn generic_arg_to_chalk < ' a , T > (
16631682 db : & dyn HirDatabase ,
16641683 kind_id : Either < TypeParamId , ConstParamId > ,
0 commit comments