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