@@ -291,7 +291,52 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
291
291
}
292
292
293
293
// 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.
295
340
self . gen_params
296
341
. params
297
342
. iter ( )
@@ -501,44 +546,10 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
501
546
let num_params_to_take = num_missing_args;
502
547
let msg = format ! ( "add missing {} argument{}" , self . kind( ) , pluralize!( num_missing_args) ) ;
503
548
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
+ ) ;
542
553
debug ! ( "suggested_args: {:?}" , & suggested_args) ;
543
554
544
555
match self . angle_brackets {
0 commit comments