@@ -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 ( ) ) ;
@@ -847,4 +858,43 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
847
858
source : RegionNameSource :: AnonRegionFromYieldTy ( yield_span, type_name) ,
848
859
} )
849
860
}
861
+
862
+ fn give_name_if_anonymous_region_appears_in_impl_signature (
863
+ & self ,
864
+ fr : RegionVid ,
865
+ ) -> Option < RegionName > {
866
+ let ty:: ReEarlyBound ( region) = * self . to_error_region ( fr) ? else {
867
+ return None ;
868
+ } ;
869
+ if region. has_name ( ) {
870
+ return None ;
871
+ } ;
872
+
873
+ let tcx = self . infcx . tcx ;
874
+ let body_parent_did = tcx. opt_parent ( self . mir_def_id ( ) . to_def_id ( ) ) ?;
875
+ if tcx. parent ( region. def_id ) != body_parent_did
876
+ || tcx. def_kind ( body_parent_did) != DefKind :: Impl
877
+ {
878
+ return None ;
879
+ }
880
+
881
+ let mut found = false ;
882
+ tcx. fold_regions ( tcx. type_of ( body_parent_did) , & mut true , |r : ty:: Region < ' tcx > , _| {
883
+ if * r == ty:: ReEarlyBound ( region) {
884
+ found = true ;
885
+ }
886
+ r
887
+ } ) ;
888
+
889
+ Some ( RegionName {
890
+ name : self . synthesize_region_name ( ) ,
891
+ source : RegionNameSource :: AnonRegionFromImplSignature (
892
+ tcx. def_span ( region. def_id ) ,
893
+ // FIXME(compiler-errors): Does this ever actually show up
894
+ // anywhere other than the self type? I couldn't create an
895
+ // example of a `'_` in the impl's trait being referenceable.
896
+ if found { "self type" } else { "header" } ,
897
+ ) ,
898
+ } )
899
+ }
850
900
}
0 commit comments