@@ -31,7 +31,7 @@ use rustc_span::edit_distance::find_best_match_for_name;
3131use rustc_span:: edition:: Edition ;
3232use rustc_span:: hygiene:: MacroKind ;
3333use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
34- use rustc_span:: Span ;
34+ use rustc_span:: { Span , DUMMY_SP } ;
3535
3636use rustc_middle:: ty;
3737
@@ -2718,10 +2718,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
27182718 suggest : impl Fn ( & mut Diag < ' _ > , bool , Span , Cow < ' static , str > , String ) -> bool ,
27192719 ) {
27202720 let mut suggest_note = true ;
2721+
27212722 for rib in self . lifetime_ribs . iter ( ) . rev ( ) {
27222723 let mut should_continue = true ;
27232724 match rib. kind {
2724- LifetimeRibKind :: Generics { binder : _ , span, kind } => {
2725+ LifetimeRibKind :: Generics { binder : node_id , span, kind } => {
27252726 // Avoid suggesting placing lifetime parameters on constant items unless the relevant
27262727 // feature is enabled. Suggest the parent item as a possible location if applicable.
27272728 if let LifetimeBinderKind :: ConstItem = kind
@@ -2750,14 +2751,48 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
27502751 | LifetimeBinderKind :: PolyTrait
27512752 | LifetimeBinderKind :: WhereBound
27522753 ) ;
2753- let ( span, sugg) = if span. is_empty ( ) {
2754+
2755+ let ( span, sugg, rm_poly_trait_span) = if span. is_empty ( ) {
2756+ let ( generic_params, poly_trait_span, trait_ref_span) =
2757+ if let Some ( with_poly_trait_ref) =
2758+ self . with_poly_trait_ref . get ( & node_id)
2759+ && higher_ranked
2760+ {
2761+ let generic_params = with_poly_trait_ref
2762+ . generic_param_idents
2763+ . iter ( )
2764+ . fold ( "" . to_string ( ) , |mut generic_params, x| {
2765+ generic_params += x. as_str ( ) ;
2766+ generic_params += ", " ;
2767+ generic_params
2768+ } ) ;
2769+ (
2770+ generic_params,
2771+ with_poly_trait_ref. poly_trait ,
2772+ with_poly_trait_ref. trait_ref ,
2773+ )
2774+ } else {
2775+ ( "" . to_string ( ) , DUMMY_SP , DUMMY_SP )
2776+ } ;
2777+
2778+ let rm_poly_trait_span = if generic_params. is_empty ( ) {
2779+ DUMMY_SP
2780+ } else {
2781+ poly_trait_span. with_hi ( trait_ref_span. lo ( ) )
2782+ } ;
2783+
2784+ let lifetime_list = format ! ( "{}{}" , generic_params, name. unwrap_or( "'a" ) ) ;
27542785 let sugg = format ! (
27552786 "{}<{}>{}" ,
27562787 if higher_ranked { "for" } else { "" } ,
2757- name. unwrap_or( "'a" ) ,
2788+ if generic_params. is_empty( ) {
2789+ name. unwrap_or( "'a" )
2790+ } else {
2791+ & lifetime_list
2792+ } ,
27582793 if higher_ranked { " " } else { "" } ,
27592794 ) ;
2760- ( span, sugg)
2795+ ( span, sugg, rm_poly_trait_span )
27612796 } else {
27622797 let span = self
27632798 . r
@@ -2767,15 +2802,30 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
27672802 . span_through_char ( span, '<' )
27682803 . shrink_to_hi ( ) ;
27692804 let sugg = format ! ( "{}, " , name. unwrap_or( "'a" ) ) ;
2770- ( span, sugg)
2805+ ( span, sugg, DUMMY_SP )
27712806 } ;
2807+
27722808 if higher_ranked {
27732809 let message = Cow :: from ( format ! (
27742810 "consider making the {} lifetime-generic with a new `{}` lifetime" ,
27752811 kind. descr( ) ,
27762812 name. unwrap_or( "'a" ) ,
27772813 ) ) ;
2778- should_continue = suggest ( err, true , span, message, sugg) ;
2814+ should_continue = if !rm_poly_trait_span. is_dummy ( ) {
2815+ // For poly-trait-ref like `for<'a> Trait<T>` in
2816+ // `T: for<'a> Trait<T> + 'b { }`.
2817+ // We should merge the higher-ranked lifetimes: existed `for<'a>` and suggestion `for<'b>`
2818+ // or will get err:
2819+ // `[E0316] nested quantification of lifetimes`.
2820+ err. multipart_suggestion_verbose (
2821+ message,
2822+ vec ! [ ( span, sugg) , ( rm_poly_trait_span, "" . to_string( ) ) ] ,
2823+ Applicability :: MaybeIncorrect ,
2824+ ) ;
2825+ false
2826+ } else {
2827+ suggest ( err, true , span, message. clone ( ) , sugg. clone ( ) )
2828+ } ;
27792829 err. note_once (
27802830 "for more information on higher-ranked polymorphism, visit \
27812831 https://doc.rust-lang.org/nomicon/hrtb.html",
@@ -3298,7 +3348,6 @@ fn mk_where_bound_predicate(
32983348 poly_trait_ref : & ast:: PolyTraitRef ,
32993349 ty : & Ty ,
33003350) -> Option < ast:: WhereBoundPredicate > {
3301- use rustc_span:: DUMMY_SP ;
33023351 let modified_segments = {
33033352 let mut segments = path. segments . clone ( ) ;
33043353 let [ preceding @ .., second_last, last] = segments. as_mut_slice ( ) else {
0 commit comments