@@ -681,23 +681,31 @@ impl<'a> TyLoweringContext<'a> {
681
681
682
682
let ty_error = GenericArgData :: Ty ( TyKind :: Error . intern ( Interner ) ) . intern ( Interner ) ;
683
683
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
+ }
689
693
}
690
694
}
691
695
}
692
696
693
697
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
+ }
701
709
} ;
702
710
let mut had_explicit_args = false ;
703
711
@@ -712,34 +720,38 @@ impl<'a> TyLoweringContext<'a> {
712
720
} ;
713
721
let skip = if generic_args. has_self_type && self_params == 0 { 1 } else { 0 } ;
714
722
// 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
716
724
. args
717
725
. iter ( )
718
726
. filter ( |arg| !matches ! ( arg, GenericArg :: Lifetime ( _) ) )
719
727
. skip ( skip)
720
728
. take ( expected_num)
721
- . zip ( def_generics. iter_id ( ) . skip ( parent_params + skip) )
722
729
{
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
+ }
743
755
}
744
756
}
745
757
} else {
@@ -757,21 +769,24 @@ impl<'a> TyLoweringContext<'a> {
757
769
for default_ty in defaults. iter ( ) . skip ( substs. len ( ) ) {
758
770
// each default can depend on the previous parameters
759
771
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
+ }
761
775
}
762
776
}
763
777
}
764
778
765
779
// add placeholders for args that were not provided
766
780
// 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 {
768
782
match eid {
769
783
Either :: Left ( _) => substs. push ( ty_error. clone ( ) ) ,
770
784
Either :: Right ( x) => {
771
785
substs. push ( unknown_const_as_generic ( self . db . const_param_ty ( x) ) )
772
786
}
773
787
}
774
788
}
789
+ // If this assert fails, it means you pushed into subst but didn't call .next() of def_generic_iter
775
790
assert_eq ! ( substs. len( ) , total_len) ;
776
791
777
792
Substitution :: from_iter ( Interner , substs)
@@ -1659,6 +1674,10 @@ pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mut
1659
1674
}
1660
1675
}
1661
1676
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.
1662
1681
pub ( crate ) fn generic_arg_to_chalk < ' a , T > (
1663
1682
db : & dyn HirDatabase ,
1664
1683
kind_id : Either < TypeParamId , ConstParamId > ,
0 commit comments