@@ -1716,121 +1716,114 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, opaque_def_id: LocalDefId) -> ErrorG
1716
1716
let span = tcx. def_span ( opaque_def_id) ;
1717
1717
let mut err = struct_span_code_err ! ( tcx. dcx( ) , span, E0720 , "cannot resolve opaque type" ) ;
1718
1718
1719
- let mut label = false ;
1720
- if let Some ( ( def_id, visitor) ) = get_owner_return_paths ( tcx, opaque_def_id) {
1721
- let typeck_results = tcx. typeck ( def_id) ;
1722
- if visitor
1719
+ let Some ( ( def_id, visitor) ) = get_owner_return_paths ( tcx, opaque_def_id) else {
1720
+ return err. emit ( ) ;
1721
+ } ;
1722
+
1723
+ let typeck_results = tcx. typeck ( def_id) ;
1724
+ if visitor
1725
+ . returns
1726
+ . iter ( )
1727
+ . filter_map ( |expr| typeck_results. node_type_opt ( expr. hir_id ) )
1728
+ . all ( |ty| matches ! ( ty. kind( ) , ty:: Never ) )
1729
+ {
1730
+ let spans = visitor
1723
1731
. returns
1724
1732
. iter ( )
1725
- . filter_map ( |expr| typeck_results. node_type_opt ( expr. hir_id ) )
1726
- . all ( |ty| matches ! ( ty. kind( ) , ty:: Never ) )
1727
- {
1728
- let spans = visitor
1729
- . returns
1730
- . iter ( )
1731
- . filter ( |expr| typeck_results. node_type_opt ( expr. hir_id ) . is_some ( ) )
1732
- . map ( |expr| expr. span )
1733
- . collect :: < Vec < Span > > ( ) ;
1734
- let span_len = spans. len ( ) ;
1735
- if span_len == 1 {
1736
- err. span_label ( spans[ 0 ] , "this returned value is of `!` type" ) ;
1737
- } else {
1738
- let mut multispan: MultiSpan = spans. clone ( ) . into ( ) ;
1739
- for span in spans {
1740
- multispan. push_span_label ( span, "this returned value is of `!` type" ) ;
1741
- }
1742
- err. span_note ( multispan, "these returned values have a concrete \" never\" type" ) ;
1743
- }
1744
- err. help ( "this error will resolve once the item's body returns a concrete type" ) ;
1733
+ . filter ( |expr| typeck_results. node_type_opt ( expr. hir_id ) . is_some ( ) )
1734
+ . map ( |expr| expr. span )
1735
+ . collect :: < Vec < Span > > ( ) ;
1736
+ if let & [ span] = & spans[ ..] {
1737
+ err. span_label ( span, "this returned value is of `!` type" ) ;
1745
1738
} else {
1746
- let mut seen = FxHashSet :: default ( ) ;
1747
- seen. insert ( span) ;
1748
- err. span_label ( span, "recursive opaque type" ) ;
1749
- label = true ;
1750
- for ( sp, ty) in visitor
1751
- . returns
1752
- . iter ( )
1753
- . filter_map ( |e| typeck_results. node_type_opt ( e. hir_id ) . map ( |t| ( e. span , t) ) )
1754
- . filter ( |( _, ty) | !matches ! ( ty. kind( ) , ty:: Never ) )
1755
- {
1756
- #[ derive( Default ) ]
1757
- struct OpaqueTypeCollector {
1758
- opaques : Vec < DefId > ,
1759
- closures : Vec < DefId > ,
1760
- }
1761
- impl < ' tcx > ty:: visit:: TypeVisitor < TyCtxt < ' tcx > > for OpaqueTypeCollector {
1762
- fn visit_ty ( & mut self , t : Ty < ' tcx > ) {
1763
- match * t. kind ( ) {
1764
- ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id : def, .. } ) => {
1765
- self . opaques . push ( def) ;
1766
- }
1767
- ty:: Closure ( def_id, ..) | ty:: Coroutine ( def_id, ..) => {
1768
- self . closures . push ( def_id) ;
1769
- t. super_visit_with ( self ) ;
1770
- }
1771
- _ => t. super_visit_with ( self ) ,
1772
- }
1773
- }
1774
- }
1739
+ let mut multispan = MultiSpan :: from ( spans. clone ( ) ) ;
1740
+ for span in spans {
1741
+ multispan. push_span_label ( span, "this returned value is of `!` type" ) ;
1742
+ }
1743
+ err. span_note ( multispan, "these returned values have a concrete \" never\" type" ) ;
1744
+ }
1745
+ err. help ( "this error will resolve once the item's body returns a concrete type" ) ;
1746
+ return err. emit ( ) ;
1747
+ }
1775
1748
1776
- let mut visitor = OpaqueTypeCollector :: default ( ) ;
1777
- ty. visit_with ( & mut visitor) ;
1778
- for def_id in visitor. opaques {
1779
- let ty_span = tcx. def_span ( def_id) ;
1780
- if !seen. contains ( & ty_span) {
1781
- let descr = if ty. is_impl_trait ( ) { "opaque " } else { "" } ;
1782
- err. span_label ( ty_span, format ! ( "returning this {descr}type `{ty}`" ) ) ;
1783
- seen. insert ( ty_span) ;
1749
+ let mut seen = FxHashSet :: default ( ) ;
1750
+ seen. insert ( span) ;
1751
+ err. span_label ( span, "recursive opaque type" ) ;
1752
+ for ( sp, ty) in visitor
1753
+ . returns
1754
+ . iter ( )
1755
+ . filter_map ( |e| typeck_results. node_type_opt ( e. hir_id ) . map ( |t| ( e. span , t) ) )
1756
+ . filter ( |( _, ty) | !matches ! ( ty. kind( ) , ty:: Never ) )
1757
+ {
1758
+ #[ derive( Default ) ]
1759
+ struct OpaqueTypeCollector {
1760
+ opaques : Vec < DefId > ,
1761
+ closures : Vec < DefId > ,
1762
+ }
1763
+ impl < ' tcx > ty:: visit:: TypeVisitor < TyCtxt < ' tcx > > for OpaqueTypeCollector {
1764
+ fn visit_ty ( & mut self , t : Ty < ' tcx > ) {
1765
+ match * t. kind ( ) {
1766
+ ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id : def, .. } ) => {
1767
+ self . opaques . push ( def) ;
1784
1768
}
1785
- err. span_label ( sp, format ! ( "returning here with type `{ty}`" ) ) ;
1769
+ ty:: Closure ( def_id, ..) | ty:: Coroutine ( def_id, ..) => {
1770
+ self . closures . push ( def_id) ;
1771
+ t. super_visit_with ( self ) ;
1772
+ }
1773
+ _ => t. super_visit_with ( self ) ,
1786
1774
}
1775
+ }
1776
+ }
1787
1777
1788
- for closure_def_id in visitor. closures {
1789
- let Some ( closure_local_did) = closure_def_id. as_local ( ) else {
1790
- continue ;
1791
- } ;
1792
- let typeck_results = tcx. typeck ( closure_local_did) ;
1793
-
1794
- let mut label_match = |ty : Ty < ' _ > , span| {
1795
- for arg in ty. walk ( ) {
1796
- if let ty:: GenericArgKind :: Type ( ty) = arg. unpack ( )
1797
- && let ty:: Alias (
1798
- ty:: Opaque ,
1799
- ty:: AliasTy { def_id : captured_def_id, .. } ,
1800
- ) = * ty. kind ( )
1801
- && captured_def_id == opaque_def_id. to_def_id ( )
1802
- {
1803
- err. span_label (
1804
- span,
1805
- format ! (
1806
- "{} captures itself here" ,
1807
- tcx. def_descr( closure_def_id)
1808
- ) ,
1809
- ) ;
1810
- }
1811
- }
1812
- } ;
1778
+ let mut visitor = OpaqueTypeCollector :: default ( ) ;
1779
+ ty. visit_with ( & mut visitor) ;
1780
+ for def_id in visitor. opaques {
1781
+ let ty_span = tcx. def_span ( def_id) ;
1782
+ if !seen. contains ( & ty_span) {
1783
+ let descr = if ty. is_impl_trait ( ) { "opaque " } else { "" } ;
1784
+ err. span_label ( ty_span, format ! ( "returning this {descr}type `{ty}`" ) ) ;
1785
+ seen. insert ( ty_span) ;
1786
+ }
1787
+ err. span_label ( sp, format ! ( "returning here with type `{ty}`" ) ) ;
1788
+ }
1813
1789
1814
- // Label any closure upvars that capture the opaque
1815
- for capture in typeck_results. closure_min_captures_flattened ( closure_local_did)
1816
- {
1817
- label_match ( capture. place . ty ( ) , capture. get_path_span ( tcx) ) ;
1818
- }
1819
- // Label any coroutine locals that capture the opaque
1820
- if tcx. is_coroutine ( closure_def_id)
1821
- && let Some ( coroutine_layout) = tcx. mir_coroutine_witnesses ( closure_def_id)
1790
+ for closure_def_id in visitor. closures {
1791
+ let Some ( closure_local_did) = closure_def_id. as_local ( ) else {
1792
+ continue ;
1793
+ } ;
1794
+ let typeck_results = tcx. typeck ( closure_local_did) ;
1795
+
1796
+ let mut label_match = |ty : Ty < ' _ > , span| {
1797
+ for arg in ty. walk ( ) {
1798
+ if let ty:: GenericArgKind :: Type ( ty) = arg. unpack ( )
1799
+ && let ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id : captured_def_id, .. } ) =
1800
+ * ty. kind ( )
1801
+ && captured_def_id == opaque_def_id. to_def_id ( )
1822
1802
{
1823
- for interior_ty in & coroutine_layout. field_tys {
1824
- label_match ( interior_ty. ty , interior_ty. source_info . span ) ;
1825
- }
1803
+ err. span_label (
1804
+ span,
1805
+ format ! ( "{} captures itself here" , tcx. def_descr( closure_def_id) ) ,
1806
+ ) ;
1826
1807
}
1827
1808
}
1809
+ } ;
1810
+
1811
+ // Label any closure upvars that capture the opaque
1812
+ for capture in typeck_results. closure_min_captures_flattened ( closure_local_did) {
1813
+ label_match ( capture. place . ty ( ) , capture. get_path_span ( tcx) ) ;
1814
+ }
1815
+ // Label any coroutine locals that capture the opaque
1816
+ if tcx. is_coroutine ( closure_def_id)
1817
+ && let Some ( coroutine_layout) = tcx. mir_coroutine_witnesses ( closure_def_id)
1818
+ {
1819
+ for interior_ty in & coroutine_layout. field_tys {
1820
+ label_match ( interior_ty. ty , interior_ty. source_info . span ) ;
1821
+ }
1828
1822
}
1829
1823
}
1830
1824
}
1831
- if !label {
1832
- err. span_label ( span, "cannot resolve opaque type" ) ;
1833
- }
1825
+
1826
+ err. span_label ( span, "cannot resolve opaque type" ) ;
1834
1827
err. emit ( )
1835
1828
}
1836
1829
0 commit comments