@@ -6,7 +6,7 @@ use rustc_hir as hir;
6
6
use rustc_hir:: def:: { DefKind , Res } ;
7
7
use rustc_middle:: ty:: print:: RegionHighlightMode ;
8
8
use rustc_middle:: ty:: subst:: { GenericArgKind , SubstsRef } ;
9
- use rustc_middle:: ty:: { self , RegionVid , Ty } ;
9
+ use rustc_middle:: ty:: { self , DefIdTree , RegionVid , Ty } ;
10
10
use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
11
11
use rustc_span:: { Span , DUMMY_SP } ;
12
12
@@ -45,6 +45,8 @@ pub(crate) enum RegionNameSource {
45
45
AnonRegionFromYieldTy ( Span , String ) ,
46
46
/// An anonymous region from an async fn.
47
47
AnonRegionFromAsyncFn ( Span ) ,
48
+ /// An anonymous region from an impl self type or trait
49
+ AnonRegionFromImplSignature ( Span , & ' static str ) ,
48
50
}
49
51
50
52
/// Describes what to highlight to explain to the user that we're giving an anonymous region a
@@ -75,7 +77,8 @@ impl RegionName {
75
77
| RegionNameSource :: AnonRegionFromUpvar ( ..)
76
78
| RegionNameSource :: AnonRegionFromOutput ( ..)
77
79
| RegionNameSource :: AnonRegionFromYieldTy ( ..)
78
- | RegionNameSource :: AnonRegionFromAsyncFn ( ..) => false ,
80
+ | RegionNameSource :: AnonRegionFromAsyncFn ( ..)
81
+ | RegionNameSource :: AnonRegionFromImplSignature ( ..) => false ,
79
82
}
80
83
}
81
84
@@ -87,7 +90,8 @@ impl RegionName {
87
90
| RegionNameSource :: SynthesizedFreeEnvRegion ( span, _)
88
91
| RegionNameSource :: AnonRegionFromUpvar ( span, _)
89
92
| RegionNameSource :: AnonRegionFromYieldTy ( span, _)
90
- | RegionNameSource :: AnonRegionFromAsyncFn ( span) => Some ( span) ,
93
+ | RegionNameSource :: AnonRegionFromAsyncFn ( span)
94
+ | RegionNameSource :: AnonRegionFromImplSignature ( span, _) => Some ( span) ,
91
95
RegionNameSource :: AnonRegionFromArgument ( ref highlight)
92
96
| RegionNameSource :: AnonRegionFromOutput ( ref highlight, _) => match * highlight {
93
97
RegionNameHighlight :: MatchedHirTy ( span)
@@ -166,6 +170,12 @@ impl RegionName {
166
170
RegionNameSource :: AnonRegionFromYieldTy ( span, type_name) => {
167
171
diag. span_label ( * span, format ! ( "yield type is {type_name}" ) ) ;
168
172
}
173
+ RegionNameSource :: AnonRegionFromImplSignature ( span, location) => {
174
+ diag. span_label (
175
+ * span,
176
+ format ! ( "lifetime `{self}` appears in the `impl`'s {location}" ) ,
177
+ ) ;
178
+ }
169
179
RegionNameSource :: Static => { }
170
180
}
171
181
}
@@ -240,7 +250,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
240
250
. or_else ( || self . give_name_if_anonymous_region_appears_in_arguments ( fr) )
241
251
. or_else ( || self . give_name_if_anonymous_region_appears_in_upvars ( fr) )
242
252
. or_else ( || self . give_name_if_anonymous_region_appears_in_output ( fr) )
243
- . or_else ( || self . give_name_if_anonymous_region_appears_in_yield_ty ( fr) ) ;
253
+ . or_else ( || self . give_name_if_anonymous_region_appears_in_yield_ty ( fr) )
254
+ . or_else ( || self . give_name_if_anonymous_region_appears_in_impl_signature ( fr) ) ;
244
255
245
256
if let Some ( ref value) = value {
246
257
self . region_names . try_borrow_mut ( ) . unwrap ( ) . insert ( fr, value. clone ( ) ) ;
@@ -840,4 +851,43 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
840
851
source : RegionNameSource :: AnonRegionFromYieldTy ( yield_span, type_name) ,
841
852
} )
842
853
}
854
+
855
+ fn give_name_if_anonymous_region_appears_in_impl_signature (
856
+ & self ,
857
+ fr : RegionVid ,
858
+ ) -> Option < RegionName > {
859
+ let ty:: ReEarlyBound ( region) = * self . to_error_region ( fr) ? else {
860
+ return None ;
861
+ } ;
862
+ if region. has_name ( ) {
863
+ return None ;
864
+ } ;
865
+
866
+ let tcx = self . infcx . tcx ;
867
+ let body_parent_did = tcx. opt_parent ( self . mir_def_id ( ) . to_def_id ( ) ) ?;
868
+ if tcx. parent ( region. def_id ) != body_parent_did
869
+ || tcx. def_kind ( body_parent_did) != DefKind :: Impl
870
+ {
871
+ return None ;
872
+ }
873
+
874
+ let mut found = false ;
875
+ tcx. fold_regions ( tcx. type_of ( body_parent_did) , & mut true , |r : ty:: Region < ' tcx > , _| {
876
+ if * r == ty:: ReEarlyBound ( region) {
877
+ found = true ;
878
+ }
879
+ r
880
+ } ) ;
881
+
882
+ Some ( RegionName {
883
+ name : self . synthesize_region_name ( ) ,
884
+ source : RegionNameSource :: AnonRegionFromImplSignature (
885
+ tcx. def_span ( region. def_id ) ,
886
+ // FIXME(compiler-errors): Does this ever actually show up
887
+ // anywhere other than the self type? I couldn't create an
888
+ // example of a `'_` in the impl's trait being referenceable.
889
+ if found { "self type" } else { "header" } ,
890
+ ) ,
891
+ } )
892
+ }
843
893
}
0 commit comments