Skip to content

Commit 84322ef

Browse files
committed
Auto merge of #93066 - nnethercote:infallible-decoder, r=bjorn3
Make `Decodable` and `Decoder` infallible. `Decoder` has two impls: - opaque: this impl is already partly infallible, i.e. in some places it currently panics on failure (e.g. if the input is too short, or on a bad `Result` discriminant), and in some places it returns an error (e.g. on a bad `Option` discriminant). The number of places where either happens is surprisingly small, just because the binary representation has very little redundancy and a lot of input reading can occur even on malformed data. - json: this impl is fully fallible, but it's only used (a) for the `.rlink` file production, and there's a `FIXME` comment suggesting it should change to a binary format, and (b) in a few tests in non-fundamental ways. Indeed #85993 is open to remove it entirely. And the top-level places in the compiler that call into decoding just abort on error anyway. So the fallibility is providing little value, and getting rid of it leads to some non-trivial performance improvements. Much of this PR is pretty boring and mechanical. Some notes about a few interesting parts: - The commit removes `Decoder::{Error,error}`. - `InternIteratorElement::intern_with`: the impl for `T` now has the same optimization for small counts that the impl for `Result<T, E>` has, because it's now much hotter. - Decodable impls for SmallVec, LinkedList, VecDeque now all use `collect`, which is nice; the one for `Vec` uses unsafe code, because that gave better perf on some benchmarks. r? `@bjorn3`
2 parents 1e40679 + 37fbd91 commit 84322ef

File tree

39 files changed

+726
-783
lines changed

39 files changed

+726
-783
lines changed

compiler/rustc_ast/src/ast.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -2418,8 +2418,9 @@ impl<S: Encoder> rustc_serialize::Encodable<S> for AttrId {
24182418
}
24192419

