@@ -1052,7 +1052,7 @@ fn clean_fn_or_proc_macro<'tcx>(
10521052 match macro_kind {
10531053 Some ( kind) => clean_proc_macro ( item, name, kind, cx) ,
10541054 None => {
1055- let mut func = clean_function ( cx, sig, generics, FunctionArgs :: Body ( body_id) ) ;
1055+ let mut func = clean_function ( cx, sig, generics, ParamsSrc :: Body ( body_id) ) ;
10561056 clean_fn_decl_legacy_const_generics ( & mut func, attrs) ;
10571057 FunctionItem ( func)
10581058 }
@@ -1071,16 +1071,11 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[hir::Attrib
10711071 for ( pos, literal) in meta_item_list. iter ( ) . filter_map ( |meta| meta. lit ( ) ) . enumerate ( ) {
10721072 match literal. kind {
10731073 ast:: LitKind :: Int ( a, _) => {
1074- let param = func. generics . params . remove ( 0 ) ;
1075- if let GenericParamDef {
1076- name,
1077- kind : GenericParamDefKind :: Const { ty, .. } ,
1078- ..
1079- } = param
1080- {
1081- func. decl . inputs . values . insert (
1074+ let GenericParamDef { name, kind, .. } = func. generics . params . remove ( 0 ) ;
1075+ if let GenericParamDefKind :: Const { ty, .. } = kind {
1076+ func. decl . inputs . insert (
10821077 a. get ( ) as _ ,
1083- Argument { name : Some ( name) , type_ : * ty, is_const : true } ,
1078+ Parameter { name : Some ( name) , type_ : * ty, is_const : true } ,
10841079 ) ;
10851080 } else {
10861081 panic ! ( "unexpected non const in position {pos}" ) ;
@@ -1092,7 +1087,7 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[hir::Attrib
10921087 }
10931088}
10941089
1095- enum FunctionArgs < ' tcx > {
1090+ enum ParamsSrc < ' tcx > {
10961091 Body ( hir:: BodyId ) ,
10971092 Idents ( & ' tcx [ Option < Ident > ] ) ,
10981093}
@@ -1101,86 +1096,62 @@ fn clean_function<'tcx>(
11011096 cx : & mut DocContext < ' tcx > ,
11021097 sig : & hir:: FnSig < ' tcx > ,
11031098 generics : & hir:: Generics < ' tcx > ,
1104- args : FunctionArgs < ' tcx > ,
1099+ params : ParamsSrc < ' tcx > ,
11051100) -> Box < Function > {
11061101 let ( generics, decl) = enter_impl_trait ( cx, |cx| {
1107- // NOTE: generics must be cleaned before args
1102+ // NOTE: Generics must be cleaned before params.
11081103 let generics = clean_generics ( generics, cx) ;
1109- let args = match args {
1110- FunctionArgs :: Body ( body_id) => {
1111- clean_args_from_types_and_body_id ( cx, sig. decl . inputs , body_id)
1112- }
1113- FunctionArgs :: Idents ( idents) => {
1114- clean_args_from_types_and_names ( cx, sig. decl . inputs , idents)
1115- }
1104+ let params = match params {
1105+ ParamsSrc :: Body ( body_id) => clean_params_via_body ( cx, sig. decl . inputs , body_id) ,
1106+ // Let's not perpetuate anon params from Rust 2015; use `_` for them.
1107+ ParamsSrc :: Idents ( idents) => clean_params ( cx, sig. decl . inputs , idents, |ident| {
1108+ Some ( ident. map_or ( kw:: Underscore , |ident| ident. name ) )
1109+ } ) ,
11161110 } ;
1117- let decl = clean_fn_decl_with_args ( cx, sig. decl , Some ( & sig. header ) , args ) ;
1111+ let decl = clean_fn_decl_with_params ( cx, sig. decl , Some ( & sig. header ) , params ) ;
11181112 ( generics, decl)
11191113 } ) ;
11201114 Box :: new ( Function { decl, generics } )
11211115}
11221116
1123- fn clean_args_from_types_and_names < ' tcx > (
1117+ fn clean_params < ' tcx > (
11241118 cx : & mut DocContext < ' tcx > ,
11251119 types : & [ hir:: Ty < ' tcx > ] ,
11261120 idents : & [ Option < Ident > ] ,
1127- ) -> Arguments {
1128- fn nonempty_name ( ident : & Option < Ident > ) -> Option < Symbol > {
1129- if let Some ( ident) = ident
1130- && ident. name != kw:: Underscore
1131- {
1132- Some ( ident. name )
1133- } else {
1134- None
1135- }
1136- }
1137-
1138- // If at least one argument has a name, use `_` as the name of unnamed
1139- // arguments. Otherwise omit argument names.
1140- let default_name = if idents. iter ( ) . any ( |ident| nonempty_name ( ident) . is_some ( ) ) {
1141- Some ( kw:: Underscore )
1142- } else {
1143- None
1144- } ;
1145-
1146- Arguments {
1147- values : types
1148- . iter ( )
1149- . enumerate ( )
1150- . map ( |( i, ty) | Argument {
1151- type_ : clean_ty ( ty, cx) ,
1152- name : idents. get ( i) . and_then ( nonempty_name) . or ( default_name) ,
1153- is_const : false ,
1154- } )
1155- . collect ( ) ,
1156- }
1121+ postprocess : impl Fn ( Option < Ident > ) -> Option < Symbol > ,
1122+ ) -> Vec < Parameter > {
1123+ types
1124+ . iter ( )
1125+ . enumerate ( )
1126+ . map ( |( i, ty) | Parameter {
1127+ name : postprocess ( idents[ i] ) ,
1128+ type_ : clean_ty ( ty, cx) ,
1129+ is_const : false ,
1130+ } )
1131+ . collect ( )
11571132}
11581133
1159- fn clean_args_from_types_and_body_id < ' tcx > (
1134+ fn clean_params_via_body < ' tcx > (
11601135 cx : & mut DocContext < ' tcx > ,
11611136 types : & [ hir:: Ty < ' tcx > ] ,
11621137 body_id : hir:: BodyId ,
1163- ) -> Arguments {
1164- let body = cx. tcx . hir_body ( body_id) ;
1165-
1166- Arguments {
1167- values : types
1168- . iter ( )
1169- . zip ( body. params )
1170- . map ( |( ty, param) | Argument {
1171- name : Some ( name_from_pat ( param. pat ) ) ,
1172- type_ : clean_ty ( ty, cx) ,
1173- is_const : false ,
1174- } )
1175- . collect ( ) ,
1176- }
1138+ ) -> Vec < Parameter > {
1139+ types
1140+ . iter ( )
1141+ . zip ( cx. tcx . hir_body ( body_id) . params )
1142+ . map ( |( ty, param) | Parameter {
1143+ name : Some ( name_from_pat ( param. pat ) ) ,
1144+ type_ : clean_ty ( ty, cx) ,
1145+ is_const : false ,
1146+ } )
1147+ . collect ( )
11771148}
11781149
1179- fn clean_fn_decl_with_args < ' tcx > (
1150+ fn clean_fn_decl_with_params < ' tcx > (
11801151 cx : & mut DocContext < ' tcx > ,
11811152 decl : & hir:: FnDecl < ' tcx > ,
11821153 header : Option < & hir:: FnHeader > ,
1183- args : Arguments ,
1154+ params : Vec < Parameter > ,
11841155) -> FnDecl {
11851156 let mut output = match decl. output {
11861157 hir:: FnRetTy :: Return ( typ) => clean_ty ( typ, cx) ,
@@ -1191,18 +1162,14 @@ fn clean_fn_decl_with_args<'tcx>(
11911162 {
11921163 output = output. sugared_async_return_type ( ) ;
11931164 }
1194- FnDecl { inputs : args , output, c_variadic : decl. c_variadic }
1165+ FnDecl { inputs : params , output, c_variadic : decl. c_variadic }
11951166}
11961167
11971168fn clean_poly_fn_sig < ' tcx > (
11981169 cx : & mut DocContext < ' tcx > ,
11991170 did : Option < DefId > ,
12001171 sig : ty:: PolyFnSig < ' tcx > ,
12011172) -> FnDecl {
1202- let mut names = did. map_or ( & [ ] as & [ _ ] , |did| cx. tcx . fn_arg_idents ( did) ) . iter ( ) ;
1203-
1204- // We assume all empty tuples are default return type. This theoretically can discard `-> ()`,
1205- // but shouldn't change any code meaning.
12061173 let mut output = clean_middle_ty ( sig. output ( ) , cx, None , None ) ;
12071174
12081175 // If the return type isn't an `impl Trait`, we can safely assume that this
@@ -1215,25 +1182,25 @@ fn clean_poly_fn_sig<'tcx>(
12151182 output = output. sugared_async_return_type ( ) ;
12161183 }
12171184
1218- FnDecl {
1219- output ,
1220- c_variadic : sig . skip_binder ( ) . c_variadic ,
1221- inputs : Arguments {
1222- values : sig
1223- . inputs ( )
1224- . iter ( )
1225- . map ( |t| Argument {
1226- type_ : clean_middle_ty ( t . map_bound ( |t| * t ) , cx , None , None ) ,
1227- name : Some ( if let Some ( Some ( ident ) ) = names . next ( ) {
1228- ident . name
1229- } else {
1230- kw :: Underscore
1231- } ) ,
1232- is_const : false ,
1233- } )
1234- . collect ( ) ,
1235- } ,
1236- }
1185+ let mut idents = did . map ( |did| cx . tcx . fn_arg_idents ( did ) ) . unwrap_or_default ( ) . iter ( ) . copied ( ) ;
1186+
1187+ // If this comes from a fn item, let's not perpetuate anon params from Rust 2015; use `_` for them.
1188+ // If this comes from a fn ptr ty, we just keep params unnamed since it's more conventional stylistically.
1189+ // Since the param name is not part of the semantic type, these params never bear a name unlike
1190+ // in the HIR case, thus we can't peform any fancy fallback logic unlike `clean_bare_fn_ty`.
1191+ let fallback = did . map ( |_| kw :: Underscore ) ;
1192+
1193+ let params = sig
1194+ . inputs ( )
1195+ . iter ( )
1196+ . map ( |ty| Parameter {
1197+ name : idents . next ( ) . flatten ( ) . map ( |ident| ident . name ) . or ( fallback ) ,
1198+ type_ : clean_middle_ty ( ty . map_bound ( |ty| * ty ) , cx , None , None ) ,
1199+ is_const : false ,
1200+ } )
1201+ . collect ( ) ;
1202+
1203+ FnDecl { inputs : params , output , c_variadic : sig . skip_binder ( ) . c_variadic }
12371204}
12381205
12391206fn clean_trait_ref < ' tcx > ( trait_ref : & hir:: TraitRef < ' tcx > , cx : & mut DocContext < ' tcx > ) -> Path {
@@ -1273,11 +1240,11 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext
12731240 RequiredAssocConstItem ( generics, Box :: new ( clean_ty ( ty, cx) ) )
12741241 }
12751242 hir:: TraitItemKind :: Fn ( ref sig, hir:: TraitFn :: Provided ( body) ) => {
1276- let m = clean_function ( cx, sig, trait_item. generics , FunctionArgs :: Body ( body) ) ;
1243+ let m = clean_function ( cx, sig, trait_item. generics , ParamsSrc :: Body ( body) ) ;
12771244 MethodItem ( m, None )
12781245 }
12791246 hir:: TraitItemKind :: Fn ( ref sig, hir:: TraitFn :: Required ( idents) ) => {
1280- let m = clean_function ( cx, sig, trait_item. generics , FunctionArgs :: Idents ( idents) ) ;
1247+ let m = clean_function ( cx, sig, trait_item. generics , ParamsSrc :: Idents ( idents) ) ;
12811248 RequiredMethodItem ( m)
12821249 }
12831250 hir:: TraitItemKind :: Type ( bounds, Some ( default) ) => {
@@ -1318,7 +1285,7 @@ pub(crate) fn clean_impl_item<'tcx>(
13181285 type_ : clean_ty ( ty, cx) ,
13191286 } ) ) ,
13201287 hir:: ImplItemKind :: Fn ( ref sig, body) => {
1321- let m = clean_function ( cx, sig, impl_. generics , FunctionArgs :: Body ( body) ) ;
1288+ let m = clean_function ( cx, sig, impl_. generics , ParamsSrc :: Body ( body) ) ;
13221289 let defaultness = cx. tcx . defaultness ( impl_. owner_id ) ;
13231290 MethodItem ( m, Some ( defaultness) )
13241291 }
@@ -1390,14 +1357,14 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
13901357 }
13911358 ty:: AssocItemContainer :: Trait => tcx. types . self_param ,
13921359 } ;
1393- let self_arg_ty =
1360+ let self_param_ty =
13941361 tcx. fn_sig ( assoc_item. def_id ) . instantiate_identity ( ) . input ( 0 ) . skip_binder ( ) ;
1395- if self_arg_ty == self_ty {
1396- item. decl . inputs . values [ 0 ] . type_ = SelfTy ;
1397- } else if let ty:: Ref ( _, ty, _) = * self_arg_ty . kind ( )
1362+ if self_param_ty == self_ty {
1363+ item. decl . inputs [ 0 ] . type_ = SelfTy ;
1364+ } else if let ty:: Ref ( _, ty, _) = * self_param_ty . kind ( )
13981365 && ty == self_ty
13991366 {
1400- match item. decl . inputs . values [ 0 ] . type_ {
1367+ match item. decl . inputs [ 0 ] . type_ {
14011368 BorrowedRef { ref mut type_, .. } => * * type_ = SelfTy ,
14021369 _ => unreachable ! ( ) ,
14031370 }
@@ -2611,15 +2578,25 @@ fn clean_bare_fn_ty<'tcx>(
26112578 cx : & mut DocContext < ' tcx > ,
26122579) -> BareFunctionDecl {
26132580 let ( generic_params, decl) = enter_impl_trait ( cx, |cx| {
2614- // NOTE: generics must be cleaned before args
2581+ // NOTE: Generics must be cleaned before params.
26152582 let generic_params = bare_fn
26162583 . generic_params
26172584 . iter ( )
26182585 . filter ( |p| !is_elided_lifetime ( p) )
26192586 . map ( |x| clean_generic_param ( cx, None , x) )
26202587 . collect ( ) ;
2621- let args = clean_args_from_types_and_names ( cx, bare_fn. decl . inputs , bare_fn. param_idents ) ;
2622- let decl = clean_fn_decl_with_args ( cx, bare_fn. decl , None , args) ;
2588+ // Since it's more conventional stylistically, elide the name of all params called `_`
2589+ // unless there's at least one interestingly named param in which case don't elide any
2590+ // name since mixing named and unnamed params is less legible.
2591+ let filter = |ident : Option < Ident > | {
2592+ ident. map ( |ident| ident. name ) . filter ( |& ident| ident != kw:: Underscore )
2593+ } ;
2594+ let fallback =
2595+ bare_fn. param_idents . iter ( ) . copied ( ) . find_map ( filter) . map ( |_| kw:: Underscore ) ;
2596+ let params = clean_params ( cx, bare_fn. decl . inputs , bare_fn. param_idents , |ident| {
2597+ filter ( ident) . or ( fallback)
2598+ } ) ;
2599+ let decl = clean_fn_decl_with_params ( cx, bare_fn. decl , None , params) ;
26232600 ( generic_params, decl)
26242601 } ) ;
26252602 BareFunctionDecl { safety : bare_fn. safety , abi : bare_fn. abi , decl, generic_params }
@@ -2629,7 +2606,6 @@ fn clean_unsafe_binder_ty<'tcx>(
26292606 unsafe_binder_ty : & hir:: UnsafeBinderTy < ' tcx > ,
26302607 cx : & mut DocContext < ' tcx > ,
26312608) -> UnsafeBinderTy {
2632- // NOTE: generics must be cleaned before args
26332609 let generic_params = unsafe_binder_ty
26342610 . generic_params
26352611 . iter ( )
@@ -3155,7 +3131,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
31553131 cx. with_param_env ( def_id, |cx| {
31563132 let kind = match item. kind {
31573133 hir:: ForeignItemKind :: Fn ( sig, idents, generics) => ForeignFunctionItem (
3158- clean_function ( cx, & sig, generics, FunctionArgs :: Idents ( idents) ) ,
3134+ clean_function ( cx, & sig, generics, ParamsSrc :: Idents ( idents) ) ,
31593135 sig. header . safety ( ) ,
31603136 ) ,
31613137 hir:: ForeignItemKind :: Static ( ty, mutability, safety) => ForeignStaticItem (
0 commit comments