Skip to content

Commit 58a721a

Browse files
committed
Auto merge of #93839 - Mark-Simulacrum:delete-json-rust-deserialization, r=nnethercote
Simplify rustc_serialize by dropping support for decoding into JSON This PR currently bundles two (somewhat separate) tasks. First, it removes the JSON Decoder trait impl, which permitted going from JSON to Rust structs. For now, we keep supporting JSON deserialization, but only to `Json` (an equivalent of serde_json::Value). The primary hard to remove user there is for custom targets -- which need some form of JSON deserialization -- but they already have a custom ad-hoc pass for moving from Json to a Rust struct. A [comment](https://github.com/rust-lang/rust/blob/e7aca895980f25f6d2d3c48e10fd04656764d1e4/compiler/rustc_target/src/spec/mod.rs#L1653) there suggests that it would be impractical to move them to a Decodable-based impl, at least without backwards compatibility concerns. I suspect that if we were widely breaking compat there, it would make sense to use serde_json at this point which would produce better error messages; the types in rustc_target are relatively isolated so we would not particularly suffer from using serde_derive. The second part of the PR (all but the first commit) is to simplify the Decoder API by removing the non-primitive `read_*` functions. These primarily add indirection (through a closure), which doesn't directly cause a performance issue (the unique closure types essentially guarantee monomorphization), but does increase the amount of work rustc and LLVM need to do. This could be split out to a separate PR, but is included here in part to help motivate the first part. Future work might consist of: * Specializing enum discriminant encoding to avoid leb128 for small enums (since we know the variant count, we can directly use read/write u8 in almost all cases) * Adding new methods to support faster deserialization (e.g., access to the underlying byte stream) * Currently these are somewhat ad-hoc supported by specializations for e.g. `Vec<u8>`, but other types which could benefit don't today. * Removing the Decoder trait entirely in favor of a concrete type -- today, we only really have one impl of it modulo wrappers used for specialization-based dispatch. Highly recommend review with whitespace changes off, as the removal of closures frequently causes things to be de-indented.
2 parents b8967b0 + c6ad61a commit 58a721a

File tree

15 files changed

+208
-1059
lines changed

15 files changed

+208
-1059
lines changed

compiler/rustc_errors/src/json/tests.rs

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

66
use crate::emitter::{ColorConfig, HumanReadableErrorType};
77
use crate::Handler;
8-
use rustc_serialize::json::decode;
8+
use rustc_serialize::json;
99
use rustc_span::{BytePos, Span};
1010

1111
use std::str;
1212

13-
#[derive(Decodable, Debug, PartialEq, Eq)]
14-
struct TestData {
15-
spans: Vec<SpanTestData>,
16-
}
17-
18-
#[derive(Decodable, Debug, PartialEq, Eq)]
13+
#[derive(Debug, PartialEq, Eq)]
1914
struct SpanTestData {
2015
pub byte_start: u32,
2116
pub byte_end: u32,
@@ -41,8 +36,6 @@ impl<T: Write> Write for Shared<T> {
4136

4237
/// Test the span yields correct positions in JSON.
4338
fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
44-
let expected_output = TestData { spans: vec![expected_output] };
45-
4639
rustc_span::create_default_session_globals_then(|| {
4740
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
4841
sm.new_source_file(Path::new("test.rs").to_owned().into(), code.to_owned());
@@ -64,9 +57,19 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
6457

6558
let bytes = output.lock().unwrap();
6659
let actual_output = str::from_utf8(&bytes).unwrap();
67-
let actual_output: TestData = decode(actual_output);
68-
69-
assert_eq!(expected_output, actual_output)
60+
let actual_output = json::from_str(&actual_output).unwrap();
61+
let spans = actual_output["spans"].as_array().unwrap();
62+
assert_eq!(spans.len(), 1);
63+
let obj = &spans[0];
64+
let actual_output = SpanTestData {
65+
byte_start: obj["byte_start"].as_u64().unwrap() as u32,
66+
byte_end: obj["byte_end"].as_u64().unwrap() as u32,
67+
line_start: obj["line_start"].as_u64().unwrap() as u32,
68+
line_end: obj["line_end"].as_u64().unwrap() as u32,
69+
column_start: obj["column_start"].as_u64().unwrap() as u32,
70+
column_end: obj["column_end"].as_u64().unwrap() as u32,
71+
};
72+
assert_eq!(expected_output, actual_output);
7073
})
7174
}
7275

compiler/rustc_macros/src/serialize.rs

+8-45
Original file line numberDiff line numberDiff line change
@@ -42,51 +42,26 @@ fn decodable_body(
4242
}
4343
let ty_name = s.ast().ident.to_string();
4444
let decode_body = match s.variants() {
45-
[vi] => {
46-
let construct = vi.construct(|field, index| decode_field(field, index, true));
47-
quote! {
48-
::rustc_serialize::Decoder::read_struct(
49-
__decoder,
50-
|__decoder| { #construct },
51-
)
52-
}
53-
}
45+
[vi] => vi.construct(|field, _index| decode_field(field)),
5446
variants => {
5547
let match_inner: TokenStream = variants
5648
.iter()
5749
.enumerate()
5850
.map(|(idx, vi)| {
59-
let construct = vi.construct(|field, index| decode_field(field, index, false));
51+
let construct = vi.construct(|field, _index| decode_field(field));
6052
quote! { #idx => { #construct } }
6153
})
6254
.collect();
63-
let names: TokenStream = variants
64-
.iter()
65-
.map(|vi| {
66-
let variant_name = vi.ast().ident.to_string();
67-
quote!(#variant_name,)
68-
})
69-
.collect();
7055
let message = format!(
7156
"invalid enum variant tag while decoding `{}`, expected 0..{}",
7257
ty_name,
7358
variants.len()
7459
);
7560
quote! {
76-
::rustc_serialize::Decoder::read_enum(
77-
__decoder,
78-
|__decoder| {
79-
::rustc_serialize::Decoder::read_enum_variant(
80-
__decoder,
81-
&[#names],
82-
|__decoder, __variant_idx| {
83-
match __variant_idx {
84-
#match_inner
85-
_ => panic!(#message),
86-
}
87-
})
88-
}
89-
)
61+
match ::rustc_serialize::Decoder::read_usize(__decoder) {
62+
#match_inner
63+
_ => panic!(#message),
64+
}
9065
}
9166
}
9267
};
@@ -101,30 +76,18 @@ fn decodable_body(
10176
)
10277
}
10378

104-
fn decode_field(field: &syn::Field, index: usize, is_struct: bool) -> proc_macro2::TokenStream {
79+
fn decode_field(field: &syn::Field) -> proc_macro2::TokenStream {
10580
let field_span = field.ident.as_ref().map_or(field.ty.span(), |ident| ident.span());
10681

10782
let decode_inner_method = if let syn::Type::Reference(_) = field.ty {
10883
quote! { ::rustc_middle::ty::codec::RefDecodable::decode }
10984
} else {
11085
quote! { ::rustc_serialize::Decodable::decode }
11186
};
112-
let (decode_method, opt_field_name) = if is_struct {
113-
let field_name = field.ident.as_ref().map_or_else(|| index.to_string(), |i| i.to_string());
114-
(proc_macro2::Ident::new("read_struct_field", field_span), quote! { #field_name, })
115-
} else {
116-
(proc_macro2::Ident::new("read_enum_variant_arg", field_span), quote! {})
117-
};
118-
11987
let __decoder = quote! { __decoder };
12088
// Use the span of the field for the method call, so
12189
// that backtraces will point to the field.
122-
let decode_call = quote_spanned! {field_span=>
123-
::rustc_serialize::Decoder::#decode_method(
124-
#__decoder, #opt_field_name #decode_inner_method)
125-
};
126-
127-
quote! { #decode_call }
90+
quote_spanned! {field_span=> #decode_inner_method(#__decoder) }
12891
}
12992

13093
pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {

compiler/rustc_query_system/src/dep_graph/serialized.rs

+18-23
Original file line numberDiff line numberDiff line change
@@ -122,29 +122,24 @@ impl<'a, K: DepKind + Decodable<opaque::Decoder<'a>>> Decodable<opaque::Decoder<
122122
let mut edge_list_data = Vec::with_capacity(edge_count);
123123

124124
for _index in 0..node_count {
125-
d.read_struct(|d| {
126-
let dep_node: DepNode<K> = d.read_struct_field("node", Decodable::decode);
127-
let _i: SerializedDepNodeIndex = nodes.push(dep_node);
128-
debug_assert_eq!(_i.index(), _index);
129-
130-
let fingerprint: Fingerprint =
131-
d.read_struct_field("fingerprint", Decodable::decode);
132-
let _i: SerializedDepNodeIndex = fingerprints.push(fingerprint);
133-
debug_assert_eq!(_i.index(), _index);
134-
135-
d.read_struct_field("edges", |d| {
136-
d.read_seq(|d, len| {
137-
let start = edge_list_data.len().try_into().unwrap();
138-
for _ in 0..len {
139-
let edge = d.read_seq_elt(Decodable::decode);
140-
edge_list_data.push(edge);
141-
}
142-
let end = edge_list_data.len().try_into().unwrap();
143-
let _i: SerializedDepNodeIndex = edge_list_indices.push((start, end));
144-
debug_assert_eq!(_i.index(), _index);
145-
})
146-
})
147-
});
125+
let dep_node: DepNode<K> = Decodable::decode(d);
126+
let _i: SerializedDepNodeIndex = nodes.push(dep_node);
127+
debug_assert_eq!(_i.index(), _index);
128+
129+
let fingerprint: Fingerprint = Decodable::decode(d);
130+
let _i: SerializedDepNodeIndex = fingerprints.push(fingerprint);
131+
debug_assert_eq!(_i.index(), _index);
132+
133+
// Deserialize edges -- sequence of DepNodeIndex
134+
let len = d.read_usize();
135+
let start = edge_list_data.len().try_into().unwrap();
136+
for _ in 0..len {
137+
let edge = Decodable::decode(d);
138+
edge_list_data.push(edge);
139+
}
140+
let end = edge_list_data.len().try_into().unwrap();
141+
let _i: SerializedDepNodeIndex = edge_list_indices.push((start, end));
142+
debug_assert_eq!(_i.index(), _index);
148143
}
149144

150145
let index: FxHashMap<_, _> =

compiler/rustc_serialize/src/collection_impls.rs

+52-55
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ impl<S: Encoder, A: Array<Item: Encodable<S>>> Encodable<S> for SmallVec<A> {
1818

1919
impl<D: Decoder, A: Array<Item: Decodable<D>>> Decodable<D> for SmallVec<A> {
2020
fn decode(d: &mut D) -> SmallVec<A> {
21-
d.read_seq(|d, len| (0..len).map(|_| d.read_seq_elt(|d| Decodable::decode(d))).collect())
21+
let len = d.read_usize();
22+
(0..len).map(|_| Decodable::decode(d)).collect()
2223
}
2324
}
2425

@@ -35,7 +36,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for LinkedList<T> {
3536

3637
impl<D: Decoder, T: Decodable<D>> Decodable<D> for LinkedList<T> {
3738
fn decode(d: &mut D) -> LinkedList<T> {
38-
d.read_seq(|d, len| (0..len).map(|_| d.read_seq_elt(|d| Decodable::decode(d))).collect())
39+
let len = d.read_usize();
40+
(0..len).map(|_| Decodable::decode(d)).collect()
3941
}
4042
}
4143

@@ -52,7 +54,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for VecDeque<T> {
5254

5355
impl<D: Decoder, T: Decodable<D>> Decodable<D> for VecDeque<T> {
5456
fn decode(d: &mut D) -> VecDeque<T> {
55-
d.read_seq(|d, len| (0..len).map(|_| d.read_seq_elt(|d| Decodable::decode(d))).collect())
57+
let len = d.read_usize();
58+
(0..len).map(|_| Decodable::decode(d)).collect()
5659
}
5760
}
5861

@@ -78,15 +81,14 @@ where
7881
V: Decodable<D>,
7982
{
8083
fn decode(d: &mut D) -> BTreeMap<K, V> {
81-
d.read_map(|d, len| {
82-
let mut map = BTreeMap::new();
83-
for _ in 0..len {
84-
let key = d.read_map_elt_key(|d| Decodable::decode(d));
85-
let val = d.read_map_elt_val(|d| Decodable::decode(d));
86-
map.insert(key, val);
87-
}
88-
map
89-
})
84+
let len = d.read_usize();
85+
let mut map = BTreeMap::new();
86+
for _ in 0..len {
87+
let key = Decodable::decode(d);
88+
let val = Decodable::decode(d);
89+
map.insert(key, val);
90+
}
91+
map
9092
}
9193
}
9294

@@ -109,13 +111,12 @@ where
109111
T: Decodable<D> + PartialEq + Ord,
110112
{
111113
fn decode(d: &mut D) -> BTreeSet<T> {
112-
d.read_seq(|d, len| {
113-
let mut set = BTreeSet::new();
114-
for _ in 0..len {
115-
set.insert(d.read_seq_elt(|d| Decodable::decode(d)));
116-
}
117-
set
118-
})
114+
let len = d.read_usize();
115+
let mut set = BTreeSet::new();
116+
for _ in 0..len {
117+
set.insert(Decodable::decode(d));
118+
}
119+
set
119120
}
120121
}
121122

@@ -143,16 +144,15 @@ where
143144
S: BuildHasher + Default,
144145
{
145146
fn decode(d: &mut D) -> HashMap<K, V, S> {
146-
d.read_map(|d, len| {
147-
let state = Default::default();
148-
let mut map = HashMap::with_capacity_and_hasher(len, state);
149-
for _ in 0..len {
150-
let key = d.read_map_elt_key(|d| Decodable::decode(d));
151-
let val = d.read_map_elt_val(|d| Decodable::decode(d));
152-
map.insert(key, val);
153-
}
154-
map
155-
})
147+
let len = d.read_usize();
148+
let state = Default::default();
149+
let mut map = HashMap::with_capacity_and_hasher(len, state);
150+
for _ in 0..len {
151+
let key = Decodable::decode(d);
152+
let val = Decodable::decode(d);
153+
map.insert(key, val);
154+
}
155+
map
156156
}
157157
}
158158

@@ -187,14 +187,13 @@ where
187187
S: BuildHasher + Default,
188188
{
189189
fn decode(d: &mut D) -> HashSet<T, S> {
190-
d.read_seq(|d, len| {
191-
let state = Default::default();
192-
let mut set = HashSet::with_capacity_and_hasher(len, state);
193-
for _ in 0..len {
194-
set.insert(d.read_seq_elt(|d| Decodable::decode(d)));
195-
}
196-
set
197-
})
190+
let len = d.read_usize();
191+
let state = Default::default();
192+
let mut set = HashSet::with_capacity_and_hasher(len, state);
193+
for _ in 0..len {
194+
set.insert(Decodable::decode(d));
195+
}
196+
set
198197
}
199198
}
200199

@@ -222,16 +221,15 @@ where
222221
S: BuildHasher + Default,
223222
{
224223
fn decode(d: &mut D) -> indexmap::IndexMap<K, V, S> {
225-
d.read_map(|d, len| {
226-
let state = Default::default();
227-
let mut map = indexmap::IndexMap::with_capacity_and_hasher(len, state);
228-
for _ in 0..len {
229-
let key = d.read_map_elt_key(|d| Decodable::decode(d));
230-
let val = d.read_map_elt_val(|d| Decodable::decode(d));
231-
map.insert(key, val);
232-
}
233-
map
234-
})
224+
let len = d.read_usize();
225+
let state = Default::default();
226+
let mut map = indexmap::IndexMap::with_capacity_and_hasher(len, state);
227+
for _ in 0..len {
228+
let key = Decodable::decode(d);
229+
let val = Decodable::decode(d);
230+
map.insert(key, val);
231+
}
232+
map
235233
}
236234
}
237235

@@ -256,14 +254,13 @@ where
256254
S: BuildHasher + Default,
257255
{
258256
fn decode(d: &mut D) -> indexmap::IndexSet<T, S> {
259-
d.read_seq(|d, len| {
260-
let state = Default::default();
261-
let mut set = indexmap::IndexSet::with_capacity_and_hasher(len, state);
262-
for _ in 0..len {
263-
set.insert(d.read_seq_elt(|d| Decodable::decode(d)));
264-
}
265-
set
266-
})
257+
let len = d.read_usize();
258+
let state = Default::default();
259+
let mut set = indexmap::IndexSet::with_capacity_and_hasher(len, state);
260+
for _ in 0..len {
261+
set.insert(Decodable::decode(d));
262+
}
263+
set
267264
}
268265
}
269266

0 commit comments

Comments
 (0)