@@ -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,53 @@ 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
+ debug ! ( "surechen1 with_poly_trait_ref:{:?}" , with_poly_trait_ref) ;
2762
+ let mut generic_params = with_poly_trait_ref
2763
+ . generic_param_idents
2764
+ . iter ( )
2765
+ . fold ( "" . to_string ( ) , |mut generic_params, x| {
2766
+ generic_params += x. as_str ( ) ;
2767
+ generic_params += "," ;
2768
+ generic_params
2769
+ } ) ;
2770
+ if !generic_params. is_empty ( ) {
2771
+ generic_params =
2772
+ generic_params[ 0 ..generic_params. len ( ) - 1 ] . to_string ( ) ;
2773
+ }
2774
+ (
2775
+ generic_params,
2776
+ with_poly_trait_ref. poly_trait ,
2777
+ with_poly_trait_ref. trait_ref ,
2778
+ )
2779
+ } else {
2780
+ ( "" . to_string ( ) , DUMMY_SP , DUMMY_SP )
2781
+ } ;
2782
+
2783
+ let rm_poly_trait_span = if generic_params. is_empty ( ) {
2784
+ DUMMY_SP
2785
+ } else {
2786
+ poly_trait_span. with_hi ( trait_ref_span. lo ( ) )
2787
+ } ;
2788
+
2789
+ let lifetime_list = format ! ( "{},{}" , generic_params, name. unwrap_or( "'a" ) ) ;
2754
2790
let sugg = format ! (
2755
2791
"{}<{}>{}" ,
2756
2792
if higher_ranked { "for" } else { "" } ,
2757
- name. unwrap_or( "'a" ) ,
2793
+ if generic_params. is_empty( ) {
2794
+ name. unwrap_or( "'a" )
2795
+ } else {
2796
+ & lifetime_list
2797
+ } ,
2758
2798
if higher_ranked { " " } else { "" } ,
2759
2799
) ;
2760
- ( span, sugg)
2800
+ ( span, sugg, rm_poly_trait_span )
2761
2801
} else {
2762
2802
let span = self
2763
2803
. r
@@ -2767,15 +2807,30 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
2767
2807
. span_through_char ( span, '<' )
2768
2808
. shrink_to_hi ( ) ;
2769
2809
let sugg = format ! ( "{}, " , name. unwrap_or( "'a" ) ) ;
2770
- ( span, sugg)
2810
+ ( span, sugg, DUMMY_SP )
2771
2811
} ;
2812
+
2772
2813
if higher_ranked {
2773
2814
let message = Cow :: from ( format ! (
2774
2815
"consider making the {} lifetime-generic with a new `{}` lifetime" ,
2775
2816
kind. descr( ) ,
2776
2817
name. unwrap_or( "'a" ) ,
2777
2818
) ) ;
2778
- should_continue = suggest ( err, true , span, message, sugg) ;
2819
+ should_continue = if !rm_poly_trait_span. is_dummy ( ) {
2820
+ // For poly-trait-ref like `for<'a> Trait<T>` in
2821
+ // `T: for<'a> Trait<T> + 'b { }`.
2822
+ // We should merge the higher-ranked lifetimes: existed `for<'a>` and suggestion `for<'b>`
2823
+ // or will get another err:
2824
+ // `[E0316] nested quantification of lifetimes`.
2825
+ err. multipart_suggestion_verbose (
2826
+ message,
2827
+ vec ! [ ( span, sugg) , ( rm_poly_trait_span, "" . to_string( ) ) ] ,
2828
+ Applicability :: MaybeIncorrect ,
2829
+ ) ;
2830
+ false
2831
+ } else {
2832
+ suggest ( err, true , span, message. clone ( ) , sugg. clone ( ) )
2833
+ } ;
2779
2834
err. note_once (
2780
2835
"for more information on higher-ranked polymorphism, visit \
2781
2836
https://doc.rust-lang.org/nomicon/hrtb.html",
@@ -3298,7 +3353,6 @@ fn mk_where_bound_predicate(
3298
3353
poly_trait_ref : & ast:: PolyTraitRef ,
3299
3354
ty : & Ty ,
3300
3355
) -> Option < ast:: WhereBoundPredicate > {
3301
- use rustc_span:: DUMMY_SP ;
3302
3356
let modified_segments = {
3303
3357
let mut segments = path. segments . clone ( ) ;
3304
3358
let [ preceding @ .., second_last, last] = segments. as_mut_slice ( ) else {
0 commit comments