24202420
impl<D: Decoder> rustc_serialize::Decodable<D> for AttrId {
2421-
fn decode(d: &mut D) -> Result<AttrId, D::Error> {
2422-
d.read_nil().map(|_| crate::attr::mk_attr_id())
2421+
fn decode(d: &mut D) -> AttrId {
2422+
d.read_unit();
2423+
crate::attr::mk_attr_id()
24232424
}
24242425
}
24252426

compiler/rustc_ast/src/ptr.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ impl<T> fmt::Pointer for P<T> {
115115
}
116116

117117
impl<D: Decoder, T: 'static + Decodable<D>> Decodable<D> for P<T> {
118-
fn decode(d: &mut D) -> Result<P<T>, D::Error> {
119-
Decodable::decode(d).map(P)
118+
fn decode(d: &mut D) -> P<T> {
119+
P(Decodable::decode(d))
120120
}
121121
}
122122

@@ -204,8 +204,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for P<[T]> {
204204
}
205205

206206
impl<D: Decoder, T: Decodable<D>> Decodable<D> for P<[T]> {
207-
fn decode(d: &mut D) -> Result<P<[T]>, D::Error> {
208-
Ok(P::from_vec(Decodable::decode(d)?))
207+
fn decode(d: &mut D) -> P<[T]> {
208+
P::from_vec(Decodable::decode(d))
209209
}
210210
}
211211

compiler/rustc_ast/src/tokenstream.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ impl<S: Encoder> Encodable<S> for LazyTokenStream {
163163
}
164164

165165
impl<D: Decoder> Decodable<D> for LazyTokenStream {
166-
fn decode(_d: &mut D) -> Result<Self, D::Error> {
166+
fn decode(_d: &mut D) -> Self {
167167
panic!("Attempted to decode LazyTokenStream");
168168
}
169169
}

compiler/rustc_data_structures/src/fingerprint.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,10 @@ impl<E: rustc_serialize::Encoder> Encodable<E> for Fingerprint {
149149

150150
impl<D: rustc_serialize::Decoder> Decodable<D> for Fingerprint {
151151
#[inline]
152-
fn decode(d: &mut D) -> Result<Self, D::Error> {
152+
fn decode(d: &mut D) -> Self {
153153
let mut bytes = [0u8; 16];
154-
d.read_raw_bytes_into(&mut bytes)?;
155-
Ok(Fingerprint::from_le_bytes(bytes))
154+
d.read_raw_bytes_into(&mut bytes);
155+
Fingerprint::from_le_bytes(bytes)
156156
}
157157
}
158158

@@ -195,8 +195,8 @@ impl<E: rustc_serialize::Encoder> Encodable<E> for PackedFingerprint {
195195

196196
impl<D: rustc_serialize::Decoder> Decodable<D> for PackedFingerprint {
197197
#[inline]
198-
fn decode(d: &mut D) -> Result<Self, D::Error> {
199-
Fingerprint::decode(d).map(PackedFingerprint)
198+
fn decode(d: &mut D) -> Self {
199+
Self(Fingerprint::decode(d))
200200
}
201201
}
202202

compiler/rustc_data_structures/src/svh.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ impl<S: Encoder> Encodable<S> for Svh {
5555
}
5656

5757
impl<D: Decoder> Decodable<D> for Svh {
58-
fn decode(d: &mut D) -> Result<Svh, D::Error> {
59-
d.read_u64().map(u64::from_le).map(Svh::new)
58+
fn decode(d: &mut D) -> Svh {
59+
Svh::new(u64::from_le(d.read_u64()))
6060
}
6161
}
6262

compiler/rustc_driver/src/lib.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -597,10 +597,7 @@ impl RustcDefaultCalls {
597597
let rlink_data = fs::read_to_string(file).unwrap_or_else(|err| {
598598
sess.fatal(&format!("failed to read rlink file: {}", err));
599599
});
600-
let codegen_results: CodegenResults =
601-
json::decode(&rlink_data).unwrap_or_else(|err| {
602-
sess.fatal(&format!("failed to decode rlink: {}", err));
603-
});
600+
let codegen_results: CodegenResults = json::decode(&rlink_data);
604601
let result = compiler.codegen_backend().link(sess, codegen_results, &outputs);
605602
abort_on_err(result, sess);
606603
} else {

compiler/rustc_errors/src/json/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
6464

6565
let bytes = output.lock().unwrap();
6666
let actual_output = str::from_utf8(&bytes).unwrap();
67-
let actual_output: TestData = decode(actual_output).unwrap();
67+
let actual_output: TestData = decode(actual_output);
6868

6969
assert_eq!(expected_output, actual_output)
7070
})

compiler/rustc_errors/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ impl Hash for ToolMetadata {
9999

100100
// Doesn't really need to round-trip
101101
impl<D: Decoder> Decodable<D> for ToolMetadata {
102-
fn decode(_d: &mut D) -> Result<Self, D::Error> {
103-
Ok(ToolMetadata(None))
102+
fn decode(_d: &mut D) -> Self {
103+
ToolMetadata(None)
104104
}
105105
}
106106

compiler/rustc_incremental/src/persist/load.rs

+3-12
Original file line numberDiff line numberDiff line change
@@ -158,14 +158,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
158158
// Decode the list of work_products
159159
let mut work_product_decoder = Decoder::new(&work_products_data[..], start_pos);
160160
let work_products: Vec<SerializedWorkProduct> =
161-
Decodable::decode(&mut work_product_decoder).unwrap_or_else(|e| {
162-
let msg = format!(
163-
"Error decoding `work-products` from incremental \
164-
compilation session directory: {}",
165-
e
166-
);
167-
sess.fatal(&msg)
168-
});
161+
Decodable::decode(&mut work_product_decoder);
169162

170163
for swp in work_products {
171164
let mut all_files_exist = true;
@@ -203,8 +196,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
203196
LoadResult::Error { message } => LoadResult::Error { message },
204197
LoadResult::Ok { data: (bytes, start_pos) } => {
205198
let mut decoder = Decoder::new(&bytes, start_pos);
206-
let prev_commandline_args_hash = u64::decode(&mut decoder)
207-
.expect("Error reading commandline arg hash from cached dep-graph");
199+
let prev_commandline_args_hash = u64::decode(&mut decoder);
208200

209201
if prev_commandline_args_hash != expected_hash {
210202
if report_incremental_info {
@@ -220,8 +212,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
220212
return LoadResult::DataOutOfDate;
221213
}
222214

223-
let dep_graph = SerializedDepGraph::decode(&mut decoder)
224-
.expect("Error reading cached dep-graph");
215+
let dep_graph = SerializedDepGraph::decode(&mut decoder);
225216

226217
LoadResult::Ok { data: (dep_graph, prev_work_products) }
227218
}

compiler/rustc_index/src/vec.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,8 @@ macro_rules! newtype_index {
395395

396396
(@serializable $type:ident) => (
397397
impl<D: ::rustc_serialize::Decoder> ::rustc_serialize::Decodable<D> for $type {
398-
fn decode(d: &mut D) -> Result<Self, D::Error> {
399-
d.read_u32().map(Self::from_u32)
398+
fn decode(d: &mut D) -> Self {
399+
Self::from_u32(d.read_u32())
400400
}
401401
}
402402
impl<E: ::rustc_serialize::Encoder> ::rustc_serialize::Encodable<E> for $type {
@@ -527,8 +527,8 @@ impl<S: Encoder, I: Idx, T: Encodable<S>> Encodable<S> for &IndexVec<I, T> {
527527
}
528528

529529
impl<D: Decoder, I: Idx, T: Decodable<D>> Decodable<D> for IndexVec<I, T> {
530-
fn decode(d: &mut D) -> Result<Self, D::Error> {
531-
Decodable::decode(d).map(|v| IndexVec { raw: v, _marker: PhantomData })
530+
fn decode(d: &mut D) -> Self {
531+
IndexVec { raw: Decodable::decode(d), _marker: PhantomData }
532532
}
533533
}
534534

compiler/rustc_macros/src/serialize.rs

+5-13
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ fn decodable_body(
4747
quote! {
4848
::rustc_serialize::Decoder::read_struct(
4949
__decoder,
50-
|__decoder| { ::std::result::Result::Ok(#construct) },
50+
|__decoder| { #construct },
5151
)
5252
}
5353
}
@@ -57,7 +57,7 @@ fn decodable_body(
5757
.enumerate()
5858
.map(|(idx, vi)| {
5959
let construct = vi.construct(|field, index| decode_field(field, index, false));
60-
quote! { #idx => { ::std::result::Result::Ok(#construct) } }
60+
quote! { #idx => { #construct } }
6161
})
6262
.collect();
6363
let names: TokenStream = variants
@@ -82,8 +82,7 @@ fn decodable_body(
8282
|__decoder, __variant_idx| {
8383
match __variant_idx {
8484
#match_inner
85-
_ => return ::std::result::Result::Err(
86-
::rustc_serialize::Decoder::error(__decoder, #message)),
85+
_ => panic!(#message),
8786
}
8887
})
8988
}
@@ -95,9 +94,7 @@ fn decodable_body(
9594
s.bound_impl(
9695
quote!(::rustc_serialize::Decodable<#decoder_ty>),
9796
quote! {
98-
fn decode(
99-
__decoder: &mut #decoder_ty,
100-
) -> ::std::result::Result<Self, <#decoder_ty as ::rustc_serialize::Decoder>::Error> {
97+
fn decode(__decoder: &mut #decoder_ty) -> Self {
10198
#decode_body
10299
}
103100
},
@@ -127,12 +124,7 @@ fn decode_field(field: &syn::Field, index: usize, is_struct: bool) -> proc_macro
127124
#__decoder, #opt_field_name #decode_inner_method)
128125
};
129126

130-
quote! {
131-
match #decode_call {
132-
::std::result::Result::Ok(__res) => __res,
133-
::std::result::Result::Err(__err) => return ::std::result::Result::Err(__err),
134-
}
135-
}
127+
quote! { #decode_call }
136128
}
137129

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

0 commit comments

Comments
 (0)