@@ -296,25 +296,35 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
296296 ) -> String {
297297 debug ! ( ?path_hir_id) ;
298298
299+ // If there was already a lifetime among the arguments, just replicate that one.
300+ if let Some ( lt) = self . gen_args . args . iter ( ) . find_map ( |arg| match arg {
301+ hir:: GenericArg :: Lifetime ( lt) => Some ( lt) ,
302+ _ => None ,
303+ } ) {
304+ return std:: iter:: repeat ( lt. to_string ( ) )
305+ . take ( num_params_to_take)
306+ . collect :: < Vec < _ > > ( )
307+ . join ( ", " ) ;
308+ }
309+
299310 let mut ret = Vec :: new ( ) ;
311+ let mut ty_id = None ;
300312 for ( id, node) in self . tcx . hir ( ) . parent_iter ( path_hir_id) {
301313 debug ! ( ?id) ;
302- let params = if let Some ( generics) = node. generics ( ) {
303- generics. params
304- } else if let hir:: Node :: Ty ( ty) = node
305- && let hir:: TyKind :: BareFn ( bare_fn) = ty. kind
306- {
307- bare_fn. generic_params
308- } else {
309- & [ ]
310- } ;
311- ret. extend ( params. iter ( ) . filter_map ( |p| {
312- let hir:: GenericParamKind :: Lifetime { kind : hir:: LifetimeParamKind :: Explicit }
313- = p. kind
314- else { return None } ;
315- let hir:: ParamName :: Plain ( name) = p. name else { return None } ;
316- Some ( name. to_string ( ) )
317- } ) ) ;
314+ if let hir:: Node :: Ty ( _) = node {
315+ ty_id = Some ( id) ;
316+ }
317+
318+ // Suggest `'_` when in function parameter or elided function return.
319+ if let Some ( fn_decl) = node. fn_decl ( ) && let Some ( ty_id) = ty_id {
320+ let in_arg = fn_decl. inputs . iter ( ) . any ( |t| t. hir_id == ty_id) ;
321+ let in_ret = matches ! ( fn_decl. output, hir:: FnRetTy :: Return ( ty) if ty. hir_id == ty_id) ;
322+
323+ if in_arg || ( in_ret && fn_decl. lifetime_elision_allowed ) {
324+ return std:: iter:: repeat ( "'_" . to_owned ( ) ) . take ( num_params_to_take) . collect :: < Vec < _ > > ( ) . join ( ", " ) ;
325+ }
326+ }
327+
318328 // Suggest `'static` when in const/static item-like.
319329 if let hir:: Node :: Item ( hir:: Item {
320330 kind : hir:: ItemKind :: Static { .. } | hir:: ItemKind :: Const { .. } ,
@@ -334,11 +344,29 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
334344 } )
335345 | hir:: Node :: AnonConst ( ..) = node
336346 {
337- ret . extend (
338- std :: iter :: repeat ( "'static" . to_owned ( ) )
339- . take ( num_params_to_take . saturating_sub ( ret . len ( ) ) ) ,
340- ) ;
347+ return std :: iter :: repeat ( "'static" . to_owned ( ) )
348+ . take ( num_params_to_take . saturating_sub ( ret . len ( ) ) )
349+ . collect :: < Vec < _ > > ( )
350+ . join ( ", " ) ;
341351 }
352+
353+ let params = if let Some ( generics) = node. generics ( ) {
354+ generics. params
355+ } else if let hir:: Node :: Ty ( ty) = node
356+ && let hir:: TyKind :: BareFn ( bare_fn) = ty. kind
357+ {
358+ bare_fn. generic_params
359+ } else {
360+ & [ ]
361+ } ;
362+ ret. extend ( params. iter ( ) . filter_map ( |p| {
363+ let hir:: GenericParamKind :: Lifetime { kind : hir:: LifetimeParamKind :: Explicit }
364+ = p. kind
365+ else { return None } ;
366+ let hir:: ParamName :: Plain ( name) = p. name else { return None } ;
367+ Some ( name. to_string ( ) )
368+ } ) ) ;
369+
342370 if ret. len ( ) >= num_params_to_take {
343371 return ret[ ..num_params_to_take] . join ( ", " ) ;
344372 }
0 commit comments