@@ -1632,12 +1632,17 @@ fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: LocalDefId,
1632
1632
struct ProhibitOpaqueVisitor < ' tcx > {
1633
1633
opaque_identity_ty : Ty < ' tcx > ,
1634
1634
generics : & ' tcx ty:: Generics ,
1635
+ ty : Option < Ty < ' tcx > > ,
1635
1636
} ;
1636
1637
1637
1638
impl < ' tcx > ty:: fold:: TypeVisitor < ' tcx > for ProhibitOpaqueVisitor < ' tcx > {
1638
1639
fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> bool {
1639
1640
debug ! ( "check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}" , t) ;
1640
- if t == self . opaque_identity_ty { false } else { t. super_visit_with ( self ) }
1641
+ if t != self . opaque_identity_ty && t. super_visit_with ( self ) {
1642
+ self . ty = Some ( t) ;
1643
+ return true ;
1644
+ }
1645
+ false
1641
1646
}
1642
1647
1643
1648
fn visit_region ( & mut self , r : ty:: Region < ' tcx > ) -> bool {
@@ -1660,46 +1665,61 @@ fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: LocalDefId,
1660
1665
}
1661
1666
}
1662
1667
1663
- let prohibit_opaque = match item. kind {
1664
- ItemKind :: OpaqueTy ( hir:: OpaqueTy {
1665
- origin : hir:: OpaqueTyOrigin :: AsyncFn | hir:: OpaqueTyOrigin :: FnReturn ,
1666
- ..
1667
- } ) => {
1668
- let mut visitor = ProhibitOpaqueVisitor {
1669
- opaque_identity_ty : tcx. mk_opaque (
1670
- def_id. to_def_id ( ) ,
1671
- InternalSubsts :: identity_for_item ( tcx, def_id. to_def_id ( ) ) ,
1672
- ) ,
1673
- generics : tcx. generics_of ( def_id) ,
1674
- } ;
1675
- debug ! ( "check_opaque_for_inheriting_lifetimes: visitor={:?}" , visitor) ;
1676
-
1677
- tcx. predicates_of ( def_id)
1678
- . predicates
1679
- . iter ( )
1680
- . any ( |( predicate, _) | predicate. visit_with ( & mut visitor) )
1681
- }
1682
- _ => false ,
1683
- } ;
1684
-
1685
- debug ! ( "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}" , prohibit_opaque) ;
1686
- if prohibit_opaque {
1687
- let is_async = match item. kind {
1688
- ItemKind :: OpaqueTy ( hir:: OpaqueTy { origin, .. } ) => match origin {
1689
- hir:: OpaqueTyOrigin :: AsyncFn => true ,
1690
- _ => false ,
1691
- } ,
1692
- _ => unreachable ! ( ) ,
1668
+ if let ItemKind :: OpaqueTy ( hir:: OpaqueTy {
1669
+ origin : hir:: OpaqueTyOrigin :: AsyncFn | hir:: OpaqueTyOrigin :: FnReturn ,
1670
+ ..
1671
+ } ) = item. kind
1672
+ {
1673
+ let mut visitor = ProhibitOpaqueVisitor {
1674
+ opaque_identity_ty : tcx. mk_opaque (
1675
+ def_id. to_def_id ( ) ,
1676
+ InternalSubsts :: identity_for_item ( tcx, def_id. to_def_id ( ) ) ,
1677
+ ) ,
1678
+ generics : tcx. generics_of ( def_id) ,
1679
+ ty : None ,
1693
1680
} ;
1681
+ let prohibit_opaque = tcx
1682
+ . predicates_of ( def_id)
1683
+ . predicates
1684
+ . iter ( )
1685
+ . any ( |( predicate, _) | predicate. visit_with ( & mut visitor) ) ;
1686
+ debug ! (
1687
+ "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor={:?}" ,
1688
+ prohibit_opaque, visitor
1689
+ ) ;
1694
1690
1695
- tcx. sess . span_err (
1696
- span,
1697
- & format ! (
1698
- "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1691
+ if prohibit_opaque {
1692
+ let is_async = match item. kind {
1693
+ ItemKind :: OpaqueTy ( hir:: OpaqueTy { origin, .. } ) => match origin {
1694
+ hir:: OpaqueTyOrigin :: AsyncFn => true ,
1695
+ _ => false ,
1696
+ } ,
1697
+ _ => unreachable ! ( ) ,
1698
+ } ;
1699
+
1700
+ let mut err = struct_span_err ! (
1701
+ tcx. sess,
1702
+ span,
1703
+ E0755 ,
1704
+ "`{}` return type cannot contain a projection or `Self` that references lifetimes from \
1699
1705
a parent scope",
1700
- if is_async { "async fn" } else { "impl Trait" } ,
1701
- ) ,
1702
- ) ;
1706
+ if is_async { "async fn" } else { "impl Trait" } ,
1707
+ ) ;
1708
+
1709
+ if let Ok ( snippet) = tcx. sess . source_map ( ) . span_to_snippet ( span) {
1710
+ if snippet == "Self" {
1711
+ if let Some ( ty) = visitor. ty {
1712
+ err. span_suggestion (
1713
+ span,
1714
+ "consider spelling out the type instead" ,
1715
+ format ! ( "{:?}" , ty) ,
1716
+ Applicability :: MaybeIncorrect ,
1717
+ ) ;
1718
+ }
1719
+ }
1720
+ }
1721
+ err. emit ( ) ;
1722
+ }
1703
1723
}
1704
1724
}
1705
1725
0 commit comments