@@ -13,8 +13,8 @@ use rustc_errors::{AddToDiagnostic, Applicability, Diag, ErrorGuaranteed, MultiS
13
13
use rustc_hir:: def_id:: DefId ;
14
14
use rustc_hir:: intravisit:: { walk_ty, Visitor } ;
15
15
use rustc_hir:: {
16
- self as hir, GenericBound , GenericParamKind , Item , ItemKind , Lifetime , LifetimeName ,
17
- LifetimeParamKind , MissingLifetimeKind , Node , TyKind ,
16
+ self as hir, GenericBound , GenericParam , GenericParamKind , Item , ItemKind , Lifetime ,
17
+ LifetimeName , LifetimeParamKind , MissingLifetimeKind , Node , TyKind ,
18
18
} ;
19
19
use rustc_middle:: ty:: {
20
20
self , AssocItemContainer , StaticLifetimeVisitor , Ty , TyCtxt , TypeSuperVisitable , TypeVisitor ,
@@ -356,87 +356,8 @@ pub fn suggest_new_region_bound(
356
356
// introducing a new lifetime `'a` or making use of one from existing named lifetimes if any
357
357
if let Some ( id) = scope_def_id
358
358
&& let Some ( generics) = tcx. hir ( ) . get_generics ( id)
359
- && let mut spans_suggs = {
360
- fn finish_bracket (
361
- suggs : & mut Vec < ( Span , String ) > ,
362
- name : & str ,
363
- bracket_span : & mut Option < Span > ,
364
- brackets : & mut usize ,
365
- ) {
366
- if let Some ( span) = bracket_span. take ( ) {
367
- let sugg: String = std:: iter:: once ( "<" )
368
- . chain (
369
- std:: iter:: repeat ( name)
370
- . take ( * brackets)
371
- . intersperse ( ", " ) ,
372
- )
373
- . chain ( [ ">" ] )
374
- . collect ( ) ;
375
- suggs. push ( ( span. shrink_to_hi ( ) , sugg) ) ;
376
- * brackets = 0 ;
377
- }
378
- }
379
- let mut spans_suggs = Vec :: new ( ) ;
380
- let mut bracket_span = None :: < Span > ;
381
- let mut brackets = 0 ;
382
- for p in generics. params {
383
- if let GenericParamKind :: Lifetime {
384
- kind : LifetimeParamKind :: Elided ( kind) ,
385
- } = p. kind
386
- {
387
- match kind {
388
- MissingLifetimeKind :: Underscore => {
389
- finish_bracket (
390
- & mut spans_suggs,
391
- name,
392
- & mut bracket_span,
393
- & mut brackets,
394
- ) ;
395
- spans_suggs. push ( ( p. span , name. to_string ( ) ) ) ;
396
- }
397
- MissingLifetimeKind :: Ampersand => {
398
- finish_bracket (
399
- & mut spans_suggs,
400
- name,
401
- & mut bracket_span,
402
- & mut brackets,
403
- ) ;
404
- spans_suggs
405
- . push ( ( p. span . shrink_to_hi ( ) , format ! ( "{name} " ) ) ) ;
406
- }
407
- MissingLifetimeKind :: Comma => {
408
- finish_bracket (
409
- & mut spans_suggs,
410
- name,
411
- & mut bracket_span,
412
- & mut brackets,
413
- ) ;
414
- spans_suggs
415
- . push ( ( p. span . shrink_to_hi ( ) , format ! ( "{name}, " ) ) ) ;
416
- }
417
- MissingLifetimeKind :: Brackets => {
418
- if bracket_span. is_some_and ( |span| span != p. span ) {
419
- finish_bracket (
420
- & mut spans_suggs,
421
- name,
422
- & mut bracket_span,
423
- & mut brackets,
424
- ) ;
425
- }
426
- bracket_span = Some ( p. span ) ;
427
- brackets += 1 ;
428
- }
429
- }
430
- }
431
- }
432
- finish_bracket (
433
- & mut spans_suggs,
434
- name,
435
- & mut bracket_span,
436
- & mut brackets,
437
- ) ;
438
- spans_suggs
439
- }
359
+ && let mut spans_suggs =
360
+ make_lifetime_spans_suggs ( name, generics. params . iter ( ) )
440
361
&& spans_suggs. len ( ) > 1
441
362
{
442
363
let use_lt = if existing_lt_name == None {
@@ -498,6 +419,57 @@ pub fn suggest_new_region_bound(
498
419
}
499
420
}
500
421
422
+ fn make_lifetime_spans_suggs < ' a > (
423
+ name : & str ,
424
+ generic_params : impl Iterator < Item = & ' a GenericParam < ' a > > ,
425
+ ) -> Vec < ( Span , String ) > {
426
+ let mut spans_suggs = Vec :: new ( ) ;
427
+ let mut bracket_span = None ;
428
+ let mut consecutive_brackets = 0 ;
429
+
430
+ let mut process_consecutive_brackets =
431
+ |span : Option < Span > , spans_suggs : & mut Vec < ( Span , String ) > | {
432
+ if span
433
+ . is_some_and ( |span| bracket_span. map_or ( true , |bracket_span| span == bracket_span) )
434
+ {
435
+ consecutive_brackets += 1 ;
436
+ } else if let Some ( bracket_span) = bracket_span. take ( ) {
437
+ let sugg = std:: iter:: once ( "<" )
438
+ . chain ( std:: iter:: repeat ( name) . take ( consecutive_brackets) . intersperse ( ", " ) )
439
+ . chain ( [ ">" ] )
440
+ . collect ( ) ;
441
+ spans_suggs. push ( ( bracket_span. shrink_to_hi ( ) , sugg) ) ;
442
+ consecutive_brackets = 0 ;
443
+ }
444
+ bracket_span = span;
445
+ } ;
446
+
447
+ for p in generic_params {
448
+ if let GenericParamKind :: Lifetime { kind : LifetimeParamKind :: Elided ( kind) } = p. kind {
449
+ match kind {
450
+ MissingLifetimeKind :: Underscore => {
451
+ process_consecutive_brackets ( None , & mut spans_suggs) ;
452
+ spans_suggs. push ( ( p. span , name. to_string ( ) ) )
453
+ }
454
+ MissingLifetimeKind :: Ampersand => {
455
+ process_consecutive_brackets ( None , & mut spans_suggs) ;
456
+ spans_suggs. push ( ( p. span . shrink_to_hi ( ) , format ! ( "{name} " ) ) ) ;
457
+ }
458
+ MissingLifetimeKind :: Comma => {
459
+ process_consecutive_brackets ( None , & mut spans_suggs) ;
460
+ spans_suggs. push ( ( p. span . shrink_to_hi ( ) , format ! ( "{name}, " ) ) ) ;
461
+ }
462
+ MissingLifetimeKind :: Brackets => {
463
+ process_consecutive_brackets ( Some ( p. span ) , & mut spans_suggs) ;
464
+ }
465
+ }
466
+ }
467
+ }
468
+ process_consecutive_brackets ( None , & mut spans_suggs) ;
469
+
470
+ spans_suggs
471
+ }
472
+
501
473
impl < ' a , ' tcx > NiceRegionError < ' a , ' tcx > {
502
474
pub fn get_impl_ident_and_self_ty_from_trait (
503
475
tcx : TyCtxt < ' tcx > ,
0 commit comments