@@ -58,8 +58,8 @@ use smallvec::SmallVec;
5858use crate :: delegation:: generics:: { GenericsGenerationResult , GenericsGenerationResults } ;
5959use crate :: errors:: { CycleInDelegationSignatureResolution , UnresolvedDelegationCallee } ;
6060use crate :: {
61- AllowReturnTypeNotation , GenericArgsMode , ImplTraitContext , ImplTraitPosition , LoweringContext ,
62- ParamMode , ResolverAstLoweringExt ,
61+ AllowReturnTypeNotation , ImplTraitContext , ImplTraitPosition , LoweringContext , ParamMode ,
62+ ResolverAstLoweringExt ,
6363} ;
6464
6565mod generics;
@@ -144,24 +144,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
144144
145145 let mut generics = self . uplift_delegation_generics ( delegation, sig_id, is_method) ;
146146
147- let body_id = self . lower_delegation_body (
147+ let ( body_id, call_expr_id ) = self . lower_delegation_body (
148148 delegation,
149149 is_method,
150150 param_count,
151151 & mut generics,
152152 span,
153153 ) ;
154154
155- let decl =
156- self . lower_delegation_decl ( sig_id, param_count, c_variadic, span, & generics) ;
155+ let decl = self . lower_delegation_decl (
156+ sig_id,
157+ param_count,
158+ c_variadic,
159+ span,
160+ & generics,
161+ delegation. id ,
162+ call_expr_id,
163+ ) ;
157164
158165 let sig = self . lower_delegation_sig ( sig_id, decl, span) ;
159166 let ident = self . lower_ident ( delegation. ident ) ;
160167
161168 let generics = self . arena . alloc ( hir:: Generics {
162169 has_where_clause_predicates : false ,
163- params : self . arena . alloc_from_iter ( generics. all_params ( span , self ) ) ,
164- predicates : self . arena . alloc_from_iter ( generics. all_predicates ( span , self ) ) ,
170+ params : self . arena . alloc_from_iter ( generics. all_params ( ) ) ,
171+ predicates : self . arena . alloc_from_iter ( generics. all_predicates ( ) ) ,
165172 span,
166173 where_clause_span : span,
167174 } ) ;
@@ -280,6 +287,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
280287 c_variadic : bool ,
281288 span : Span ,
282289 generics : & GenericsGenerationResults < ' hir > ,
290+ call_path_node_id : NodeId ,
291+ call_expr_id : HirId ,
283292 ) -> & ' hir hir:: FnDecl < ' hir > {
284293 // The last parameter in C variadic functions is skipped in the signature,
285294 // like during regular lowering.
@@ -297,7 +306,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
297306 hir_id : self . next_id ( ) ,
298307 kind : hir:: TyKind :: InferDelegation ( hir:: InferDelegation :: Sig (
299308 sig_id,
300- hir:: InferDelegationSig :: Output ( self . arena . alloc ( hir:: DelegationGenerics {
309+ hir:: InferDelegationSig :: Output ( self . arena . alloc ( hir:: DelegationInfo {
310+ call_expr_id,
311+ call_path_res : self . get_resolution_id ( call_path_node_id) ,
301312 child_args_segment_id : generics. child . args_segment_id ,
302313 parent_args_segment_id : generics. parent . args_segment_id ,
303314 self_ty_id : generics. self_ty_id ,
@@ -400,10 +411,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
400411 param_count : usize ,
401412 generics : & mut GenericsGenerationResults < ' hir > ,
402413 span : Span ,
403- ) -> BodyId {
414+ ) -> ( BodyId , HirId ) {
404415 let block = delegation. body . as_deref ( ) ;
416+ let mut call_expr_id = HirId :: INVALID ;
405417
406- self . lower_body ( |this| {
418+ let block_id = self . lower_body ( |this| {
407419 let mut parameters: Vec < hir:: Param < ' _ > > = Vec :: with_capacity ( param_count) ;
408420 let mut args: Vec < hir:: Expr < ' _ > > = Vec :: with_capacity ( param_count) ;
409421
@@ -440,10 +452,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
440452 args. push ( this. lower_target_expr ( & block) ) ;
441453 }
442454
443- let final_expr = this. finalize_body_lowering ( delegation, args, generics, span) ;
455+ let ( final_expr, hir_id) =
456+ this. finalize_body_lowering ( delegation, args, generics, span) ;
457+
458+ call_expr_id = hir_id;
444459
445460 ( this. arena . alloc_from_iter ( parameters) , final_expr)
446- } )
461+ } ) ;
462+
463+ debug_assert_ne ! ( call_expr_id, HirId :: INVALID ) ;
464+
465+ ( block_id, call_expr_id)
447466 }
448467
449468 // FIXME(fn_delegation): Alternatives for target expression lowering:
@@ -459,108 +478,59 @@ impl<'hir> LoweringContext<'_, 'hir> {
459478 self . mk_expr ( hir:: ExprKind :: Block ( block, None ) , block. span )
460479 }
461480
462- // Generates expression for the resulting body. If possible, `MethodCall` is used
463- // to allow autoref/autoderef for target expression. For example in:
464- //
465- // trait Trait : Sized {
466- // fn by_value(self) -> i32 { 1 }
467- // fn by_mut_ref(&mut self) -> i32 { 2 }
468- // fn by_ref(&self) -> i32 { 3 }
469- // }
470- //
471- // struct NewType(SomeType);
472- // impl Trait for NewType {
473- // reuse Trait::* { self.0 }
474- // }
475- //
476- // `self.0` will automatically coerce.
477481 fn finalize_body_lowering (
478482 & mut self ,
479483 delegation : & Delegation ,
480484 args : Vec < hir:: Expr < ' hir > > ,
481485 generics : & mut GenericsGenerationResults < ' hir > ,
482486 span : Span ,
483- ) -> hir:: Expr < ' hir > {
484- let args = self . arena . alloc_from_iter ( args) ;
485-
486- let has_generic_args =
487- delegation. path . segments . iter ( ) . rev ( ) . skip ( 1 ) . any ( |segment| segment. args . is_some ( ) ) ;
488-
489- let call = if self
490- . get_resolution_id ( delegation. id )
491- . map ( |def_id| self . is_method ( def_id, span) )
492- . unwrap_or_default ( )
493- && delegation. qself . is_none ( )
494- && !has_generic_args
495- && !args. is_empty ( )
496- {
497- let ast_segment = delegation. path . segments . last ( ) . unwrap ( ) ;
498- let segment = self . lower_path_segment (
499- delegation. path . span ,
500- ast_segment,
501- ParamMode :: Optional ,
502- GenericArgsMode :: Err ,
503- ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
504- None ,
505- ) ;
506-
507- // FIXME(fn_delegation): proper support for parent generics propagation
508- // in method call scenario.
509- let segment = self . process_segment ( span, & segment, & mut generics. child ) ;
510- let segment = self . arena . alloc ( segment) ;
511-
512- self . arena . alloc ( hir:: Expr {
513- hir_id : self . next_id ( ) ,
514- kind : hir:: ExprKind :: MethodCall ( segment, & args[ 0 ] , & args[ 1 ..] , span) ,
515- span,
516- } )
517- } else {
518- let path = self . lower_qpath (
519- delegation. id ,
520- & delegation. qself ,
521- & delegation. path ,
522- ParamMode :: Optional ,
523- AllowReturnTypeNotation :: No ,
524- ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
525- None ,
526- ) ;
527-
528- let new_path = match path {
529- hir:: QPath :: Resolved ( ty, path) => {
530- let mut new_path = path. clone ( ) ;
531- let len = new_path. segments . len ( ) ;
532-
533- new_path. segments = self . arena . alloc_from_iter (
534- new_path. segments . iter ( ) . enumerate ( ) . map ( |( idx, segment) | {
535- if idx + 2 == len {
536- self . process_segment ( span, segment, & mut generics. parent )
537- } else if idx + 1 == len {
538- self . process_segment ( span, segment, & mut generics. child )
539- } else {
540- segment. clone ( )
541- }
542- } ) ,
543- ) ;
544-
545- hir:: QPath :: Resolved ( ty, self . arena . alloc ( new_path) )
546- }
547- hir:: QPath :: TypeRelative ( ty, segment) => {
548- let segment = self . process_segment ( span, segment, & mut generics. child ) ;
549-
550- hir:: QPath :: TypeRelative ( ty, self . arena . alloc ( segment) )
551- }
552- } ;
487+ ) -> ( hir:: Expr < ' hir > , HirId ) {
488+ let path = self . lower_qpath (
489+ delegation. id ,
490+ & delegation. qself ,
491+ & delegation. path ,
492+ ParamMode :: Optional ,
493+ AllowReturnTypeNotation :: No ,
494+ ImplTraitContext :: Disallowed ( ImplTraitPosition :: Path ) ,
495+ None ,
496+ ) ;
497+
498+ let new_path = match path {
499+ hir:: QPath :: Resolved ( ty, path) => {
500+ let mut new_path = path. clone ( ) ;
501+ let len = new_path. segments . len ( ) ;
502+
503+ new_path. segments = self . arena . alloc_from_iter (
504+ new_path. segments . iter ( ) . enumerate ( ) . map ( |( idx, segment) | {
505+ if idx + 2 == len {
506+ self . process_segment ( span, segment, & mut generics. parent )
507+ } else if idx + 1 == len {
508+ self . process_segment ( span, segment, & mut generics. child )
509+ } else {
510+ segment. clone ( )
511+ }
512+ } ) ,
513+ ) ;
553514
554- generics. self_ty_id = match new_path {
555- hir:: QPath :: Resolved ( ty, _) => ty,
556- hir:: QPath :: TypeRelative ( ty, _) => Some ( ty) ,
515+ hir:: QPath :: Resolved ( ty, self . arena . alloc ( new_path) )
557516 }
558- . map ( |ty| ty. hir_id ) ;
517+ hir:: QPath :: TypeRelative ( ty, segment) => {
518+ let segment = self . process_segment ( span, segment, & mut generics. child ) ;
559519
560- let callee_path = self . arena . alloc ( self . mk_expr ( hir:: ExprKind :: Path ( new_path ) , span ) ) ;
561- self . arena . alloc ( self . mk_expr ( hir :: ExprKind :: Call ( callee_path , args ) , span ) )
520+ hir:: QPath :: TypeRelative ( ty , self . arena . alloc ( segment ) )
521+ }
562522 } ;
563523
524+ generics. self_ty_id = match new_path {
525+ hir:: QPath :: Resolved ( ty, _) => ty,
526+ hir:: QPath :: TypeRelative ( ty, _) => Some ( ty) ,
527+ }
528+ . map ( |ty| ty. hir_id ) ;
529+
530+ let callee_path = self . arena . alloc ( self . mk_expr ( hir:: ExprKind :: Path ( new_path) , span) ) ;
531+ let args = self . arena . alloc_from_iter ( args) ;
532+ let call = self . arena . alloc ( self . mk_expr ( hir:: ExprKind :: Call ( callee_path, args) , span) ) ;
533+
564534 let block = self . arena . alloc ( hir:: Block {
565535 stmts : & [ ] ,
566536 expr : Some ( call) ,
@@ -570,7 +540,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
570540 targeted_by_break : false ,
571541 } ) ;
572542
573- self . mk_expr ( hir:: ExprKind :: Block ( block, None ) , span)
543+ ( self . mk_expr ( hir:: ExprKind :: Block ( block, None ) , span) , call . hir_id )
574544 }
575545
576546 fn process_segment (
@@ -581,8 +551,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
581551 ) -> hir:: PathSegment < ' hir > {
582552 let details = result. generics . args_propagation_details ( ) ;
583553
554+ // Always uplift generic params, because if they are not empty then they
555+ // should be generated in delegation.
556+ let generics = result. generics . into_hir_generics ( self , span) ;
584557 let segment = if details. should_propagate {
585- let generics = result. generics . into_hir_generics ( self , span) ;
586558 let args = generics. into_generic_args ( self , span) ;
587559
588560 // Needed for better error messages (`trait-impl-wrong-args-count.rs` test).
0 commit comments