@@ -8,8 +8,10 @@ use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorRepor
88use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
99use rustc_hir:: intravisit:: { walk_ty, ErasedMap , NestedVisitorMap , Visitor } ;
1010use rustc_hir:: { self as hir, GenericBound , Item , ItemKind , Lifetime , LifetimeName , Node , TyKind } ;
11- use rustc_middle:: ty:: { self , AssocItemContainer , RegionKind , Ty , TypeFoldable , TypeVisitor } ;
12- use rustc_span:: Span ;
11+ use rustc_middle:: ty:: {
12+ self , AssocItem , AssocItemContainer , RegionKind , Ty , TypeFoldable , TypeVisitor ,
13+ } ;
14+ use rustc_span:: { MultiSpan , Span } ;
1315
1416impl < ' a , ' tcx > NiceRegionError < ' a , ' tcx > {
1517 /// Print the error message for lifetime errors when the return type is a static impl Trait.
@@ -51,7 +53,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
5153 cause. span ,
5254 "...is captured and required to live as long as `'static` here" ,
5355 ) ;
54- if self . find_impl_on_dyn_trait ( & mut err, param. param_ty , & assoc. container ) {
56+ if self . find_impl_on_dyn_trait ( & mut err, param. param_ty , assoc) {
5557 err. emit ( ) ;
5658 return Some ( ErrorReported ) ;
5759 } else {
@@ -131,7 +133,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
131133
132134 if let SubregionOrigin :: Subtype ( box TypeTrace { cause, .. } ) = & sup_origin {
133135 if let ObligationCauseCode :: UnifyReceiver ( assoc) = & cause. code {
134- self . find_impl_on_dyn_trait ( & mut err, param. param_ty , & assoc. container ) ;
136+ self . find_impl_on_dyn_trait ( & mut err, param. param_ty , assoc) ;
135137 }
136138 }
137139
@@ -263,7 +265,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
263265 & self ,
264266 err : & mut DiagnosticBuilder < ' _ > ,
265267 ty : Ty < ' _ > ,
266- container : & AssocItemContainer ,
268+ assoc : & AssocItem ,
267269 ) -> bool {
268270 let tcx = self . tcx ( ) ;
269271 let mut suggested = false ;
@@ -272,7 +274,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
272274 let mut v = TraitObjectVisitor ( vec ! [ ] ) ;
273275 v. visit_ty ( ty) ;
274276
275- let container_id = match container {
277+ let container_id = match assoc . container {
276278 // When the obligation comes from an `impl Foo for dyn Bar {}`, we
277279 // have the `DefId` of the `trait` itself, not the relevant `impl`
278280 // block. Because of this, we have to look at all the `trait`s
@@ -284,16 +286,35 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
284286 // have the `DefId` of the relevant `Item`, so we use it directly.
285287 AssocItemContainer :: ImplContainer ( def_id) => {
286288 if let Some ( Node :: Item ( Item { kind : ItemKind :: Impl { self_ty, .. } , .. } ) ) =
287- tcx. hir ( ) . get_if_local ( * def_id)
289+ tcx. hir ( ) . get_if_local ( def_id)
288290 {
289291 for found_did in & v. 0 {
290292 let mut hir_v = HirTraitObjectVisitor ( vec ! [ ] , * found_did) ;
291293 hir_v. visit_ty ( self_ty) ;
292294 if let [ span] = & hir_v. 0 [ ..] {
295+ let mut multi_span: MultiSpan = vec ! [ * span] . into ( ) ;
296+ multi_span. push_span_label (
297+ * span,
298+ "this trait object has an implicit `'static` lifetime requirement"
299+ . to_string ( ) ,
300+ ) ;
301+ multi_span. push_span_label (
302+ assoc. ident . span ,
303+ "the `'static` requirement is introduced when calling this method"
304+ . to_string ( ) ,
305+ ) ;
306+ err. span_note (
307+ multi_span,
308+ & format ! (
309+ "when using method `{}` on `{}`, an implicit `'static` \
310+ requirement is introduced",
311+ assoc. ident,
312+ tcx. def_path_str( * found_did) ,
313+ ) ,
314+ ) ;
293315 err. span_suggestion_verbose (
294316 span. shrink_to_hi ( ) ,
295- "this `impl` introduces an implicit `'static` requirement, \
296- consider changing it",
317+ "consider relaxing the implicit `'static` requirement" ,
297318 " + '_" . to_string ( ) ,
298319 Applicability :: MaybeIncorrect ,
299320 ) ;
@@ -316,24 +337,53 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
316337 let impl_did = tcx. hir ( ) . local_def_id ( * impl_node) ;
317338 match tcx. hir ( ) . get_if_local ( impl_did. to_def_id ( ) ) {
318339 Some ( Node :: Item ( Item {
319- kind : ItemKind :: Impl { self_ty, of_trait : Some ( of_trait) , .. } ,
340+ kind : ItemKind :: Impl { self_ty, of_trait : Some ( of_trait) , items , .. } ,
320341 ..
321- } ) ) if of_trait. trait_def_id ( ) == Some ( * container_id) => Some ( self_ty) ,
342+ } ) ) if of_trait. trait_def_id ( ) == Some ( container_id) => Some ( (
343+ self_ty,
344+ // Get the ident of the method, in order to use its `Span`.
345+ items
346+ . iter ( )
347+ . filter ( |item| item. ident == assoc. ident )
348+ . map ( |item| item. ident )
349+ . next ( )
350+ . unwrap_or ( assoc. ident ) ,
351+ ) ) ,
322352 _ => None ,
323353 }
324354 } ) ;
325355
326356 // Given all the `impl`s of the relevant `trait`, look for those that are implemented for
327357 // the trait object in the `fn` parameter type.
328- for self_ty in impl_self_tys {
358+ for ( self_ty, method ) in impl_self_tys {
329359 for found_did in & v. 0 {
330360 let mut hir_v = HirTraitObjectVisitor ( vec ! [ ] , * found_did) ;
331361 hir_v. visit_ty ( self_ty) ;
332362 if let [ span] = & hir_v. 0 [ ..] {
363+ let mut multi_span: MultiSpan = vec ! [ * span] . into ( ) ;
364+ multi_span. push_span_label (
365+ * span,
366+ "this trait object has an implicit `'static` lifetime requirement"
367+ . to_string ( ) ,
368+ ) ;
369+ multi_span. push_span_label (
370+ method. span ,
371+ "the `'static` requirement is introduced when calling this method"
372+ . to_string ( ) ,
373+ ) ;
374+ err. span_note (
375+ multi_span,
376+ & format ! (
377+ "when using method `{}` of trait `{}` on `{}`, an implicit `'static` \
378+ requirement is introduced",
379+ method,
380+ tcx. def_path_str( container_id) ,
381+ tcx. def_path_str( * found_did) ,
382+ ) ,
383+ ) ;
333384 err. span_suggestion_verbose (
334385 span. shrink_to_hi ( ) ,
335- "this `impl` introduces an implicit `'static` requirement, \
336- consider changing it",
386+ "consider relaxing the implicit `'static` requirement" ,
337387 " + '_" . to_string ( ) ,
338388 Applicability :: MaybeIncorrect ,
339389 ) ;
0 commit comments