Skip to content

Commit

Permalink
Auto merge of #14608 - weihanglo:deserialize, r=epage
Browse files Browse the repository at this point in the history
refactor(compiler): zero-copy deserialization when possible
  • Loading branch information
bors committed Sep 29, 2024
2 parents 2d368ed + d6b740f commit 5e2878f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/cargo/core/compiler/job_queue/job_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl<'a, 'gctx> JobState<'a, 'gctx> {
}

/// See [`Message::Diagnostic`] and [`Message::WarningCount`].
pub fn emit_diag(&self, level: String, diag: String, fixable: bool) -> CargoResult<()> {
pub fn emit_diag(&self, level: &str, diag: String, fixable: bool) -> CargoResult<()> {
if let Some(dedupe) = self.output {
let emitted = dedupe.emit_diag(&diag)?;
if level == "warning" {
Expand All @@ -116,7 +116,7 @@ impl<'a, 'gctx> JobState<'a, 'gctx> {
} else {
self.messages.push_bounded(Message::Diagnostic {
id: self.id,
level,
level: level.to_string(),
diag,
fixable,
});
Expand Down
47 changes: 29 additions & 18 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ mod unit;
pub mod unit_dependencies;
pub mod unit_graph;

use std::borrow::Cow;
use std::collections::{HashMap, HashSet};
use std::env;
use std::ffi::{OsStr, OsString};
Expand Down Expand Up @@ -1756,10 +1757,15 @@ fn on_stderr_line_inner(
..
} => {
#[derive(serde::Deserialize)]
struct CompilerMessage {
struct CompilerMessage<'a> {
// `rendered` contains escape sequences, which can't be
// zero-copy deserialized by serde_json.
// See https://github.com/serde-rs/json/issues/742
rendered: String,
message: String,
level: String,
#[serde(borrow)]
message: Cow<'a, str>,
#[serde(borrow)]
level: Cow<'a, str>,
children: Vec<PartialDiagnostic>,
}

Expand All @@ -1782,7 +1788,8 @@ fn on_stderr_line_inner(
suggestion_applicability: Option<Applicability>,
}

if let Ok(mut msg) = serde_json::from_str::<CompilerMessage>(compiler_message.get()) {
if let Ok(mut msg) = serde_json::from_str::<CompilerMessage<'_>>(compiler_message.get())
{
if msg.message.starts_with("aborting due to")
|| msg.message.ends_with("warning emitted")
|| msg.message.ends_with("warnings emitted")
Expand All @@ -1808,7 +1815,7 @@ fn on_stderr_line_inner(
})
.any(|b| b);
count_diagnostic(&msg.level, options);
state.emit_diag(msg.level, rendered, machine_applicable)?;
state.emit_diag(&msg.level, rendered, machine_applicable)?;
}
return Ok(true);
}
Expand All @@ -1819,16 +1826,17 @@ fn on_stderr_line_inner(
// cached replay to enable/disable colors without re-invoking rustc.
MessageFormat::Json { ansi: false, .. } => {
#[derive(serde::Deserialize, serde::Serialize)]
struct CompilerMessage {
struct CompilerMessage<'a> {
rendered: String,
#[serde(flatten)]
other: std::collections::BTreeMap<String, serde_json::Value>,
#[serde(flatten, borrow)]
other: std::collections::BTreeMap<Cow<'a, str>, serde_json::Value>,
}
if let Ok(mut error) = serde_json::from_str::<CompilerMessage>(compiler_message.get()) {
if let Ok(mut error) =
serde_json::from_str::<CompilerMessage<'_>>(compiler_message.get())
{
error.rendered = anstream::adapter::strip_str(&error.rendered).to_string();
let new_line = serde_json::to_string(&error)?;
let new_msg: Box<serde_json::value::RawValue> = serde_json::from_str(&new_line)?;
compiler_message = new_msg;
compiler_message = serde_json::value::RawValue::from_string(new_line)?;
}
}

Expand All @@ -1844,11 +1852,12 @@ fn on_stderr_line_inner(
// Look for a matching directive and inform Cargo internally that a
// metadata file has been produced.
#[derive(serde::Deserialize)]
struct ArtifactNotification {
artifact: String,
struct ArtifactNotification<'a> {
#[serde(borrow)]
artifact: Cow<'a, str>,
}

if let Ok(artifact) = serde_json::from_str::<ArtifactNotification>(compiler_message.get()) {
if let Ok(artifact) = serde_json::from_str::<ArtifactNotification<'_>>(compiler_message.get()) {
trace!("found directive from rustc: `{}`", artifact.artifact);
if artifact.artifact.ends_with(".rmeta") {
debug!("looks like metadata finished early!");
Expand All @@ -1866,12 +1875,14 @@ fn on_stderr_line_inner(
}

#[derive(serde::Deserialize)]
struct CompilerMessage {
message: String,
level: String,
struct CompilerMessage<'a> {
#[serde(borrow)]
message: Cow<'a, str>,
#[serde(borrow)]
level: Cow<'a, str>,
}

if let Ok(msg) = serde_json::from_str::<CompilerMessage>(compiler_message.get()) {
if let Ok(msg) = serde_json::from_str::<CompilerMessage<'_>>(compiler_message.get()) {
if msg.message.starts_with("aborting due to")
|| msg.message.ends_with("warning emitted")
|| msg.message.ends_with("warnings emitted")
Expand Down

0 comments on commit 5e2878f

Please sign in to comment.