@@ -7,6 +7,7 @@ use rustc_attr as attr;
7
7
use rustc_errors:: { Applicability , ErrorReported } ;
8
8
use rustc_hir as hir;
9
9
use rustc_hir:: def_id:: { DefId , LocalDefId , LOCAL_CRATE } ;
10
+ use rustc_hir:: intravisit:: Visitor ;
10
11
use rustc_hir:: lang_items:: LangItem ;
11
12
use rustc_hir:: { ItemKind , Node } ;
12
13
use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
@@ -557,6 +558,8 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
557
558
) ;
558
559
559
560
if let Some ( ty) = prohibit_opaque. break_value ( ) {
561
+ let mut visitor = SelfTySpanVisitor { tcx, selfty_spans : vec ! [ ] } ;
562
+ visitor. visit_item ( & item) ;
560
563
let is_async = match item. kind {
561
564
ItemKind :: OpaqueTy ( hir:: OpaqueTy { origin, .. } ) => {
562
565
matches ! ( origin, hir:: OpaqueTyOrigin :: AsyncFn )
@@ -573,15 +576,13 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
573
576
if is_async { "async fn" } else { "impl Trait" } ,
574
577
) ;
575
578
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
+ ) ;
585
586
}
586
587
err. emit ( ) ;
587
588
}
@@ -1590,3 +1591,31 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
1590
1591
}
1591
1592
err. emit ( ) ;
1592
1593
}
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