@@ -194,7 +194,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
194194 return self . generate_delegation_error ( span, delegation) ;
195195 }
196196
197- let mut generics = self . uplift_delegation_generics ( delegation, sig_id, is_method ) ;
197+ let mut generics = self . uplift_delegation_generics ( delegation, sig_id) ;
198198
199199 let ( body_id, call_expr_id, unused_target_expr) = self . lower_delegation_body (
200200 delegation,
@@ -404,10 +404,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
404404 hir:: InferDelegationSig :: Output ( self . arena . alloc ( hir:: DelegationInfo {
405405 call_expr_id,
406406 call_path_res : self . get_resolution_id ( call_path_node_id) ,
407- child_args_segment_id : generics. child . args_segment_id ,
408- parent_args_segment_id : generics. parent . args_segment_id ,
409- self_ty_id : generics. self_ty_id ,
410- propagate_self_ty : generics. propagate_self_ty ,
407+ child_seg_id : generics. child . args_segment_id ,
408+ child_seg_id_for_sig : generics. child . segment_id_for_sig ( ) ,
409+ parent_seg_id_for_sig : generics. parent . segment_id_for_sig ( ) ,
410+ self_ty_propagation_kind : generics. self_ty_propagation_kind ,
411411 group_id : {
412412 let id = match source {
413413 DelegationSource :: Single => None ,
@@ -625,20 +625,40 @@ impl<'hir> LoweringContext<'_, 'hir> {
625625 } ) ,
626626 ) ;
627627
628- hir:: QPath :: Resolved ( ty, self . arena . alloc ( new_path) )
629- }
630- hir:: QPath :: TypeRelative ( ty, segment) => {
631- let segment = self . process_segment ( span, segment, & mut generics. child ) ;
628+ // Explicitly create `Self` self-type in case of infers or static
629+ // free-to-trait reuses.
630+ let ty = match generics. self_ty_propagation_kind {
631+ Some ( hir:: DelegationSelfTyPropagationKind :: SelfParam ) => {
632+ let self_param = generics. parent . generics . find_self_param ( ) ;
633+ let path = self . create_generic_arg_path ( self_param) ;
634+ let kind = hir:: TyKind :: Path ( path) ;
635+
636+ let ty = match ty {
637+ Some ( ty) => hir:: Ty { kind, ..ty. clone ( ) } ,
638+ None => hir:: Ty { kind, hir_id : self . next_id ( ) , span } ,
639+ } ;
640+
641+ Some ( & * self . arena . alloc ( ty) )
642+ }
643+ _ => ty,
644+ } ;
632645
633- hir:: QPath :: TypeRelative ( ty, self . arena . alloc ( segment ) )
646+ hir:: QPath :: Resolved ( ty, self . arena . alloc ( new_path ) )
634647 }
648+ hir:: QPath :: TypeRelative ( ..) => unreachable ! ( "until inherent methods are supported" ) ,
635649 } ;
636650
637- generics. self_ty_id = match new_path {
638- hir:: QPath :: Resolved ( ty, _) => ty,
639- hir:: QPath :: TypeRelative ( ty, _) => Some ( ty) ,
651+ if let Some ( hir:: DelegationSelfTyPropagationKind :: SelfTy ( id) ) =
652+ generics. self_ty_propagation_kind . as_mut ( )
653+ {
654+ * id = match new_path {
655+ hir:: QPath :: Resolved ( ty, _) => {
656+ ty. expect ( "must contain self type as `SelfTy` propagation kind is specified" )
657+ }
658+ hir:: QPath :: TypeRelative ( ty, _) => ty,
659+ }
660+ . hir_id ;
640661 }
641- . map ( |ty| ty. hir_id ) ;
642662
643663 let callee_path = self . arena . alloc ( self . mk_expr ( hir:: ExprKind :: Path ( new_path) , span) ) ;
644664 let args = self . arena . alloc_from_iter ( args) ;
@@ -662,25 +682,38 @@ impl<'hir> LoweringContext<'_, 'hir> {
662682 segment : & hir:: PathSegment < ' hir > ,
663683 result : & mut GenericsGenerationResult < ' hir > ,
664684 ) -> hir:: PathSegment < ' hir > {
665- let details = result. generics . args_propagation_details ( ) ;
666-
667- // Always uplift generic params, because if they are not empty then they
668- // should be generated in delegation.
669- let generics = result. generics . into_hir_generics ( self , span) ;
670- let segment = if details. should_propagate {
671- let args = generics. into_generic_args ( self , span) ;
672-
673- // Needed for better error messages (`trait-impl-wrong-args-count.rs` test).
674- let args = if args. is_empty ( ) { None } else { Some ( args) } ;
675-
676- hir:: PathSegment { args, ..segment. clone ( ) }
677- } else {
678- segment. clone ( )
679- } ;
685+ let infer_indices = result. generics . infer_indices ( ) ;
686+ result. generics . into_hir_generics ( self , span) ;
687+
688+ let mut segment = segment. clone ( ) ;
689+ let mut args_iter = result. generics . create_args_iterator ( ) ;
690+
691+ let new_args = segment
692+ . args
693+ . filter ( |args| !args. is_empty ( ) )
694+ . map ( |args| {
695+ self . arena . alloc_from_iter ( args. args . iter ( ) . enumerate ( ) . map ( |( idx, arg) | {
696+ if infer_indices. contains ( & idx) {
697+ args_iter. next ( self , |_| arg. hir_id ( ) ) . expect ( "arg must exist for infer" )
698+ } else {
699+ * arg
700+ }
701+ } ) )
702+ } )
703+ . unwrap_or_else ( || self . arena . alloc_from_iter ( args_iter. consume_all ( self ) ) ) ;
704+
705+ // Needed for better error messages (`trait-impl-wrong-args-count.rs` test).
706+ segment. args = ( !new_args. is_empty ( ) ) . then ( || {
707+ & * self . arena . alloc ( hir:: GenericArgs {
708+ args : new_args,
709+ constraints : & [ ] ,
710+ parenthesized : hir:: GenericArgsParentheses :: No ,
711+ span_ext : segment. args . map_or ( span, |args| args. span_ext ) ,
712+ } )
713+ } ) ;
680714
681- if details. use_args_in_sig_inheritance {
682- result. args_segment_id = Some ( segment. hir_id ) ;
683- }
715+ result. args_segment_id = segment. hir_id ;
716+ result. use_for_sig_inheritance = !result. generics . is_trait_impl ( ) ;
684717
685718 segment
686719 }
0 commit comments