From 9d7a3b232d92277ba75434ac1f8a78d54d521b6c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 12 Nov 2022 21:15:48 -0800 Subject: [PATCH] Fix failure to parse rustc's JSON output if it is too nested --- src/cargo/core/compiler/mod.rs | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 9fe859feee6..ac47aafa706 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -61,7 +61,7 @@ use crate::util::interning::InternedString; use crate::util::machine_message::{self, Message}; use crate::util::{add_path_args, internal, iter_join_onto, profile}; use cargo_util::{paths, ProcessBuilder, ProcessError}; -use rustfix::diagnostics::{Applicability, Diagnostic}; +use rustfix::diagnostics::Applicability; const RUSTDOC_CRATE_VERSION_FLAG: &str = "--crate-version"; @@ -1421,8 +1421,26 @@ fn on_stderr_line_inner( rendered: String, message: String, level: String, - // `children: Vec` if we need to check them recursively - children: Vec, + children: Vec, + } + + // A partial rustfix::diagnostics::Diagnostic. We deserialize only a + // subset of the fields because rustc's output can be extremely + // deeply nested JSON in pathological cases involving macro + // expansion. Rustfix's Diagnostic struct is recursive containing a + // field `children: Vec`, and it can cause deserialization to + // hit serde_json's default recursion limit, or overflow the stack + // if we turn that off. Cargo only cares about the 1 field listed + // here. + #[derive(serde::Deserialize)] + struct PartialDiagnostic { + spans: Vec, + } + + // A partial rustfix::diagnostics::DiagnosticSpan. + #[derive(serde::Deserialize)] + struct PartialDiagnosticSpan { + suggestion_applicability: Option, } if let Ok(mut msg) = serde_json::from_str::(compiler_message.get()) {