@@ -6,7 +6,7 @@ use rustc_hir as hir;
66use rustc_hir:: def:: { DefKind , Res } ;
77use rustc_middle:: ty:: print:: RegionHighlightMode ;
88use rustc_middle:: ty:: subst:: { GenericArgKind , SubstsRef } ;
9- use rustc_middle:: ty:: { self , RegionVid , Ty } ;
9+ use rustc_middle:: ty:: { self , DefIdTree , RegionVid , Ty } ;
1010use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
1111use rustc_span:: { Span , DUMMY_SP } ;
1212
@@ -45,6 +45,8 @@ pub(crate) enum RegionNameSource {
4545 AnonRegionFromYieldTy ( Span , String ) ,
4646 /// An anonymous region from an async fn.
4747 AnonRegionFromAsyncFn ( Span ) ,
48+ /// An anonymous region from an impl self type or trait
49+ AnonRegionFromImplSignature ( Span , & ' static str ) ,
4850}
4951
5052/// Describes what to highlight to explain to the user that we're giving an anonymous region a
@@ -75,7 +77,8 @@ impl RegionName {
7577 | RegionNameSource :: AnonRegionFromUpvar ( ..)
7678 | RegionNameSource :: AnonRegionFromOutput ( ..)
7779 | RegionNameSource :: AnonRegionFromYieldTy ( ..)
78- | RegionNameSource :: AnonRegionFromAsyncFn ( ..) => false ,
80+ | RegionNameSource :: AnonRegionFromAsyncFn ( ..)
81+ | RegionNameSource :: AnonRegionFromImplSignature ( ..) => false ,
7982 }
8083 }
8184
@@ -87,7 +90,8 @@ impl RegionName {
8790 | RegionNameSource :: SynthesizedFreeEnvRegion ( span, _)
8891 | RegionNameSource :: AnonRegionFromUpvar ( span, _)
8992 | RegionNameSource :: AnonRegionFromYieldTy ( span, _)
90- | RegionNameSource :: AnonRegionFromAsyncFn ( span) => Some ( span) ,
93+ | RegionNameSource :: AnonRegionFromAsyncFn ( span)
94+ | RegionNameSource :: AnonRegionFromImplSignature ( span, _) => Some ( span) ,
9195 RegionNameSource :: AnonRegionFromArgument ( ref highlight)
9296 | RegionNameSource :: AnonRegionFromOutput ( ref highlight, _) => match * highlight {
9397 RegionNameHighlight :: MatchedHirTy ( span)
@@ -166,6 +170,12 @@ impl RegionName {
166170 RegionNameSource :: AnonRegionFromYieldTy ( span, type_name) => {
167171 diag. span_label ( * span, format ! ( "yield type is {type_name}" ) ) ;
168172 }
173+ RegionNameSource :: AnonRegionFromImplSignature ( span, location) => {
174+ diag. span_label (
175+ * span,
176+ format ! ( "lifetime `{self}` appears in the `impl`'s {location}" ) ,
177+ ) ;
178+ }
169179 RegionNameSource :: Static => { }
170180 }
171181 }
@@ -240,7 +250,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
240250 . or_else ( || self . give_name_if_anonymous_region_appears_in_arguments ( fr) )
241251 . or_else ( || self . give_name_if_anonymous_region_appears_in_upvars ( fr) )
242252 . 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) ) ;
244255
245256 if let Some ( ref value) = value {
246257 self . region_names . try_borrow_mut ( ) . unwrap ( ) . insert ( fr, value. clone ( ) ) ;
@@ -847,4 +858,43 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
847858 source : RegionNameSource :: AnonRegionFromYieldTy ( yield_span, type_name) ,
848859 } )
849860 }
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+ }
850900}
0 commit comments