@@ -291,7 +291,52 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
291291 }
292292
293293 // Creates lifetime name suggestions from the lifetime parameter names
294- fn get_lifetime_args_suggestions_from_param_names ( & self , num_params_to_take : usize ) -> String {
294+ fn get_lifetime_args_suggestions_from_param_names (
295+ & self ,
296+ path_hir_id : Option < hir:: HirId > ,
297+ num_params_to_take : usize ,
298+ ) -> String {
299+ debug ! ( ?path_hir_id) ;
300+
301+ if let Some ( path_hir_id) = path_hir_id {
302+ // We first try to get lifetime name suggestions from scope or elision information.
303+ // If none is available we use the parameter definitions
304+ if let Some ( LifetimeScopeForPath :: Elided ) = self . tcx . lifetime_scope ( path_hir_id) {
305+ // Use suggestions of the form `<'_, '_>` in case lifetime can be elided
306+ return [ "'_" ] . repeat ( num_params_to_take) . join ( "," ) ;
307+ }
308+
309+ let mut ret = Vec :: new ( ) ;
310+ for ( id, node) in self . tcx . hir ( ) . parent_iter ( path_hir_id) {
311+ debug ! ( ?id) ;
312+ let params = if let Some ( generics) = node. generics ( ) {
313+ generics. params
314+ } else if let hir:: Node :: Ty ( ty) = node
315+ && let hir:: TyKind :: BareFn ( bare_fn) = ty. kind
316+ {
317+ bare_fn. generic_params
318+ } else {
319+ & [ ]
320+ } ;
321+ ret. extend ( params. iter ( ) . filter_map ( |p| {
322+ let hir:: GenericParamKind :: Lifetime { kind : hir:: LifetimeParamKind :: Explicit }
323+ = p. kind
324+ else { return None } ;
325+ let hir:: ParamName :: Plain ( name) = p. name else { return None } ;
326+ Some ( name. to_string ( ) )
327+ } ) ) ;
328+ if ret. len ( ) >= num_params_to_take {
329+ return ret[ ..num_params_to_take] . join ( ", " ) ;
330+ }
331+ // We cannot refer to lifetimes defined in an outer function.
332+ if let hir:: Node :: Item ( _) = node {
333+ break ;
334+ }
335+ }
336+ }
337+
338+ // We could not gather enough lifetime parameters in the scope.
339+ // We use the parameter names from the target type's definition instead.
295340 self . gen_params
296341 . params
297342 . iter ( )
@@ -501,44 +546,10 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
501546 let num_params_to_take = num_missing_args;
502547 let msg = format ! ( "add missing {} argument{}" , self . kind( ) , pluralize!( num_missing_args) ) ;
503548
504- // we first try to get lifetime name suggestions from scope or elision information. If none is
505- // available we use the parameter definitions
506- let suggested_args = if let Some ( hir_id) = self . path_segment . hir_id {
507- if let Some ( lifetimes_in_scope) = self . tcx . lifetime_scope ( hir_id) {
508- match lifetimes_in_scope {
509- LifetimeScopeForPath :: NonElided ( param_names) => {
510- debug ! ( "NonElided(param_names: {:?})" , param_names) ;
511-
512- if param_names. len ( ) >= num_params_to_take {
513- // use lifetime parameters in scope for suggestions
514- param_names
515- . iter ( )
516- . take ( num_params_to_take)
517- . map ( |def_id| {
518- self . tcx . item_name ( def_id. to_def_id ( ) ) . to_ident_string ( )
519- } )
520- . collect :: < Vec < _ > > ( )
521- . join ( ", " )
522- } else {
523- // Not enough lifetime arguments in scope -> create suggestions from
524- // lifetime parameter names in definition. An error for the incorrect
525- // lifetime scope will be output later.
526- self . get_lifetime_args_suggestions_from_param_names ( num_params_to_take)
527- }
528- }
529- LifetimeScopeForPath :: Elided => {
530- debug ! ( "Elided" ) ;
531- // use suggestions of the form `<'_, '_>` in case lifetime can be elided
532- [ "'_" ] . repeat ( num_params_to_take) . join ( "," )
533- }
534- }
535- } else {
536- self . get_lifetime_args_suggestions_from_param_names ( num_params_to_take)
537- }
538- } else {
539- self . get_lifetime_args_suggestions_from_param_names ( num_params_to_take)
540- } ;
541-
549+ let suggested_args = self . get_lifetime_args_suggestions_from_param_names (
550+ self . path_segment . hir_id ,
551+ num_params_to_take,
552+ ) ;
542553 debug ! ( "suggested_args: {:?}" , & suggested_args) ;
543554
544555 match self . angle_brackets {
0 commit comments