Skip to content

Commit 7e9b92c

Browse files
committed
Auto merge of #85993 - bjorn3:serde_json, r=wesleywiser
Remove all json handling from rustc_serialize Json is now handled using serde_json. Where appropriate I have replaced json usage with binary serialization (rmeta files) or manual string formatting (emcc linker arg generation). This allowed for removing and simplifying a lot of code, which hopefully results in faster serialization/deserialization and faster compiles of rustc itself. Where sensible we now use serde. Metadata and incr cache serialization keeps using a heavily modified (compared to crates.io) rustc-serialize version that in the future could probably be extended with zero-copy deserialization or other perf tricks that serde can't support due to supporting more than one serialization format. Note that I had to remove `-Zast-json` and `-Zast-json-noexpand` as the relevant AST types don't implement `serde::Serialize`. Fixes #40177 See also rust-lang/compiler-team#418
2 parents 9a74608 + 5cc3593 commit 7e9b92c

File tree

48 files changed

+603
-4235
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+603
-4235
lines changed

Cargo.lock

+6
Original file line numberDiff line numberDiff line change
@@ -3686,6 +3686,7 @@ dependencies = [
36863686
"rustc_span",
36873687
"rustc_symbol_mangling",
36883688
"rustc_target",
3689+
"serde_json",
36893690
"smallvec",
36903691
"snap",
36913692
"tempfile",
@@ -3774,6 +3775,7 @@ dependencies = [
37743775
"rustc_span",
37753776
"rustc_target",
37763777
"rustc_typeck",
3778+
"serde_json",
37773779
"tracing",
37783780
"winapi",
37793781
]
@@ -3809,6 +3811,8 @@ dependencies = [
38093811
"rustc_macros",
38103812
"rustc_serialize",
38113813
"rustc_span",
3814+
"serde",
3815+
"serde_json",
38123816
"termcolor",
38133817
"termize",
38143818
"tracing",
@@ -4024,6 +4028,7 @@ dependencies = [
40244028
"rustc_serialize",
40254029
"rustc_span",
40264030
"rustc_target",
4031+
"serde",
40274032
]
40284033

40294034
[[package]]
@@ -4445,6 +4450,7 @@ dependencies = [
44454450
"rustc_macros",
44464451
"rustc_serialize",
44474452
"rustc_span",
4453+
"serde_json",
44484454
"tracing",
44494455
]
44504456

compiler/rustc_ast/src/ast.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,6 @@ use std::convert::TryFrom;
4141
use std::fmt;
4242
use std::mem;
4343

44-
#[cfg(test)]
45-
mod tests;
46-
4744
/// A "Label" is an identifier of some point in sources,
4845
/// e.g. in the following code:
4946
///
@@ -2476,8 +2473,8 @@ rustc_index::newtype_index! {
24762473
}
24772474

24782475
impl<S: Encoder> rustc_serialize::Encodable<S> for AttrId {
2479-
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
2480-
s.emit_unit()
2476+
fn encode(&self, _s: &mut S) -> Result<(), S::Error> {
2477+
Ok(())
24812478
}
24822479
}
24832480

compiler/rustc_ast/src/ast/tests.rs

-11
This file was deleted.

compiler/rustc_codegen_ssa/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ jobserver = "0.1.22"
1616
tempfile = "3.2"
1717
thorin-dwp = "0.2"
1818
pathdiff = "0.2.0"
19+
serde_json = "1.0.59"
1920
snap = "1"
2021
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
2122
regex = "1.4"

compiler/rustc_codegen_ssa/src/back/linker.rs

+5-15
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
1414
use rustc_middle::middle::dependency_format::Linkage;
1515
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind};
1616
use rustc_middle::ty::TyCtxt;
17-
use rustc_serialize::{json, Encoder};
1817
use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
1918
use rustc_session::Session;
2019
use rustc_span::symbol::Symbol;
@@ -1152,21 +1151,12 @@ impl<'a> Linker for EmLinker<'a> {
11521151
self.cmd.arg("-s");
11531152

11541153
let mut arg = OsString::from("EXPORTED_FUNCTIONS=");
1155-
let mut encoded = String::new();
1156-
1157-
{
1158-
let mut encoder = json::Encoder::new(&mut encoded);
1159-
let res = encoder.emit_seq(symbols.len(), |encoder| {
1160-
for (i, sym) in symbols.iter().enumerate() {
1161-
encoder.emit_seq_elt(i, |encoder| encoder.emit_str(&("_".to_owned() + sym)))?;
1162-
}
1163-
Ok(())
1164-
});
1165-
if let Err(e) = res {
1166-
self.sess.fatal(&format!("failed to encode exported symbols: {}", e));
1167-
}
1168-
}
1154+
let encoded = serde_json::to_string(
1155+
&symbols.iter().map(|sym| "_".to_owned() + sym).collect::<Vec<_>>(),
1156+
)
1157+
.unwrap();
11691158
debug!("{}", encoded);
1159+
11701160
arg.push(encoded);
11711161

11721162
self.cmd.arg(arg);

compiler/rustc_driver/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ crate-type = ["dylib"]
99
[dependencies]
1010
libc = "0.2"
1111
tracing = { version = "0.1.28" }
12+
serde_json = "1.0.59"
1213
rustc_log = { path = "../rustc_log" }
1314
rustc_middle = { path = "../rustc_middle" }
1415
rustc_ast_pretty = { path = "../rustc_ast_pretty" }

compiler/rustc_driver/src/lib.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ use rustc_log::stdout_isatty;
3030
use rustc_metadata::locator;
3131
use rustc_save_analysis as save;
3232
use rustc_save_analysis::DumpHandler;
33-
use rustc_serialize::json::ToJson;
3433
use rustc_session::config::{nightly_options, CG_OPTIONS, DB_OPTIONS};
3534
use rustc_session::config::{ErrorOutputType, Input, OutputType, PrintRequest, TrimmedDefPaths};
3635
use rustc_session::cstore::MetadataLoader;
@@ -40,6 +39,7 @@ use rustc_session::{config, DiagnosticOutput, Session};
4039
use rustc_session::{early_error, early_error_no_abort, early_warn};
4140
use rustc_span::source_map::{FileLoader, FileName};
4241
use rustc_span::symbol::sym;
42+
use rustc_target::json::ToJson;
4343

4444
use std::borrow::Cow;
4545
use std::cmp::max;
@@ -343,10 +343,7 @@ fn run_compiler(
343343
return early_exit();
344344
}
345345

346-
if sess.opts.debugging_opts.parse_only
347-
|| sess.opts.debugging_opts.show_span.is_some()
348-
|| sess.opts.debugging_opts.ast_json_noexpand
349-
{
346+
if sess.opts.debugging_opts.parse_only || sess.opts.debugging_opts.show_span.is_some() {
350347
return early_exit();
351348
}
352349

@@ -375,7 +372,7 @@ fn run_compiler(
375372

376373
queries.global_ctxt()?;
377374

378-
if sess.opts.debugging_opts.no_analysis || sess.opts.debugging_opts.ast_json {
375+
if sess.opts.debugging_opts.no_analysis {
379376
return early_exit();
380377
}
381378

@@ -665,7 +662,9 @@ fn print_crate_info(
665662
}
666663
Sysroot => println!("{}", sess.sysroot.display()),
667664
TargetLibdir => println!("{}", sess.target_tlib_path.dir.display()),
668-
TargetSpec => println!("{}", sess.target.to_json().pretty()),
665+
TargetSpec => {
666+
println!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap());
667+
}
669668
FileNames | CrateName => {
670669
let input = input.unwrap_or_else(|| {
671670
early_error(ErrorOutputType::default(), "no input file provided")

compiler/rustc_errors/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ atty = "0.2"
1919
termcolor = "1.0"
2020
annotate-snippets = "0.8.0"
2121
termize = "0.1.1"
22+
serde = { version = "1.0.125", features = ["derive"] }
23+
serde_json = "1.0.59"
2224

2325
[target.'cfg(windows)'.dependencies]
2426
winapi = { version = "0.3", features = ["handleapi", "synchapi", "winbase"] }

compiler/rustc_errors/src/json.rs

+18-18
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use std::path::Path;
2828
use std::sync::{Arc, Mutex};
2929
use std::vec;
3030

31-
use rustc_serialize::json::{as_json, as_pretty_json};
31+
use serde::Serialize;
3232

3333
#[cfg(test)]
3434
mod tests;
@@ -126,9 +126,9 @@ impl Emitter for JsonEmitter {
126126
fn emit_diagnostic(&mut self, diag: &crate::Diagnostic) {
127127
let data = Diagnostic::from_errors_diagnostic(diag, self);
128128
let result = if self.pretty {
129-
writeln!(&mut self.dst, "{}", as_pretty_json(&data))
129+
writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&data).unwrap())
130130
} else {
131-
writeln!(&mut self.dst, "{}", as_json(&data))
131+
writeln!(&mut self.dst, "{}", serde_json::to_string(&data).unwrap())
132132
}
133133
.and_then(|_| self.dst.flush());
134134
if let Err(e) = result {
@@ -139,9 +139,9 @@ impl Emitter for JsonEmitter {
139139
fn emit_artifact_notification(&mut self, path: &Path, artifact_type: &str) {
140140
let data = ArtifactNotification { artifact: path, emit: artifact_type };
141141
let result = if self.pretty {
142-
writeln!(&mut self.dst, "{}", as_pretty_json(&data))
142+
writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&data).unwrap())
143143
} else {
144-
writeln!(&mut self.dst, "{}", as_json(&data))
144+
writeln!(&mut self.dst, "{}", serde_json::to_string(&data).unwrap())
145145
}
146146
.and_then(|_| self.dst.flush());
147147
if let Err(e) = result {
@@ -161,9 +161,9 @@ impl Emitter for JsonEmitter {
161161
.collect();
162162
let report = FutureIncompatReport { future_incompat_report: data };
163163
let result = if self.pretty {
164-
writeln!(&mut self.dst, "{}", as_pretty_json(&report))
164+
writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&report).unwrap())
165165
} else {
166-
writeln!(&mut self.dst, "{}", as_json(&report))
166+
writeln!(&mut self.dst, "{}", serde_json::to_string(&report).unwrap())
167167
}
168168
.and_then(|_| self.dst.flush());
169169
if let Err(e) = result {
@@ -175,9 +175,9 @@ impl Emitter for JsonEmitter {
175175
let lint_level = lint_level.as_str();
176176
let data = UnusedExterns { lint_level, unused_extern_names: unused_externs };
177177
let result = if self.pretty {
178-
writeln!(&mut self.dst, "{}", as_pretty_json(&data))
178+
writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&data).unwrap())
179179
} else {
180-
writeln!(&mut self.dst, "{}", as_json(&data))
180+
writeln!(&mut self.dst, "{}", serde_json::to_string(&data).unwrap())
181181
}
182182
.and_then(|_| self.dst.flush());
183183
if let Err(e) = result {
@@ -204,7 +204,7 @@ impl Emitter for JsonEmitter {
204204

205205
// The following data types are provided just for serialisation.
206206

207-
#[derive(Encodable)]
207+
#[derive(Serialize)]
208208
struct Diagnostic {
209209
/// The primary error message.
210210
message: String,
@@ -218,7 +218,7 @@ struct Diagnostic {
218218
rendered: Option<String>,
219219
}
220220

221-
#[derive(Encodable)]
221+
#[derive(Serialize)]
222222
struct DiagnosticSpan {
223223
file_name: String,
224224
byte_start: u32,
@@ -245,7 +245,7 @@ struct DiagnosticSpan {
245245
expansion: Option<Box<DiagnosticSpanMacroExpansion>>,
246246
}
247247

248-
#[derive(Encodable)]
248+
#[derive(Serialize)]
249249
struct DiagnosticSpanLine {
250250
text: String,
251251

@@ -255,7 +255,7 @@ struct DiagnosticSpanLine {
255255
highlight_end: usize,
256256
}
257257

258-
#[derive(Encodable)]
258+
#[derive(Serialize)]
259259
struct DiagnosticSpanMacroExpansion {
260260
/// span where macro was applied to generate this code; note that
261261
/// this may itself derive from a macro (if
@@ -269,28 +269,28 @@ struct DiagnosticSpanMacroExpansion {
269269
def_site_span: DiagnosticSpan,
270270
}
271271

272-
#[derive(Encodable)]
272+
#[derive(Serialize)]
273273
struct DiagnosticCode {
274274
/// The code itself.
275275
code: String,
276276
/// An explanation for the code.
277277
explanation: Option<&'static str>,
278278
}
279279

280-
#[derive(Encodable)]
280+
#[derive(Serialize)]
281281
struct ArtifactNotification<'a> {
282282
/// The path of the artifact.
283283
artifact: &'a Path,
284284
/// What kind of artifact we're emitting.
285285
emit: &'a str,
286286
}
287287

288-
#[derive(Encodable)]
288+
#[derive(Serialize)]
289289
struct FutureBreakageItem {
290290
diagnostic: Diagnostic,
291291
}
292292

293-
#[derive(Encodable)]
293+
#[derive(Serialize)]
294294
struct FutureIncompatReport {
295295
future_incompat_report: Vec<FutureBreakageItem>,
296296
}
@@ -299,7 +299,7 @@ struct FutureIncompatReport {
299299
// doctest component (as well as cargo).
300300
// We could unify this struct the one in rustdoc but they have different
301301
// ownership semantics, so doing so would create wasteful allocations.
302-
#[derive(Encodable)]
302+
#[derive(Serialize)]
303303
struct UnusedExterns<'a, 'b, 'c> {
304304
/// The severity level of the unused dependencies lint
305305
lint_level: &'a str,

compiler/rustc_errors/src/json/tests.rs

+12-14
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,18 @@ use rustc_span::source_map::{FilePathMapping, SourceMap};
55

66
use crate::emitter::{ColorConfig, HumanReadableErrorType};
77
use crate::Handler;
8-
use rustc_serialize::json;
98
use rustc_span::{BytePos, Span};
109

1110
use std::str;
1211

13-
#[derive(Debug, PartialEq, Eq)]
12+
use serde::Deserialize;
13+
14+
#[derive(Deserialize, Debug, PartialEq, Eq)]
15+
struct TestData {
16+
spans: Vec<SpanTestData>,
17+
}
18+
19+
#[derive(Deserialize, Debug, PartialEq, Eq)]
1420
struct SpanTestData {
1521
pub byte_start: u32,
1622
pub byte_end: u32,
@@ -61,19 +67,11 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
6167

6268
let bytes = output.lock().unwrap();
6369
let actual_output = str::from_utf8(&bytes).unwrap();
64-
let actual_output = json::from_str(&actual_output).unwrap();
65-
let spans = actual_output["spans"].as_array().unwrap();
70+
let actual_output: TestData = serde_json::from_str(actual_output).unwrap();
71+
let spans = actual_output.spans;
6672
assert_eq!(spans.len(), 1);
67-
let obj = &spans[0];
68-
let actual_output = SpanTestData {
69-
byte_start: obj["byte_start"].as_u64().unwrap() as u32,
70-
byte_end: obj["byte_end"].as_u64().unwrap() as u32,
71-
line_start: obj["line_start"].as_u64().unwrap() as u32,
72-
line_end: obj["line_end"].as_u64().unwrap() as u32,
73-
column_start: obj["column_start"].as_u64().unwrap() as u32,
74-
column_end: obj["column_end"].as_u64().unwrap() as u32,
75-
};
76-
assert_eq!(expected_output, actual_output);
73+
74+
assert_eq!(expected_output, spans[0])
7775
})
7876
}
7977

compiler/rustc_interface/src/passes.rs

-9
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ use rustc_passes::{self, hir_stats, layout_test};
2727
use rustc_plugin_impl as plugin;
2828
use rustc_query_impl::{OnDiskCache, Queries as TcxQueries};
2929
use rustc_resolve::{Resolver, ResolverArenas};
30-
use rustc_serialize::json;
3130
use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType};
3231
use rustc_session::cstore::{MetadataLoader, MetadataLoaderDyn};
3332
use rustc_session::output::{filename_for_input, filename_for_metadata};
@@ -59,10 +58,6 @@ pub fn parse<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
5958
}
6059
})?;
6160

62-
if sess.opts.debugging_opts.ast_json_noexpand {
63-
println!("{}", json::as_json(&krate));
64-
}
65-
6661
if sess.opts.debugging_opts.input_stats {
6762
eprintln!("Lines of code: {}", sess.source_map().count_lines());
6863
eprintln!("Pre-expansion node count: {}", count_nodes(&krate));
@@ -423,10 +418,6 @@ pub fn configure_and_expand(
423418
hir_stats::print_ast_stats(&krate, "POST EXPANSION AST STATS");
424419
}
425420

426-
if sess.opts.debugging_opts.ast_json {
427-
println!("{}", json::as_json(&krate));
428-
}
429-
430421
resolver.resolve_crate(&krate);
431422

432423
// Needs to go *after* expansion to be able to check the results of macro expansion.

0 commit comments

Comments
 (0)