@@ -20,6 +20,10 @@ pub(super) enum DelegationGenerics<T> {
2020 /// In free-to-trait reuse, when user specified args for trait `reuse Trait::<i32>::foo;`
2121 /// in this case we need to both generate `Self` and process user args.
2222 SelfAndUserSpecified ( Option < T > ) ,
23+ /// In delegations from trait impl to other entities like free functions or trait functions,
24+ /// we want to generate a function whose generics matches generics of signature function
25+ /// in trait.
26+ TraitImpl ( Option < T > , bool /* Has user-specified args */ ) ,
2327}
2428
2529/// Used for storing either AST generics or their lowered HIR version. Firstly we obtain
@@ -48,12 +52,29 @@ pub(super) struct GenericsGenerationResults<'hir> {
4852 pub ( super ) child : GenericsGenerationResult < ' hir > ,
4953}
5054
55+ pub ( super ) struct GenericArgsPropagationDetails {
56+ pub ( super ) should_propagate : bool ,
57+ pub ( super ) use_args_in_sig_inheritance : bool ,
58+ }
59+
5160impl < T > DelegationGenerics < T > {
52- fn is_user_specified ( & self ) -> bool {
53- matches ! (
54- self ,
55- DelegationGenerics :: UserSpecified | DelegationGenerics :: SelfAndUserSpecified { .. }
56- )
61+ fn args_propagation_details ( & self ) -> GenericArgsPropagationDetails {
62+ match self {
63+ DelegationGenerics :: UserSpecified | DelegationGenerics :: SelfAndUserSpecified { .. } => {
64+ GenericArgsPropagationDetails {
65+ should_propagate : false ,
66+ use_args_in_sig_inheritance : true ,
67+ }
68+ }
69+ DelegationGenerics :: TraitImpl ( _, user_specified) => GenericArgsPropagationDetails {
70+ should_propagate : !* user_specified,
71+ use_args_in_sig_inheritance : false ,
72+ } ,
73+ DelegationGenerics :: Default ( _) => GenericArgsPropagationDetails {
74+ should_propagate : true ,
75+ use_args_in_sig_inheritance : false ,
76+ } ,
77+ }
5778 }
5879}
5980
@@ -77,6 +98,12 @@ impl<'hir> HirOrAstGenerics<'hir> {
7798 DelegationGenerics :: SelfAndUserSpecified ( generics) => {
7899 DelegationGenerics :: SelfAndUserSpecified ( generics. as_mut ( ) . map ( process_params) )
79100 }
101+ DelegationGenerics :: TraitImpl ( generics, user_specified) => {
102+ DelegationGenerics :: TraitImpl (
103+ generics. as_mut ( ) . map ( process_params) ,
104+ * user_specified,
105+ )
106+ }
80107 } ;
81108
82109 * self = HirOrAstGenerics :: Hir ( hir_generics) ;
@@ -91,7 +118,8 @@ impl<'hir> HirOrAstGenerics<'hir> {
91118 HirOrAstGenerics :: Hir ( hir_generics) => match hir_generics {
92119 DelegationGenerics :: UserSpecified => hir:: Generics :: empty ( ) ,
93120 DelegationGenerics :: Default ( generics)
94- | DelegationGenerics :: SelfAndUserSpecified ( generics) => {
121+ | DelegationGenerics :: SelfAndUserSpecified ( generics)
122+ | DelegationGenerics :: TraitImpl ( generics, _) => {
95123 generics. unwrap_or ( hir:: Generics :: empty ( ) )
96124 }
97125 } ,
@@ -111,17 +139,18 @@ impl<'hir> HirOrAstGenerics<'hir> {
111139 HirOrAstGenerics :: Hir ( hir_generics) => match hir_generics {
112140 DelegationGenerics :: UserSpecified => None ,
113141 DelegationGenerics :: Default ( generics)
114- | DelegationGenerics :: SelfAndUserSpecified ( generics) => generics. map ( |generics| {
142+ | DelegationGenerics :: SelfAndUserSpecified ( generics)
143+ | DelegationGenerics :: TraitImpl ( generics, _) => generics. map ( |generics| {
115144 ctx. create_generics_args_from_params ( generics. params , add_lifetimes, span)
116145 } ) ,
117146 } ,
118147 }
119148 }
120149
121- pub ( super ) fn is_user_specified ( & self ) -> bool {
150+ pub ( super ) fn args_propagation_details ( & self ) -> GenericArgsPropagationDetails {
122151 match self {
123- HirOrAstGenerics :: Ast ( ast_generics) => ast_generics. is_user_specified ( ) ,
124- HirOrAstGenerics :: Hir ( hir_generics) => hir_generics. is_user_specified ( ) ,
152+ HirOrAstGenerics :: Ast ( ast_generics) => ast_generics. args_propagation_details ( ) ,
153+ HirOrAstGenerics :: Hir ( hir_generics) => hir_generics. args_propagation_details ( ) ,
125154 }
126155 }
127156}
@@ -215,10 +244,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
215244 item_id : NodeId ,
216245 span : Span ,
217246 ) -> GenericsGenerationResults < ' hir > {
218- let delegation_in_free_ctx = !matches ! (
219- self . tcx. def_kind( self . tcx. local_parent( self . local_def_id( item_id) ) ) ,
220- DefKind :: Trait | DefKind :: Impl { .. }
221- ) ;
247+ let delegation_parent_kind =
248+ self . tcx . def_kind ( self . tcx . local_parent ( self . local_def_id ( item_id) ) ) ;
249+
250+ let segments = & delegation. path . segments ;
251+ let len = segments. len ( ) ;
252+ let child_user_specified = segments[ len - 1 ] . args . is_some ( ) ;
253+
254+ // If we are in trait impl always generate function whose generics matches
255+ // those that are defined in trait.
256+ if matches ! ( delegation_parent_kind, DefKind :: Impl { of_trait: true } ) {
257+ // Considering parent generics, during signature inheritance
258+ // we will take those args that are in trait impl header trait ref.
259+ let parent = GenericsGenerationResult :: new ( DelegationGenerics :: Default ( None ) ) ;
260+
261+ let generics = self . get_fn_like_generics ( root_fn_id, span) ;
262+ let child = DelegationGenerics :: TraitImpl ( generics, child_user_specified) ;
263+ let child = GenericsGenerationResult :: new ( child) ;
264+
265+ return GenericsGenerationResults { parent, child } ;
266+ }
267+
268+ let delegation_in_free_ctx =
269+ !matches ! ( delegation_parent_kind, DefKind :: Trait | DefKind :: Impl { .. } ) ;
222270
223271 let root_function_in_trait =
224272 matches ! ( self . tcx. def_kind( self . tcx. parent( root_fn_id) ) , DefKind :: Trait ) ;
@@ -234,9 +282,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
234282 )
235283 } ;
236284
237- let segments = & delegation. path . segments ;
238- let len = segments. len ( ) ;
239-
240285 let can_add_generics_to_parent = len >= 2
241286 && self . get_resolution_id ( segments[ len - 2 ] . id ) . is_some_and ( |def_id| {
242287 matches ! ( self . tcx. def_kind( def_id) , DefKind :: Trait | DefKind :: TraitAlias )
@@ -256,7 +301,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
256301 DelegationGenerics :: Default ( None )
257302 } ;
258303
259- let child_generics = if segments [ len - 1 ] . args . is_some ( ) {
304+ let child_generics = if child_user_specified {
260305 DelegationGenerics :: UserSpecified
261306 } else {
262307 DelegationGenerics :: Default ( self . get_fn_like_generics ( root_fn_id, span) )
0 commit comments