@@ -1742,6 +1742,33 @@ fn on_stderr_line_inner(
17421742 return Ok ( true ) ;
17431743 }
17441744
1745+ #[ derive( serde:: Deserialize ) ]
1746+ struct CompilerMessage {
1747+ rendered : String ,
1748+ message : String ,
1749+ level : String ,
1750+ children : Vec < PartialDiagnostic > ,
1751+ }
1752+
1753+ // A partial rustfix::diagnostics::Diagnostic. We deserialize only a
1754+ // subset of the fields because rustc's output can be extremely
1755+ // deeply nested JSON in pathological cases involving macro
1756+ // expansion. Rustfix's Diagnostic struct is recursive containing a
1757+ // field `children: Vec<Self>`, and it can cause deserialization to
1758+ // hit serde_json's default recursion limit, or overflow the stack
1759+ // if we turn that off. Cargo only cares about the 1 field listed
1760+ // here.
1761+ #[ derive( serde:: Deserialize ) ]
1762+ struct PartialDiagnostic {
1763+ spans : Vec < PartialDiagnosticSpan > ,
1764+ }
1765+
1766+ // A partial rustfix::diagnostics::DiagnosticSpan.
1767+ #[ derive( serde:: Deserialize ) ]
1768+ struct PartialDiagnosticSpan {
1769+ suggestion_applicability : Option < Applicability > ,
1770+ }
1771+
17451772 // Depending on what we're emitting from Cargo itself, we figure out what to
17461773 // do with this JSON message.
17471774 match options. format {
@@ -1755,32 +1782,6 @@ fn on_stderr_line_inner(
17551782 render_diagnostics : true ,
17561783 ..
17571784 } => {
1758- #[ derive( serde:: Deserialize ) ]
1759- struct CompilerMessage {
1760- rendered : String ,
1761- message : String ,
1762- level : String ,
1763- children : Vec < PartialDiagnostic > ,
1764- }
1765-
1766- // A partial rustfix::diagnostics::Diagnostic. We deserialize only a
1767- // subset of the fields because rustc's output can be extremely
1768- // deeply nested JSON in pathological cases involving macro
1769- // expansion. Rustfix's Diagnostic struct is recursive containing a
1770- // field `children: Vec<Self>`, and it can cause deserialization to
1771- // hit serde_json's default recursion limit, or overflow the stack
1772- // if we turn that off. Cargo only cares about the 1 field listed
1773- // here.
1774- #[ derive( serde:: Deserialize ) ]
1775- struct PartialDiagnostic {
1776- spans : Vec < PartialDiagnosticSpan > ,
1777- }
1778-
1779- // A partial rustfix::diagnostics::DiagnosticSpan.
1780- #[ derive( serde:: Deserialize ) ]
1781- struct PartialDiagnosticSpan {
1782- suggestion_applicability : Option < Applicability > ,
1783- }
17841785
17851786 if let Ok ( mut msg) = serde_json:: from_str :: < CompilerMessage > ( compiler_message. get ( ) ) {
17861787 if msg. message . starts_with ( "aborting due to" )
@@ -1865,12 +1866,30 @@ fn on_stderr_line_inner(
18651866 return Ok ( true ) ;
18661867 }
18671868
1868- #[ derive( serde:: Deserialize ) ]
1869- struct CompilerMessage {
1870- level : String ,
1871- }
1872- if let Ok ( message) = serde_json:: from_str :: < CompilerMessage > ( compiler_message. get ( ) ) {
1873- count_diagnostic ( & message. level , options) ;
1869+ if let Ok ( msg) = serde_json:: from_str :: < CompilerMessage > ( compiler_message. get ( ) ) {
1870+ if msg. message . starts_with ( "aborting due to" )
1871+ || msg. message . ends_with ( "warning emitted" )
1872+ || msg. message . ends_with ( "warnings emitted" )
1873+ {
1874+ // Skip this line; we'll print our own summary at the end.
1875+ return Ok ( true ) ;
1876+ }
1877+ let rendered = msg. rendered ;
1878+ if options. show_diagnostics {
1879+ let machine_applicable: bool = msg
1880+ . children
1881+ . iter ( )
1882+ . map ( |child| {
1883+ child
1884+ . spans
1885+ . iter ( )
1886+ . filter_map ( |span| span. suggestion_applicability )
1887+ . any ( |app| app == Applicability :: MachineApplicable )
1888+ } )
1889+ . any ( |b| b) ;
1890+ count_diagnostic ( & msg. level , options) ;
1891+ state. emit_diag ( msg. level , rendered, machine_applicable) ?;
1892+ }
18741893 }
18751894
18761895 let msg = machine_message:: FromCompiler {
0 commit comments