@@ -9,7 +9,7 @@ use rustc_hir as hir;
99use rustc_hir:: def_id:: { DefId , LocalDefId , LOCAL_CRATE } ;
1010use rustc_hir:: intravisit:: Visitor ;
1111use rustc_hir:: lang_items:: LangItem ;
12- use rustc_hir:: { ItemKind , Node } ;
12+ use rustc_hir:: { def :: Res , ItemKind , Node , PathSegment } ;
1313use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
1414use rustc_infer:: infer:: { RegionVariableOrigin , TyCtxtInferExt } ;
1515use rustc_middle:: ty:: fold:: TypeFoldable ;
@@ -516,10 +516,11 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
516516 }
517517 }
518518
519- #[ derive( Debug ) ]
520519 struct ProhibitOpaqueVisitor < ' tcx > {
521520 opaque_identity_ty : Ty < ' tcx > ,
522521 generics : & ' tcx ty:: Generics ,
522+ tcx : TyCtxt < ' tcx > ,
523+ selftys : Vec < ( Span , Option < String > ) > ,
523524 }
524525
525526 impl < ' tcx > ty:: fold:: TypeVisitor < ' tcx > for ProhibitOpaqueVisitor < ' tcx > {
@@ -536,6 +537,29 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
536537 }
537538 }
538539
540+ impl Visitor < ' tcx > for ProhibitOpaqueVisitor < ' tcx > {
541+ type Map = rustc_middle:: hir:: map:: Map < ' tcx > ;
542+
543+ fn nested_visit_map ( & mut self ) -> hir:: intravisit:: NestedVisitorMap < Self :: Map > {
544+ hir:: intravisit:: NestedVisitorMap :: OnlyBodies ( self . tcx . hir ( ) )
545+ }
546+
547+ fn visit_ty ( & mut self , arg : & ' tcx hir:: Ty < ' tcx > ) {
548+ match arg. kind {
549+ hir:: TyKind :: Path ( hir:: QPath :: Resolved ( None , path) ) => match & path. segments {
550+ [ PathSegment { res : Some ( Res :: SelfTy ( _, impl_ref) ) , .. } ] => {
551+ let impl_ty_name =
552+ impl_ref. map ( |( def_id, _) | self . tcx . def_path_str ( def_id) ) ;
553+ self . selftys . push ( ( path. span , impl_ty_name) ) ;
554+ }
555+ _ => { }
556+ } ,
557+ _ => { }
558+ }
559+ hir:: intravisit:: walk_ty ( self , arg) ;
560+ }
561+ }
562+
539563 if let ItemKind :: OpaqueTy ( hir:: OpaqueTy {
540564 origin : hir:: OpaqueTyOrigin :: AsyncFn | hir:: OpaqueTyOrigin :: FnReturn ,
541565 ..
@@ -547,18 +571,19 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
547571 InternalSubsts :: identity_for_item ( tcx, def_id. to_def_id ( ) ) ,
548572 ) ,
549573 generics : tcx. generics_of ( def_id) ,
574+ tcx,
575+ selftys : vec ! [ ] ,
550576 } ;
551577 let prohibit_opaque = tcx
552578 . explicit_item_bounds ( def_id)
553579 . iter ( )
554580 . try_for_each ( |( predicate, _) | predicate. visit_with ( & mut visitor) ) ;
555581 debug ! (
556- "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor={:?}" ,
557- prohibit_opaque, visitor
582+ "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor.opaque_identity_ty={:?}, visitor.generics ={:?}" ,
583+ prohibit_opaque, visitor. opaque_identity_ty , visitor . generics
558584 ) ;
559585
560586 if let Some ( ty) = prohibit_opaque. break_value ( ) {
561- let mut visitor = SelfTySpanVisitor { tcx, selfty_spans : vec ! [ ] } ;
562587 visitor. visit_item ( & item) ;
563588 let is_async = match item. kind {
564589 ItemKind :: OpaqueTy ( hir:: OpaqueTy { origin, .. } ) => {
@@ -576,11 +601,11 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
576601 if is_async { "async fn" } else { "impl Trait" } ,
577602 ) ;
578603
579- for span in visitor. selfty_spans {
604+ for ( span, name ) in visitor. selftys {
580605 err. span_suggestion (
581606 span,
582607 "consider spelling out the type instead" ,
583- format ! ( "{:?}" , ty) ,
608+ name . unwrap_or_else ( || format ! ( "{:?}" , ty) ) ,
584609 Applicability :: MaybeIncorrect ,
585610 ) ;
586611 }
@@ -1591,31 +1616,3 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'tcx>, def_id: LocalDefId, span: Span) {
15911616 }
15921617 err. emit ( ) ;
15931618}
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