@@ -232,123 +232,199 @@ impl<'hir> GenericsGenerationResult<'hir> {
232232 }
233233}
234234
235+ enum ParentSegmentArgs < ' a > {
236+ /// Parent segment is valid and generic args are specified:
237+ /// `reuse Trait::<'static, ()>::foo;`.
238+ Specified ( & ' a AngleBracketedArgs ) ,
239+ /// Parent segment is valid and args are not specified:
240+ /// `reuse Trait::foo;`.
241+ NotSpecified ,
242+ /// Parent segment doest not exist (`reuse foo`) or we can not
243+ /// add generics to it:
244+ /// ```rust
245+ /// mod to_reuse {
246+ /// fn foo() {}
247+ /// }
248+ ///
249+ /// // Can't add generic args to module.
250+ /// reuse to_reuse::foo;
251+ /// ```
252+ Invalid ,
253+ }
254+
255+ struct GenericsResolutionDto < ' a , ' tcx > {
256+ trait_impl : bool ,
257+
258+ parent_args : ParentSegmentArgs < ' a > ,
259+ child_args : Option < & ' a AngleBracketedArgs > ,
260+
261+ sig_parent_params : & ' tcx [ ty:: GenericParamDef ] ,
262+ sig_child_params : & ' tcx [ ty:: GenericParamDef ] ,
263+
264+ free_to_trait_delegation : bool ,
265+ /// `reuse Trait::foo;`.
266+ qself_is_none : bool ,
267+ /// `reuse <_ as Trait>::foo;`.
268+ qself_is_infer : bool ,
269+ /// Whether we should generate `Self` generic param.
270+ generate_self : bool ,
271+ }
272+
235273impl < ' hir , T : LoweringContextForResolution < ' hir > > DelegationResolverForLowering < ' _ , T > {
236- pub ( super ) fn resolve_generics (
274+ fn create_resolution_dto < ' a > (
237275 & self ,
238- delegation : & Delegation ,
276+ delegation : & ' a Delegation ,
239277 sig_id : DefId ,
240- ) -> GenericsGenerationResults < ' hir > {
278+ ) -> GenericsResolutionDto < ' a , ' hir > {
241279 let tcx = self . 0 . tcx ( ) ;
242-
243280 let delegation_parent_kind = tcx. def_kind ( tcx. local_parent ( self . 0 . owner_id ( ) ) ) ;
244281
245- let segments = & delegation. path . segments ;
246- let len = segments. len ( ) ;
282+ let trait_impl = matches ! ( delegation_parent_kind, DefKind :: Impl { of_trait: true } ) ;
283+
284+ let delegation_in_free_ctx =
285+ !matches ! ( delegation_parent_kind, DefKind :: Trait | DefKind :: Impl { .. } ) ;
286+
287+ let sig_parent = tcx. parent ( sig_id) ;
288+ let sig_in_trait = matches ! ( tcx. def_kind( sig_parent) , DefKind :: Trait ) ;
289+ let free_to_trait_delegation = delegation_in_free_ctx && sig_in_trait;
290+
291+ let sig_child_params = & tcx. generics_of ( sig_id) . own_params ;
292+ let mut sig_parent_params: & [ ty:: GenericParamDef ] = & [ ] ;
247293
248- let get_user_args = | idx : usize | -> Option < & AngleBracketedArgs > {
249- let segment = & segments [ idx ] ;
294+ let qself_is_infer =
295+ delegation . qself . as_ref ( ) . is_some_and ( |qself| qself . ty . is_maybe_parenthesised_infer ( ) ) ;
250296
251- let Some ( args) = segment. args . as_ref ( ) else { return None } ;
252- let GenericArgs :: AngleBracketed ( args) = args else {
253- tcx. dcx ( ) . span_delayed_bug (
254- segment. span ( ) ,
255- "expected angle-bracketed generic args in delegation segment" ,
256- ) ;
297+ let qself_is_none = delegation. qself . is_none ( ) ;
298+ let generate_self = free_to_trait_delegation && ( qself_is_none || qself_is_infer) ;
257299
258- return None ;
259- } ;
300+ let parent_args = if let [ .., parent_segment, _] = & delegation. path . segments [ ..] {
301+ if let Some ( res) = self . 0 . get_resolution_id ( parent_segment. id )
302+ && matches ! ( tcx. def_kind( res) , DefKind :: Trait | DefKind :: TraitAlias )
303+ {
304+ sig_parent_params = & tcx. generics_of ( sig_parent) . own_params ;
305+ self . get_user_args ( parent_segment)
306+ . map ( |args| ParentSegmentArgs :: Specified ( args) )
307+ . unwrap_or ( ParentSegmentArgs :: NotSpecified )
308+ } else {
309+ ParentSegmentArgs :: Invalid
310+ }
311+ } else {
312+ ParentSegmentArgs :: Invalid
313+ } ;
314+
315+ let child_segment = delegation. path . segments . last ( ) . expect ( "must be at least one segment" ) ;
316+ let child_args = self . get_user_args ( child_segment) ;
317+
318+ GenericsResolutionDto {
319+ trait_impl,
320+ parent_args,
321+ child_args,
322+ sig_parent_params,
323+ sig_child_params,
324+ free_to_trait_delegation,
325+ qself_is_none,
326+ qself_is_infer,
327+ generate_self,
328+ }
329+ }
330+
331+ fn get_user_args < ' a > ( & self , segment : & ' a PathSegment ) -> Option < & ' a AngleBracketedArgs > {
332+ let Some ( args) = segment. args . as_ref ( ) else { return None } ;
333+ let GenericArgs :: AngleBracketed ( args) = args else {
334+ self . 0 . tcx ( ) . dcx ( ) . span_delayed_bug (
335+ segment. span ( ) ,
336+ "expected angle-bracketed generic args in delegation segment" ,
337+ ) ;
260338
261- // Treat empty args `reuse foo::<> as bar` as `reuse foo as bar`,
262- // the same logic applied when we call function `fn f<T>(t: T)`
263- // like that `f::<>(())`, in HIR no `<>` will be generated.
264- ( !args. args . is_empty ( ) ) . then ( || args)
339+ return None ;
265340 } ;
266341
267- let sig_params = & tcx. generics_of ( sig_id) . own_params [ ..] ;
342+ // Treat empty args `reuse foo::<> as bar` as `reuse foo as bar`,
343+ // the same logic applied when we call function `fn f<T>(t: T)`
344+ // like that `f::<>(())`, in HIR no `<>` will be generated.
345+ ( !args. args . is_empty ( ) ) . then ( || args)
346+ }
347+
348+ pub ( super ) fn resolve_generics (
349+ & self ,
350+ delegation : & Delegation ,
351+ sig_id : DefId ,
352+ ) -> GenericsGenerationResults < ' hir > {
353+ let dto @ GenericsResolutionDto { trait_impl, generate_self, sig_child_params, .. } =
354+ self . create_resolution_dto ( delegation, sig_id) ;
268355
269356 // If we are in trait impl always generate function whose generics matches
270357 // those that are defined in trait.
271- if matches ! ( delegation_parent_kind , DefKind :: Impl { of_trait : true } ) {
358+ if trait_impl {
272359 // Considering parent generics, during signature inheritance
273360 // we will take those args that are in trait impl header trait ref.
274361 let parent =
275362 DelegationGenerics { data : vec ! [ ] , pos : GenericsPosition :: Child , trait_impl : true } ;
276363
277364 let parent = GenericsGenerationResult :: new ( parent) ;
278365
279- let child = DelegationGenerics :: generate_all ( sig_params, GenericsPosition :: Child , true ) ;
366+ let child = DelegationGenerics :: generate_all (
367+ dto. sig_child_params ,
368+ GenericsPosition :: Child ,
369+ true ,
370+ ) ;
371+
280372 let child = GenericsGenerationResult :: new ( child) ;
281373
282374 return GenericsGenerationResults { parent, child, self_ty_propagation_kind : None } ;
283375 }
284376
285- let delegation_in_free_ctx =
286- !matches ! ( delegation_parent_kind, DefKind :: Trait | DefKind :: Impl { .. } ) ;
287-
288- let sig_parent = tcx. parent ( sig_id) ;
289- let sig_in_trait = matches ! ( tcx. def_kind( sig_parent) , DefKind :: Trait ) ;
290- let free_to_trait_delegation = delegation_in_free_ctx && sig_in_trait;
291-
292- let qself_is_infer =
293- delegation. qself . as_ref ( ) . is_some_and ( |qself| qself. ty . is_maybe_parenthesised_infer ( ) ) ;
294-
295- let qself_is_none = delegation. qself . is_none ( ) ;
296-
297- let generate_self = free_to_trait_delegation && ( qself_is_none || qself_is_infer) ;
298-
299- let can_add_generics_to_parent = len >= 2
300- && self . 0 . get_resolution_id ( segments[ len - 2 ] . id ) . is_some_and ( |def_id| {
301- matches ! ( tcx. def_kind( def_id) , DefKind :: Trait | DefKind :: TraitAlias )
302- } ) ;
303-
304- let parent_generics = if can_add_generics_to_parent {
305- let sig_parent_params = & tcx. generics_of ( sig_parent) . own_params ;
306-
307- if let Some ( args) = get_user_args ( len - 2 ) {
308- DelegationGenerics {
309- data : Self :: create_slots_from_args (
310- tcx,
311- args,
312- & sig_parent_params[ usize:: from ( !generate_self) ..] ,
313- generate_self,
314- ) ,
315- pos : GenericsPosition :: Parent ,
316- trait_impl : false ,
317- }
318- } else {
319- DelegationGenerics :: generate_all (
320- & sig_parent_params[ usize:: from ( !generate_self) ..] ,
321- GenericsPosition :: Parent ,
322- false ,
323- )
377+ let tcx = self . 0 . tcx ( ) ;
378+ let parent_generics = match dto. parent_args {
379+ ParentSegmentArgs :: Specified ( args) => DelegationGenerics {
380+ data : Self :: create_slots_from_args (
381+ tcx,
382+ args,
383+ & dto. sig_parent_params [ usize:: from ( !generate_self) ..] ,
384+ generate_self,
385+ ) ,
386+ pos : GenericsPosition :: Parent ,
387+ trait_impl,
388+ } ,
389+ ParentSegmentArgs :: NotSpecified => DelegationGenerics :: generate_all (
390+ & dto. sig_parent_params [ usize:: from ( !generate_self) ..] ,
391+ GenericsPosition :: Parent ,
392+ trait_impl,
393+ ) ,
394+ ParentSegmentArgs :: Invalid => {
395+ DelegationGenerics { data : vec ! [ ] , pos : GenericsPosition :: Parent , trait_impl }
324396 }
325- } else {
326- DelegationGenerics { data : vec ! [ ] , pos : GenericsPosition :: Parent , trait_impl : false }
327397 } ;
328398
329- let child_generics = if let Some ( args) = get_user_args ( len - 1 ) {
330- let synth_params_index =
331- sig_params. iter ( ) . position ( |p| p. kind . is_synthetic ( ) ) . unwrap_or ( sig_params. len ( ) ) ;
399+ let child_generics = if let Some ( args) = dto. child_args {
400+ let synth_params_index = sig_child_params
401+ . iter ( )
402+ . position ( |p| p. kind . is_synthetic ( ) )
403+ . unwrap_or ( sig_child_params. len ( ) ) ;
332404
333- let mut slots =
334- Self :: create_slots_from_args ( tcx, args, & sig_params[ ..synth_params_index] , false ) ;
405+ let mut slots = Self :: create_slots_from_args (
406+ tcx,
407+ args,
408+ & dto. sig_child_params [ ..synth_params_index] ,
409+ trait_impl,
410+ ) ;
335411
336- for synth_param in & sig_params [ synth_params_index..] {
412+ for synth_param in & sig_child_params [ synth_params_index..] {
337413 slots. push ( GenericArgSlot :: Generate ( synth_param, None ) ) ;
338414 }
339415
340- DelegationGenerics { data : slots, pos : GenericsPosition :: Child , trait_impl : false }
416+ DelegationGenerics { data : slots, pos : GenericsPosition :: Child , trait_impl }
341417 } else {
342- DelegationGenerics :: generate_all ( sig_params , GenericsPosition :: Child , false )
418+ DelegationGenerics :: generate_all ( sig_child_params , GenericsPosition :: Child , trait_impl )
343419 } ;
344420
345421 GenericsGenerationResults {
346422 parent : GenericsGenerationResult :: new ( parent_generics) ,
347423 child : GenericsGenerationResult :: new ( child_generics) ,
348- self_ty_propagation_kind : match free_to_trait_delegation {
349- true => Some ( match qself_is_none {
424+ self_ty_propagation_kind : match dto . free_to_trait_delegation {
425+ true => Some ( match dto . qself_is_none {
350426 true => hir:: DelegationSelfTyPropagationKind :: SelfParam ,
351- false => match qself_is_infer {
427+ false => match dto . qself_is_infer {
352428 true => hir:: DelegationSelfTyPropagationKind :: SelfParam ,
353429 // HirId is filled during generic args propagation.
354430 false => hir:: DelegationSelfTyPropagationKind :: SelfTy ( HirId :: INVALID ) ,
0 commit comments