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