@@ -1639,51 +1639,56 @@ fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: LocalDefId,
16391639 struct ProhibitOpaqueVisitor < ' tcx > {
16401640 opaque_identity_ty : Ty < ' tcx > ,
16411641 generics : & ' tcx ty:: Generics ,
1642+ ty : Option < Ty < ' tcx > > ,
16421643 } ;
16431644
16441645 impl < ' tcx > ty:: fold:: TypeVisitor < ' tcx > for ProhibitOpaqueVisitor < ' tcx > {
16451646 fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> bool {
16461647 debug ! ( "check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}" , t) ;
1648+ self . ty = Some ( t) ;
16471649 if t == self . opaque_identity_ty { false } else { t. super_visit_with ( self ) }
16481650 }
16491651
16501652 fn visit_region ( & mut self , r : ty:: Region < ' tcx > ) -> bool {
16511653 debug ! ( "check_opaque_for_inheriting_lifetimes: (visit_region) r={:?}" , r) ;
16521654 if let RegionKind :: ReEarlyBound ( ty:: EarlyBoundRegion { index, .. } ) = r {
1653- return * index < self . generics . parent_count as u32 ;
1655+ let found_lifetime = * index < self . generics . parent_count as u32 ;
1656+ if !found_lifetime {
1657+ self . ty = None ;
1658+ }
1659+ return found_lifetime;
16541660 }
16551661
16561662 r. super_visit_with ( self )
16571663 }
16581664 }
16591665
1666+ let mut visitor = ProhibitOpaqueVisitor {
1667+ opaque_identity_ty : tcx. mk_opaque (
1668+ def_id. to_def_id ( ) ,
1669+ InternalSubsts :: identity_for_item ( tcx, def_id. to_def_id ( ) ) ,
1670+ ) ,
1671+ generics : tcx. generics_of ( def_id) ,
1672+ ty : None ,
1673+ } ;
1674+ debug ! ( "check_opaque_for_inheriting_lifetimes: visitor={:?}" , visitor) ;
1675+
16601676 let prohibit_opaque = match item. kind {
16611677 ItemKind :: OpaqueTy ( hir:: OpaqueTy {
1662- bounds,
16631678 origin : hir:: OpaqueTyOrigin :: AsyncFn | hir:: OpaqueTyOrigin :: FnReturn ,
16641679 ..
1665- } ) => {
1666- let mut visitor = ProhibitOpaqueVisitor {
1667- opaque_identity_ty : tcx. mk_opaque (
1668- def_id. to_def_id ( ) ,
1669- InternalSubsts :: identity_for_item ( tcx, def_id. to_def_id ( ) ) ,
1670- ) ,
1671- generics : tcx. generics_of ( def_id) ,
1672- } ;
1673- debug ! ( "check_opaque_for_inheriting_lifetimes: visitor={:?}" , visitor) ;
1674-
1675- for bound in bounds {
1676- debug ! ( "check_opaque_for_inheriting_lifetimes: {:?}" , bound. trait_ref( ) ) ;
1677- }
1678- tcx. predicates_of ( def_id)
1679- . predicates
1680- . iter ( )
1681- . any ( |( predicate, _) | predicate. visit_with ( & mut visitor) )
1682- }
1680+ } ) => tcx
1681+ . predicates_of ( def_id)
1682+ . predicates
1683+ . iter ( )
1684+ . any ( |( predicate, _) | predicate. visit_with ( & mut visitor) ) ,
16831685 _ => false ,
16841686 } ;
1687+ debug ! (
1688+ "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor={:?}" ,
1689+ prohibit_opaque, visitor
1690+ ) ;
16851691
1686- debug ! ( "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}" , prohibit_opaque) ;
16871692 if prohibit_opaque {
16881693 let is_async = match item. kind {
16891694 ItemKind :: OpaqueTy ( hir:: OpaqueTy { origin, .. } ) => match origin {
@@ -1693,14 +1698,28 @@ fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: LocalDefId,
16931698 _ => unreachable ! ( ) ,
16941699 } ;
16951700
1696- tcx. sess . span_err (
1701+ let mut err = struct_span_err ! (
1702+ tcx. sess,
16971703 span,
1698- & format ! (
1704+ E0754 ,
16991705 "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
17001706 a parent scope",
17011707 if is_async { "async fn" } else { "impl Trait" } ,
1702- )
17031708 ) ;
1709+
1710+ if let Ok ( snippet) = tcx. sess . source_map ( ) . span_to_snippet ( span) {
1711+ if snippet == "Self" {
1712+ if let Some ( ty) = visitor. ty {
1713+ err. span_suggestion (
1714+ span,
1715+ "consider spelling out the type instead" ,
1716+ format ! ( "{:?}" , ty) ,
1717+ Applicability :: MaybeIncorrect ,
1718+ ) ;
1719+ }
1720+ }
1721+ }
1722+ err. emit ( ) ;
17041723 }
17051724}
17061725
0 commit comments