@@ -31,7 +31,7 @@ use rustc_span::edit_distance::find_best_match_for_name;
31
31
use rustc_span:: edition:: Edition ;
32
32
use rustc_span:: hygiene:: MacroKind ;
33
33
use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
34
- use rustc_span:: Span ;
34
+ use rustc_span:: { Span , DUMMY_SP } ;
35
35
36
36
use rustc_middle:: ty;
37
37
@@ -2718,10 +2718,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
2718
2718
suggest : impl Fn ( & mut Diag < ' _ > , bool , Span , Cow < ' static , str > , String ) -> bool ,
2719
2719
) {
2720
2720
let mut suggest_note = true ;
2721
+
2721
2722
for rib in self . lifetime_ribs . iter ( ) . rev ( ) {
2722
2723
let mut should_continue = true ;
2723
2724
match rib. kind {
2724
- LifetimeRibKind :: Generics { binder : _ , span, kind } => {
2725
+ LifetimeRibKind :: Generics { binder : node_id , span, kind } => {
2725
2726
// Avoid suggesting placing lifetime parameters on constant items unless the relevant
2726
2727
// feature is enabled. Suggest the parent item as a possible location if applicable.
2727
2728
if let LifetimeBinderKind :: ConstItem = kind
@@ -2750,14 +2751,48 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
2750
2751
| LifetimeBinderKind :: PolyTrait
2751
2752
| LifetimeBinderKind :: WhereBound
2752
2753
) ;
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" ) ) ;
2754
2785
let sugg = format ! (
2755
2786
"{}<{}>{}" ,
2756
2787
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
+ } ,
2758
2793
if higher_ranked { " " } else { "" } ,
2759
2794
) ;
2760
- ( span, sugg)
2795
+ ( span, sugg, rm_poly_trait_span )
2761
2796
} else {
2762
2797
let span = self
2763
2798
. r
@@ -2767,15 +2802,30 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
2767
2802
. span_through_char ( span, '<' )
2768
2803
. shrink_to_hi ( ) ;
2769
2804
let sugg = format ! ( "{}, " , name. unwrap_or( "'a" ) ) ;
2770
- ( span, sugg)
2805
+ ( span, sugg, DUMMY_SP )
2771
2806
} ;
2807
+
2772
2808
if higher_ranked {
2773
2809
let message = Cow :: from ( format ! (
2774
2810
"consider making the {} lifetime-generic with a new `{}` lifetime" ,
2775
2811
kind. descr( ) ,
2776
2812
name. unwrap_or( "'a" ) ,
2777
2813
) ) ;
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
+ } ;
2779
2829
err. note_once (
2780
2830
"for more information on higher-ranked polymorphism, visit \
2781
2831
https://doc.rust-lang.org/nomicon/hrtb.html",
@@ -3298,7 +3348,6 @@ fn mk_where_bound_predicate(
3298
3348
poly_trait_ref : & ast:: PolyTraitRef ,
3299
3349
ty : & Ty ,
3300
3350
) -> Option < ast:: WhereBoundPredicate > {
3301
- use rustc_span:: DUMMY_SP ;
3302
3351
let modified_segments = {
3303
3352
let mut segments = path. segments . clone ( ) ;
3304
3353
let [ preceding @ .., second_last, last] = segments. as_mut_slice ( ) else {
0 commit comments