@@ -7,6 +7,7 @@ use rustc_attr as attr;
77use rustc_errors:: { Applicability , ErrorReported } ;
88use rustc_hir as hir;
99use rustc_hir:: def_id:: { DefId , LocalDefId , LOCAL_CRATE } ;
10+ use rustc_hir:: intravisit:: Visitor ;
1011use rustc_hir:: lang_items:: LangItem ;
1112use rustc_hir:: { ItemKind , Node } ;
1213use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
@@ -557,6 +558,8 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
557558 ) ;
558559
559560 if let Some ( ty) = prohibit_opaque. break_value ( ) {
561+ let mut visitor = SelfTySpanVisitor { tcx, selfty_spans : vec ! [ ] } ;
562+ visitor. visit_item ( & item) ;
560563 let is_async = match item. kind {
561564 ItemKind :: OpaqueTy ( hir:: OpaqueTy { origin, .. } ) => {
562565 matches ! ( origin, hir:: OpaqueTyOrigin :: AsyncFn )
@@ -573,15 +576,13 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
573576 if is_async { "async fn" } else { "impl Trait" } ,
574577 ) ;
575578
576- if let Ok ( snippet) = tcx. sess . source_map ( ) . span_to_snippet ( span) {
577- if snippet == "Self" {
578- err. span_suggestion (
579- span,
580- "consider spelling out the type instead" ,
581- format ! ( "{:?}" , ty) ,
582- Applicability :: MaybeIncorrect ,
583- ) ;
584- }
579+ for span in visitor. selfty_spans {
580+ err. span_suggestion (
581+ span,
582+ "consider spelling out the type instead" ,
583+ format ! ( "{:?}" , ty) ,
584+ Applicability :: MaybeIncorrect ,
585+ ) ;
585586 }
586587 err. emit ( ) ;
587588 }
@@ -1590,3 +1591,31 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
15901591 }
15911592 err. emit ( ) ;
15921593}
1594+
1595+ struct SelfTySpanVisitor < ' tcx > {
1596+ tcx : TyCtxt < ' tcx > ,
1597+ selfty_spans : Vec < Span > ,
1598+ }
1599+
1600+ impl Visitor < ' tcx > for SelfTySpanVisitor < ' tcx > {
1601+ type Map = rustc_middle:: hir:: map:: Map < ' tcx > ;
1602+
1603+ fn nested_visit_map ( & mut self ) -> hir:: intravisit:: NestedVisitorMap < Self :: Map > {
1604+ hir:: intravisit:: NestedVisitorMap :: OnlyBodies ( self . tcx . hir ( ) )
1605+ }
1606+
1607+ fn visit_ty ( & mut self , arg : & ' tcx hir:: Ty < ' tcx > ) {
1608+ match arg. kind {
1609+ hir:: TyKind :: Path ( hir:: QPath :: Resolved ( None , path) ) => match & path. segments {
1610+ [ segment]
1611+ if segment. res . map ( |res| matches ! ( res, Res :: SelfTy ( _, _) ) ) . unwrap_or ( false ) =>
1612+ {
1613+ self . selfty_spans . push ( path. span ) ;
1614+ }
1615+ _ => { }
1616+ } ,
1617+ _ => { }
1618+ }
1619+ hir:: intravisit:: walk_ty ( self , arg) ;
1620+ }
1621+ }
0 commit comments