@@ -1716,121 +1716,114 @@ 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+ 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
17231731 . returns
17241732 . 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" ) ;
17451738 } 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+ }
17751748
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) ;
17841768 }
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 ) ,
17861774 }
1775+ }
1776+ }
17871777
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+ }
18131789
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 ( )
18221802 {
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+ ) ;
18261807 }
18271808 }
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+ }
18281822 }
18291823 }
18301824 }
1831- if !label {
1832- err. span_label ( span, "cannot resolve opaque type" ) ;
1833- }
1825+
1826+ err. span_label ( span, "cannot resolve opaque type" ) ;
18341827 err. emit ( )
18351828}
18361829
0 commit comments