@@ -858,6 +858,67 @@ pub(crate) fn clean_generics<'tcx>(
858858 }
859859}
860860
861+ /// Cleans delegation generics with HIR ordering and ty-side fallback.
862+ fn clean_delegation_generics < ' tcx > (
863+ gens : & hir:: Generics < ' tcx > ,
864+ cx : & mut DocContext < ' tcx > ,
865+ ty_generics : Generics ,
866+ ) -> Generics {
867+ let mut hir_generics = clean_generics ( gens, cx) ;
868+ let impl_trait_param_def_ids = hir_generics
869+ . params
870+ . iter ( )
871+ . filter ( |param| param. is_synthetic_param ( ) )
872+ . map ( |param| param. def_id )
873+ . collect :: < Vec < _ > > ( ) ;
874+
875+ for def_id in impl_trait_param_def_ids {
876+ cx. impl_trait_bounds . remove ( & def_id. into ( ) ) ;
877+ }
878+ hir_generics. params . retain ( |param| !param. is_synthetic_param ( ) ) ;
879+ hir_generics. where_predicates =
880+ hir_generics
881+ . where_predicates
882+ . into_iter ( )
883+ . filter_map ( |mut pred| {
884+ if retain_delegation_predicate ( cx. tcx , & mut pred) { Some ( pred) } else { None }
885+ } )
886+ . collect ( ) ;
887+
888+ let Generics { params : ty_params, where_predicates } = ty_generics;
889+ let where_predicates =
890+ where_predicates
891+ . into_iter ( )
892+ . filter_map ( |mut pred| {
893+ if retain_delegation_predicate ( cx. tcx , & mut pred) { Some ( pred) } else { None }
894+ } )
895+ . collect ( ) ;
896+ let mut generics = Generics { params : hir_generics. params , where_predicates } ;
897+
898+ for param in ty_params {
899+ if !generics. params . iter ( ) . any ( |existing| existing. def_id == param. def_id ) {
900+ generics. params . push ( param) ;
901+ }
902+ }
903+ for pred in hir_generics. where_predicates {
904+ if !generics. where_predicates . contains ( & pred) {
905+ generics. where_predicates . push ( pred) ;
906+ }
907+ }
908+
909+ generics
910+ }
911+
912+ fn retain_delegation_predicate ( tcx : TyCtxt < ' _ > , pred : & mut WherePredicate ) -> bool {
913+ match pred {
914+ WherePredicate :: BoundPredicate { bounds, .. } => {
915+ bounds. retain ( |bound| !bound. is_meta_sized_bound ( tcx) ) ;
916+ !bounds. is_empty ( )
917+ }
918+ WherePredicate :: RegionPredicate { .. } | WherePredicate :: EqPredicate { .. } => true ,
919+ }
920+ }
921+
861922fn clean_ty_generics < ' tcx > ( cx : & mut DocContext < ' tcx > , def_id : DefId ) -> Generics {
862923 clean_ty_generics_inner ( cx, cx. tcx . generics_of ( def_id) , cx. tcx . explicit_predicates_of ( def_id) )
863924}
@@ -1091,10 +1152,10 @@ fn clean_fn_or_proc_macro<'tcx>(
10911152 None => {
10921153 let mut func = clean_function (
10931154 cx,
1155+ item. owner_id . to_def_id ( ) ,
10941156 sig,
10951157 generics,
10961158 ParamsSrc :: Body ( body_id) ,
1097- item. owner_id . to_def_id ( ) ,
10981159 ) ;
10991160 clean_fn_decl_legacy_const_generics ( & mut func, attrs) ;
11001161 FunctionItem ( func)
@@ -1130,33 +1191,32 @@ enum ParamsSrc<'tcx> {
11301191
11311192fn clean_function < ' tcx > (
11321193 cx : & mut DocContext < ' tcx > ,
1194+ def_id : DefId ,
11331195 sig : & hir:: FnSig < ' tcx > ,
11341196 generics : & hir:: Generics < ' tcx > ,
11351197 params : ParamsSrc < ' tcx > ,
1136- def_id : DefId ,
11371198) -> Box < Function > {
1199+ if sig. decl . opt_delegation_sig_id ( ) . is_some ( ) {
1200+ return enter_impl_trait ( cx, |cx| {
1201+ // Delegation HIR signatures are unresolved, so clean the resolved ty-side function.
1202+ let mut function = inline:: build_function ( cx, def_id) ;
1203+ let ty_generics = mem:: take ( & mut function. generics ) ;
1204+ function. generics = clean_delegation_generics ( generics, cx, ty_generics) ;
1205+ function
1206+ } ) ;
1207+ }
1208+
11381209 let ( generics, decl) = enter_impl_trait ( cx, |cx| {
11391210 // NOTE: Generics must be cleaned before params.
11401211 let generics = clean_generics ( generics, cx) ;
1141- let decl = if sig. decl . opt_delegation_sig_id ( ) . is_some ( ) {
1142- // A delegation item (`reuse path::method`) has no resolved signature in the
1143- // HIR: its inputs and return type are `InferDelegation` nodes that clean to
1144- // `_`, and an `async` header over that inferred return type would panic in
1145- // `sugared_async_return_type`. The resolved signature only exists on the ty
1146- // side, so clean that instead, exactly like an inlined item. This both fixes
1147- // the rendered `-> _` / `self: _` and makes the async sugaring well-defined.
1148- let sig = cx. tcx . fn_sig ( def_id) . instantiate_identity ( ) . skip_norm_wip ( ) ;
1149- clean_poly_fn_sig ( cx, Some ( def_id) , sig)
1150- } else {
1151- let params = match params {
1152- ParamsSrc :: Body ( body_id) => clean_params_via_body ( cx, sig. decl . inputs , body_id) ,
1153- // Let's not perpetuate anon params from Rust 2015; use `_` for them.
1154- ParamsSrc :: Idents ( idents) => clean_params ( cx, sig. decl . inputs , idents, |ident| {
1155- Some ( ident. map_or ( kw:: Underscore , |ident| ident. name ) )
1156- } ) ,
1157- } ;
1158- clean_fn_decl_with_params ( cx, sig. decl , Some ( & sig. header ) , params)
1212+ let params = match params {
1213+ ParamsSrc :: Body ( body_id) => clean_params_via_body ( cx, sig. decl . inputs , body_id) ,
1214+ // Let's not perpetuate anon params from Rust 2015; use `_` for them.
1215+ ParamsSrc :: Idents ( idents) => clean_params ( cx, sig. decl . inputs , idents, |ident| {
1216+ Some ( ident. map_or ( kw:: Underscore , |ident| ident. name ) )
1217+ } ) ,
11591218 } ;
1219+ let decl = clean_fn_decl_with_params ( cx, sig. decl , Some ( & sig. header ) , params) ;
11601220 ( generics, decl)
11611221 } ) ;
11621222 Box :: new ( Function { decl, generics } )
@@ -1289,16 +1349,16 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
12891349 }
12901350 hir:: TraitItemKind :: Fn ( ref sig, hir:: TraitFn :: Provided ( body) ) => {
12911351 let m =
1292- clean_function ( cx, sig, trait_item. generics , ParamsSrc :: Body ( body) , local_did ) ;
1352+ clean_function ( cx, local_did , sig, trait_item. generics , ParamsSrc :: Body ( body) ) ;
12931353 MethodItem ( m, Defaultness :: from_trait_item ( trait_item. defaultness ) )
12941354 }
12951355 hir:: TraitItemKind :: Fn ( ref sig, hir:: TraitFn :: Required ( idents) ) => {
12961356 let m = clean_function (
12971357 cx,
1358+ local_did,
12981359 sig,
12991360 trait_item. generics ,
13001361 ParamsSrc :: Idents ( idents) ,
1301- local_did,
13021362 ) ;
13031363 RequiredMethodItem ( m, Defaultness :: from_trait_item ( trait_item. defaultness ) )
13041364 }
@@ -1340,7 +1400,7 @@ pub(crate) fn clean_impl_item<'tcx>(
13401400 type_ : clean_ty ( ty, cx) ,
13411401 } ) ) ,
13421402 hir:: ImplItemKind :: Fn ( ref sig, body) => {
1343- let m = clean_function ( cx, sig, impl_. generics , ParamsSrc :: Body ( body) , local_did ) ;
1403+ let m = clean_function ( cx, local_did , sig, impl_. generics , ParamsSrc :: Body ( body) ) ;
13441404 let defaultness = match impl_. impl_kind {
13451405 hir:: ImplItemImplKind :: Inherent { .. } => hir:: Defaultness :: Final ,
13461406 hir:: ImplItemImplKind :: Trait { defaultness, .. } => defaultness,
@@ -3279,7 +3339,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
32793339 cx. with_param_env ( def_id, |cx| {
32803340 let kind = match item. kind {
32813341 hir:: ForeignItemKind :: Fn ( sig, idents, generics) => ForeignFunctionItem (
3282- clean_function ( cx, & sig, generics, ParamsSrc :: Idents ( idents) , def_id ) ,
3342+ clean_function ( cx, def_id , & sig, generics, ParamsSrc :: Idents ( idents) ) ,
32833343 sig. header . safety ( ) ,
32843344 ) ,
32853345 hir:: ForeignItemKind :: Static ( ty, mutability, safety) => ForeignStaticItem (
0 commit comments