@@ -1052,7 +1052,7 @@ fn clean_fn_or_proc_macro<'tcx>(
1052
1052
match macro_kind {
1053
1053
Some ( kind) => clean_proc_macro ( item, name, kind, cx) ,
1054
1054
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) ) ;
1056
1056
clean_fn_decl_legacy_const_generics ( & mut func, attrs) ;
1057
1057
FunctionItem ( func)
1058
1058
}
@@ -1071,16 +1071,11 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[hir::Attrib
1071
1071
for ( pos, literal) in meta_item_list. iter ( ) . filter_map ( |meta| meta. lit ( ) ) . enumerate ( ) {
1072
1072
match literal. kind {
1073
1073
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 (
1082
1077
a. get ( ) as _ ,
1083
- Argument { name : Some ( name) , type_ : * ty, is_const : true } ,
1078
+ Parameter { name : Some ( name) , type_ : * ty, is_const : true } ,
1084
1079
) ;
1085
1080
} else {
1086
1081
panic ! ( "unexpected non const in position {pos}" ) ;
@@ -1092,7 +1087,7 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[hir::Attrib
1092
1087
}
1093
1088
}
1094
1089
1095
- enum FunctionArgs < ' tcx > {
1090
+ enum ParamsSrc < ' tcx > {
1096
1091
Body ( hir:: BodyId ) ,
1097
1092
Idents ( & ' tcx [ Option < Ident > ] ) ,
1098
1093
}
@@ -1101,86 +1096,62 @@ fn clean_function<'tcx>(
1101
1096
cx : & mut DocContext < ' tcx > ,
1102
1097
sig : & hir:: FnSig < ' tcx > ,
1103
1098
generics : & hir:: Generics < ' tcx > ,
1104
- args : FunctionArgs < ' tcx > ,
1099
+ params : ParamsSrc < ' tcx > ,
1105
1100
) -> Box < Function > {
1106
1101
let ( generics, decl) = enter_impl_trait ( cx, |cx| {
1107
- // NOTE: generics must be cleaned before args
1102
+ // NOTE: Generics must be cleaned before params.
1108
1103
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
+ } ) ,
1116
1110
} ;
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 ) ;
1118
1112
( generics, decl)
1119
1113
} ) ;
1120
1114
Box :: new ( Function { decl, generics } )
1121
1115
}
1122
1116
1123
- fn clean_args_from_types_and_names < ' tcx > (
1117
+ fn clean_params < ' tcx > (
1124
1118
cx : & mut DocContext < ' tcx > ,
1125
1119
types : & [ hir:: Ty < ' tcx > ] ,
1126
1120
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 ( )
1157
1132
}
1158
1133
1159
- fn clean_args_from_types_and_body_id < ' tcx > (
1134
+ fn clean_params_via_body < ' tcx > (
1160
1135
cx : & mut DocContext < ' tcx > ,
1161
1136
types : & [ hir:: Ty < ' tcx > ] ,
1162
1137
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 ( )
1177
1148
}
1178
1149
1179
- fn clean_fn_decl_with_args < ' tcx > (
1150
+ fn clean_fn_decl_with_params < ' tcx > (
1180
1151
cx : & mut DocContext < ' tcx > ,
1181
1152
decl : & hir:: FnDecl < ' tcx > ,
1182
1153
header : Option < & hir:: FnHeader > ,
1183
- args : Arguments ,
1154
+ params : Vec < Parameter > ,
1184
1155
) -> FnDecl {
1185
1156
let mut output = match decl. output {
1186
1157
hir:: FnRetTy :: Return ( typ) => clean_ty ( typ, cx) ,
@@ -1191,18 +1162,14 @@ fn clean_fn_decl_with_args<'tcx>(
1191
1162
{
1192
1163
output = output. sugared_async_return_type ( ) ;
1193
1164
}
1194
- FnDecl { inputs : args , output, c_variadic : decl. c_variadic }
1165
+ FnDecl { inputs : params , output, c_variadic : decl. c_variadic }
1195
1166
}
1196
1167
1197
1168
fn clean_poly_fn_sig < ' tcx > (
1198
1169
cx : & mut DocContext < ' tcx > ,
1199
1170
did : Option < DefId > ,
1200
1171
sig : ty:: PolyFnSig < ' tcx > ,
1201
1172
) -> 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.
1206
1173
let mut output = clean_middle_ty ( sig. output ( ) , cx, None , None ) ;
1207
1174
1208
1175
// 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>(
1215
1182
output = output. sugared_async_return_type ( ) ;
1216
1183
}
1217
1184
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 }
1237
1204
}
1238
1205
1239
1206
fn 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
1273
1240
RequiredAssocConstItem ( generics, Box :: new ( clean_ty ( ty, cx) ) )
1274
1241
}
1275
1242
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) ) ;
1277
1244
MethodItem ( m, None )
1278
1245
}
1279
1246
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) ) ;
1281
1248
RequiredMethodItem ( m)
1282
1249
}
1283
1250
hir:: TraitItemKind :: Type ( bounds, Some ( default) ) => {
@@ -1318,7 +1285,7 @@ pub(crate) fn clean_impl_item<'tcx>(
1318
1285
type_ : clean_ty ( ty, cx) ,
1319
1286
} ) ) ,
1320
1287
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) ) ;
1322
1289
let defaultness = cx. tcx . defaultness ( impl_. owner_id ) ;
1323
1290
MethodItem ( m, Some ( defaultness) )
1324
1291
}
@@ -1390,14 +1357,14 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
1390
1357
}
1391
1358
ty:: AssocItemContainer :: Trait => tcx. types . self_param ,
1392
1359
} ;
1393
- let self_arg_ty =
1360
+ let self_param_ty =
1394
1361
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 ( )
1398
1365
&& ty == self_ty
1399
1366
{
1400
- match item. decl . inputs . values [ 0 ] . type_ {
1367
+ match item. decl . inputs [ 0 ] . type_ {
1401
1368
BorrowedRef { ref mut type_, .. } => * * type_ = SelfTy ,
1402
1369
_ => unreachable ! ( ) ,
1403
1370
}
@@ -2611,15 +2578,25 @@ fn clean_bare_fn_ty<'tcx>(
2611
2578
cx : & mut DocContext < ' tcx > ,
2612
2579
) -> BareFunctionDecl {
2613
2580
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.
2615
2582
let generic_params = bare_fn
2616
2583
. generic_params
2617
2584
. iter ( )
2618
2585
. filter ( |p| !is_elided_lifetime ( p) )
2619
2586
. map ( |x| clean_generic_param ( cx, None , x) )
2620
2587
. 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) ;
2623
2600
( generic_params, decl)
2624
2601
} ) ;
2625
2602
BareFunctionDecl { safety : bare_fn. safety , abi : bare_fn. abi , decl, generic_params }
@@ -2629,7 +2606,6 @@ fn clean_unsafe_binder_ty<'tcx>(
2629
2606
unsafe_binder_ty : & hir:: UnsafeBinderTy < ' tcx > ,
2630
2607
cx : & mut DocContext < ' tcx > ,
2631
2608
) -> UnsafeBinderTy {
2632
- // NOTE: generics must be cleaned before args
2633
2609
let generic_params = unsafe_binder_ty
2634
2610
. generic_params
2635
2611
. iter ( )
@@ -3155,7 +3131,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
3155
3131
cx. with_param_env ( def_id, |cx| {
3156
3132
let kind = match item. kind {
3157
3133
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) ) ,
3159
3135
sig. header . safety ( ) ,
3160
3136
) ,
3161
3137
hir:: ForeignItemKind :: Static ( ty, mutability, safety) => ForeignStaticItem (
0 commit comments