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 commit 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.
This commit is contained in:
Nicholas Nethercote 2022-01-18 13:22:50 +11:00
parent 88600a6d7f
commit 416399dc10
39 changed files with 726 additions and 781 deletions

View File

@ -2418,8 +2418,9 @@ impl<S: Encoder> rustc_serialize::Encodable<S> for AttrId {
}
impl<D: Decoder> rustc_serialize::Decodable<D> for AttrId {
fn decode(d: &mut D) -> Result<AttrId, D::Error> {
d.read_unit().map(|_| crate::attr::mk_attr_id())
fn decode(d: &mut D) -> AttrId {
d.read_unit();
crate::attr::mk_attr_id()
}
}

View File

@ -115,8 +115,8 @@ impl<T> fmt::Pointer for P<T> {
}
impl<D: Decoder, T: 'static + Decodable<D>> Decodable<D> for P<T> {
fn decode(d: &mut D) -> Result<P<T>, D::Error> {
Decodable::decode(d).map(P)
fn decode(d: &mut D) -> P<T> {
P(Decodable::decode(d))
}
}
@ -204,8 +204,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for P<[T]> {
}
impl<D: Decoder, T: Decodable<D>> Decodable<D> for P<[T]> {
fn decode(d: &mut D) -> Result<P<[T]>, D::Error> {
Ok(P::from_vec(Decodable::decode(d)?))
fn decode(d: &mut D) -> P<[T]> {
P::from_vec(Decodable::decode(d))
}
}

View File

@ -163,7 +163,7 @@ impl<S: Encoder> Encodable<S> for LazyTokenStream {
}
impl<D: Decoder> Decodable<D> for LazyTokenStream {
fn decode(_d: &mut D) -> Result<Self, D::Error> {
fn decode(_d: &mut D) -> Self {
panic!("Attempted to decode LazyTokenStream");
}
}

View File

@ -149,10 +149,10 @@ impl<E: rustc_serialize::Encoder> Encodable<E> for Fingerprint {
impl<D: rustc_serialize::Decoder> Decodable<D> for Fingerprint {
#[inline]
fn decode(d: &mut D) -> Result<Self, D::Error> {
fn decode(d: &mut D) -> Self {
let mut bytes = [0u8; 16];
d.read_raw_bytes_into(&mut bytes)?;
Ok(Fingerprint::from_le_bytes(bytes))
d.read_raw_bytes_into(&mut bytes);
Fingerprint::from_le_bytes(bytes)
}
}
@ -195,8 +195,8 @@ impl<E: rustc_serialize::Encoder> Encodable<E> for PackedFingerprint {
impl<D: rustc_serialize::Decoder> Decodable<D> for PackedFingerprint {
#[inline]
fn decode(d: &mut D) -> Result<Self, D::Error> {
Fingerprint::decode(d).map(PackedFingerprint)
fn decode(d: &mut D) -> Self {
Self(Fingerprint::decode(d))
}
}

View File

@ -55,8 +55,8 @@ impl<S: Encoder> Encodable<S> for Svh {
}
impl<D: Decoder> Decodable<D> for Svh {
fn decode(d: &mut D) -> Result<Svh, D::Error> {
d.read_u64().map(u64::from_le).map(Svh::new)
fn decode(d: &mut D) -> Svh {
Svh::new(u64::from_le(d.read_u64()))
}
}

View File

@ -597,10 +597,7 @@ impl RustcDefaultCalls {
let rlink_data = fs::read_to_string(file).unwrap_or_else(|err| {
sess.fatal(&format!("failed to read rlink file: {}", err));
});
let codegen_results: CodegenResults =
json::decode(&rlink_data).unwrap_or_else(|err| {
sess.fatal(&format!("failed to decode rlink: {}", err));
});
let codegen_results: CodegenResults = json::decode(&rlink_data);
let result = compiler.codegen_backend().link(sess, codegen_results, &outputs);
abort_on_err(result, sess);
} else {

View File

@ -64,7 +64,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
let bytes = output.lock().unwrap();
let actual_output = str::from_utf8(&bytes).unwrap();
let actual_output: TestData = decode(actual_output).unwrap();
let actual_output: TestData = decode(actual_output);
assert_eq!(expected_output, actual_output)
})

View File

@ -99,8 +99,8 @@ impl Hash for ToolMetadata {
// Doesn't really need to round-trip
impl<D: Decoder> Decodable<D> for ToolMetadata {
fn decode(_d: &mut D) -> Result<Self, D::Error> {
Ok(ToolMetadata(None))
fn decode(_d: &mut D) -> Self {
ToolMetadata(None)
}
}

View File

@ -158,14 +158,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
// Decode the list of work_products
let mut work_product_decoder = Decoder::new(&work_products_data[..], start_pos);
let work_products: Vec<SerializedWorkProduct> =
Decodable::decode(&mut work_product_decoder).unwrap_or_else(|e| {
let msg = format!(
"Error decoding `work-products` from incremental \
compilation session directory: {}",
e
);
sess.fatal(&msg)
});
Decodable::decode(&mut work_product_decoder);
for swp in work_products {
let mut all_files_exist = true;
@ -203,8 +196,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
LoadResult::Error { message } => LoadResult::Error { message },
LoadResult::Ok { data: (bytes, start_pos) } => {
let mut decoder = Decoder::new(&bytes, start_pos);
let prev_commandline_args_hash = u64::decode(&mut decoder)
.expect("Error reading commandline arg hash from cached dep-graph");
let prev_commandline_args_hash = u64::decode(&mut decoder);
if prev_commandline_args_hash != expected_hash {
if report_incremental_info {
@ -220,8 +212,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
return LoadResult::DataOutOfDate;
}
let dep_graph = SerializedDepGraph::decode(&mut decoder)
.expect("Error reading cached dep-graph");
let dep_graph = SerializedDepGraph::decode(&mut decoder);
LoadResult::Ok { data: (dep_graph, prev_work_products) }
}

View File

@ -395,8 +395,8 @@ macro_rules! newtype_index {
(@serializable $type:ident) => (
impl<D: ::rustc_serialize::Decoder> ::rustc_serialize::Decodable<D> for $type {
fn decode(d: &mut D) -> Result<Self, D::Error> {
d.read_u32().map(Self::from_u32)
fn decode(d: &mut D) -> Self {
Self::from_u32(d.read_u32())
}
}
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> {
}
impl<D: Decoder, I: Idx, T: Decodable<D>> Decodable<D> for IndexVec<I, T> {
fn decode(d: &mut D) -> Result<Self, D::Error> {
Decodable::decode(d).map(|v| IndexVec { raw: v, _marker: PhantomData })
fn decode(d: &mut D) -> Self {
IndexVec { raw: Decodable::decode(d), _marker: PhantomData }
}
}

View File

@ -47,7 +47,7 @@ fn decodable_body(
quote! {
::rustc_serialize::Decoder::read_struct(
__decoder,
|__decoder| { ::std::result::Result::Ok(#construct) },
|__decoder| { #construct },
)
}
}
@ -57,7 +57,7 @@ fn decodable_body(
.enumerate()
.map(|(idx, vi)| {
let construct = vi.construct(|field, index| decode_field(field, index, false));
quote! { #idx => { ::std::result::Result::Ok(#construct) } }
quote! { #idx => { #construct } }
})
.collect();
let names: TokenStream = variants
@ -82,8 +82,7 @@ fn decodable_body(
|__decoder, __variant_idx| {
match __variant_idx {
#match_inner
_ => return ::std::result::Result::Err(
::rustc_serialize::Decoder::error(__decoder, #message)),
_ => panic!(#message),
}
})
}
@ -95,9 +94,7 @@ fn decodable_body(
s.bound_impl(
quote!(::rustc_serialize::Decodable<#decoder_ty>),
quote! {
fn decode(
__decoder: &mut #decoder_ty,
) -> ::std::result::Result<Self, <#decoder_ty as ::rustc_serialize::Decoder>::Error> {
fn decode(__decoder: &mut #decoder_ty) -> Self {
#decode_body
}
},
@ -127,12 +124,7 @@ fn decode_field(field: &syn::Field, index: usize, is_struct: bool) -> proc_macro
#__decoder, #opt_field_name #decode_inner_method)
};
quote! {
match #decode_call {
::std::result::Result::Ok(__res) => __res,
::std::result::Result::Err(__err) => return ::std::result::Result::Err(__err),
}
}
quote! { #decode_call }
}
pub fn type_encodable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStream {

View File

@ -263,7 +263,7 @@ impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Lazy<T> {
fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T {
let mut dcx = metadata.decoder(self.position.get());
dcx.lazy_state = LazyState::NodeStart(self.position);
T::decode(&mut dcx).unwrap()
T::decode(&mut dcx)
}
}
@ -274,7 +274,7 @@ impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable<DecodeContext<'a, 'tcx>>> Lazy<[T]> {
) -> impl ExactSizeIterator<Item = T> + Captures<'a> + Captures<'tcx> + 'x {
let mut dcx = metadata.decoder(self.position.get());
dcx.lazy_state = LazyState::NodeStart(self.position);
(0..self.meta).map(move |_| T::decode(&mut dcx).unwrap())
(0..self.meta).map(move |_| T::decode(&mut dcx))
}
}
@ -300,11 +300,8 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
if cnum == LOCAL_CRATE { self.cdata().cnum } else { self.cdata().cnum_map[cnum] }
}
fn read_lazy_with_meta<T: ?Sized + LazyMeta>(
&mut self,
meta: T::Meta,
) -> Result<Lazy<T>, <Self as Decoder>::Error> {
let distance = self.read_usize()?;
fn read_lazy_with_meta<T: ?Sized + LazyMeta>(&mut self, meta: T::Meta) -> Lazy<T> {
let distance = self.read_usize();
let position = match self.lazy_state {
LazyState::NoNode => bug!("read_lazy_with_meta: outside of a metadata node"),
LazyState::NodeStart(start) => {
@ -315,7 +312,7 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
LazyState::Previous(last_pos) => last_pos.get() + distance,
};
self.lazy_state = LazyState::Previous(NonZeroUsize::new(position).unwrap());
Ok(Lazy::from_position_and_meta(NonZeroUsize::new(position).unwrap(), meta))
Lazy::from_position_and_meta(NonZeroUsize::new(position).unwrap(), meta)
}
#[inline]
@ -342,25 +339,21 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
self.opaque.position()
}
fn cached_ty_for_shorthand<F>(
&mut self,
shorthand: usize,
or_insert_with: F,
) -> Result<Ty<'tcx>, Self::Error>
fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx>
where
F: FnOnce(&mut Self) -> Result<Ty<'tcx>, Self::Error>,
F: FnOnce(&mut Self) -> Ty<'tcx>,
{
let tcx = self.tcx();
let key = ty::CReaderCacheKey { cnum: Some(self.cdata().cnum), pos: shorthand };
if let Some(&ty) = tcx.ty_rcache.borrow().get(&key) {
return Ok(ty);
return ty;
}
let ty = or_insert_with(self)?;
let ty = or_insert_with(self);
tcx.ty_rcache.borrow_mut().insert(key, ty);
Ok(ty)
ty
}
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
@ -376,7 +369,7 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
r
}
fn decode_alloc_id(&mut self) -> Result<rustc_middle::mir::interpret::AllocId, Self::Error> {
fn decode_alloc_id(&mut self) -> rustc_middle::mir::interpret::AllocId {
if let Some(alloc_decoding_session) = self.alloc_decoding_session {
alloc_decoding_session.decode_alloc_id(self)
} else {
@ -386,48 +379,48 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for CrateNum {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result<CrateNum, String> {
let cnum = CrateNum::from_u32(d.read_u32()?);
Ok(d.map_encoded_cnum_to_current(cnum))
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> CrateNum {
let cnum = CrateNum::from_u32(d.read_u32());
d.map_encoded_cnum_to_current(cnum)
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefIndex {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result<DefIndex, String> {
Ok(DefIndex::from_u32(d.read_u32()?))
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefIndex {
DefIndex::from_u32(d.read_u32())
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnIndex {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result<ExpnIndex, String> {
Ok(ExpnIndex::from_u32(d.read_u32()?))
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> ExpnIndex {
ExpnIndex::from_u32(d.read_u32())
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SyntaxContext {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<SyntaxContext, String> {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> SyntaxContext {
let cdata = decoder.cdata();
let sess = decoder.sess.unwrap();
let cname = cdata.root.name;
rustc_span::hygiene::decode_syntax_context(decoder, &cdata.hygiene_context, |_, id| {
debug!("SpecializedDecoder<SyntaxContext>: decoding {}", id);
Ok(cdata
cdata
.root
.syntax_contexts
.get(cdata, id)
.unwrap_or_else(|| panic!("Missing SyntaxContext {:?} for crate {:?}", id, cname))
.decode((cdata, sess)))
.decode((cdata, sess))
})
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<ExpnId, String> {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> ExpnId {
let local_cdata = decoder.cdata();
let sess = decoder.sess.unwrap();
let cnum = CrateNum::decode(decoder)?;
let index = u32::decode(decoder)?;
let cnum = CrateNum::decode(decoder);
let index = u32::decode(decoder);
let expn_id = rustc_span::hygiene::decode_expn_id(cnum, index, |expn_id| {
let ExpnId { krate: cnum, local_id: index } = expn_id;
@ -453,23 +446,23 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
.decode((crate_data, sess));
(expn_data, expn_hash)
});
Ok(expn_id)
expn_id
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<Span, String> {
let ctxt = SyntaxContext::decode(decoder)?;
let tag = u8::decode(decoder)?;
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Span {
let ctxt = SyntaxContext::decode(decoder);
let tag = u8::decode(decoder);
if tag == TAG_PARTIAL_SPAN {
return Ok(DUMMY_SP.with_ctxt(ctxt));
return DUMMY_SP.with_ctxt(ctxt);
}
debug_assert!(tag == TAG_VALID_SPAN_LOCAL || tag == TAG_VALID_SPAN_FOREIGN);
let lo = BytePos::decode(decoder)?;
let len = BytePos::decode(decoder)?;
let lo = BytePos::decode(decoder);
let len = BytePos::decode(decoder);
let hi = lo + len;
let Some(sess) = decoder.sess else {
@ -512,7 +505,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
if decoder.cdata().root.is_proc_macro_crate() {
// Decode `CrateNum` as u32 - using `CrateNum::decode` will ICE
// since we don't have `cnum_map` populated.
let cnum = u32::decode(decoder)?;
let cnum = u32::decode(decoder);
panic!(
"Decoding of crate {:?} tried to access proc-macro dep {:?}",
decoder.cdata().root.name,
@ -520,7 +513,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
);
}
// tag is TAG_VALID_SPAN_FOREIGN, checked by `debug_assert` above
let cnum = CrateNum::decode(decoder)?;
let cnum = CrateNum::decode(decoder);
debug!(
"SpecializedDecoder<Span>::specialized_decode: loading source files from cnum {:?}",
cnum
@ -582,18 +575,18 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
(hi + source_file.translated_source_file.start_pos) - source_file.original_start_pos;
// Do not try to decode parent for foreign spans.
Ok(Span::new(lo, hi, ctxt, None))
Span::new(lo, hi, ctxt, None)
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [thir::abstract_const::Node<'tcx>] {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result<Self, String> {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
ty::codec::RefDecodable::decode(d)
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx>, Span)] {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result<Self, String> {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
ty::codec::RefDecodable::decode(d)
}
}
@ -601,7 +594,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx
impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a, 'tcx>>
for Lazy<T>
{
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<Self, String> {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
decoder.read_lazy_with_meta(())
}
}
@ -609,9 +602,9 @@ impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a
impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a, 'tcx>>
for Lazy<[T]>
{
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<Self, String> {
let len = decoder.read_usize()?;
if len == 0 { Ok(Lazy::empty()) } else { decoder.read_lazy_with_meta(len) }
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
let len = decoder.read_usize();
if len == 0 { Lazy::empty() } else { decoder.read_lazy_with_meta(len) }
}
}
@ -620,8 +613,8 @@ impl<'a, 'tcx, I: Idx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeCo
where
Option<T>: FixedSizeEncoding,
{
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Result<Self, String> {
let len = decoder.read_usize()?;
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
let len = decoder.read_usize();
decoder.read_lazy_with_meta(len)
}
}

View File

@ -39,11 +39,11 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for DefPathHashMapRef<'tcx> {
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefPathHashMapRef<'static> {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Result<DefPathHashMapRef<'static>, String> {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefPathHashMapRef<'static> {
// Import TyDecoder so we can access the DecodeContext::position() method
use crate::rustc_middle::ty::codec::TyDecoder;
let len = d.read_usize()?;
let len = d.read_usize();
let pos = d.position();
let o = OwningRef::new(d.blob().clone()).map(|x| &x[pos..pos + len]);
@ -52,7 +52,9 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefPathHashMapRef<'static>
// the method. We use read_raw_bytes() for that.
let _ = d.read_raw_bytes(len);
let inner = odht::HashTable::from_raw_bytes(o).map_err(|e| format!("{}", e))?;
Ok(DefPathHashMapRef::OwnedFromMetadata(inner))
let inner = odht::HashTable::from_raw_bytes(o).unwrap_or_else(|e| {
panic!("decode error: {}", e);
});
DefPathHashMapRef::OwnedFromMetadata(inner)
}
}

View File

@ -45,8 +45,9 @@ impl<S: serialize::Encoder> serialize::Encodable<S> for GraphIsCyclicCache {
impl<D: serialize::Decoder> serialize::Decodable<D> for GraphIsCyclicCache {
#[inline]
fn decode(d: &mut D) -> Result<Self, D::Error> {
serialize::Decodable::decode(d).map(|_v: ()| Self::new())
fn decode(d: &mut D) -> Self {
let () = serialize::Decodable::decode(d);
Self::new()
}
}

View File

@ -273,20 +273,20 @@ pub struct AllocDecodingSession<'s> {
impl<'s> AllocDecodingSession<'s> {
/// Decodes an `AllocId` in a thread-safe way.
pub fn decode_alloc_id<'tcx, D>(&self, decoder: &mut D) -> Result<AllocId, D::Error>
pub fn decode_alloc_id<'tcx, D>(&self, decoder: &mut D) -> AllocId
where
D: TyDecoder<'tcx>,
{
// Read the index of the allocation.
let idx = usize::try_from(decoder.read_u32()?).unwrap();
let idx = usize::try_from(decoder.read_u32()).unwrap();
let pos = usize::try_from(self.state.data_offsets[idx]).unwrap();
// Decode the `AllocDiscriminant` now so that we know if we have to reserve an
// `AllocId`.
let (alloc_kind, pos) = decoder.with_position(pos, |decoder| {
let alloc_kind = AllocDiscriminant::decode(decoder)?;
Ok((alloc_kind, decoder.position()))
})?;
let alloc_kind = AllocDiscriminant::decode(decoder);
(alloc_kind, decoder.position())
});
// Check the decoding state to see if it's already decoded or if we should
// decode it here.
@ -295,7 +295,7 @@ impl<'s> AllocDecodingSession<'s> {
match *entry {
State::Done(alloc_id) => {
return Ok(alloc_id);
return alloc_id;
}
ref mut entry @ State::Empty => {
// We are allowed to decode.
@ -329,7 +329,7 @@ impl<'s> AllocDecodingSession<'s> {
State::InProgress(ref mut sessions, alloc_id) => {
if sessions.contains(&self.session_id) {
// Don't recurse.
return Ok(alloc_id);
return alloc_id;
} else {
// Start decoding concurrently.
sessions.insert(self.session_id);
@ -343,37 +343,37 @@ impl<'s> AllocDecodingSession<'s> {
let alloc_id = decoder.with_position(pos, |decoder| {
match alloc_kind {
AllocDiscriminant::Alloc => {
let alloc = <&'tcx Allocation as Decodable<_>>::decode(decoder)?;
let alloc = <&'tcx Allocation as Decodable<_>>::decode(decoder);
// We already have a reserved `AllocId`.
let alloc_id = alloc_id.unwrap();
trace!("decoded alloc {:?}: {:#?}", alloc_id, alloc);
decoder.tcx().set_alloc_id_same_memory(alloc_id, alloc);
Ok(alloc_id)
alloc_id
}
AllocDiscriminant::Fn => {
assert!(alloc_id.is_none());
trace!("creating fn alloc ID");
let instance = ty::Instance::decode(decoder)?;
let instance = ty::Instance::decode(decoder);
trace!("decoded fn alloc instance: {:?}", instance);
let alloc_id = decoder.tcx().create_fn_alloc(instance);
Ok(alloc_id)
alloc_id
}
AllocDiscriminant::Static => {
assert!(alloc_id.is_none());
trace!("creating extern static alloc ID");
let did = <DefId as Decodable<D>>::decode(decoder)?;
let did = <DefId as Decodable<D>>::decode(decoder);
trace!("decoded static def-ID: {:?}", did);
let alloc_id = decoder.tcx().create_static_alloc(did);
Ok(alloc_id)
alloc_id
}
}
})?;
});
self.state.decoding_state[idx].with_lock(|entry| {
*entry = State::Done(alloc_id);
});
Ok(alloc_id)
alloc_id
}
}

View File

@ -619,20 +619,20 @@ impl<'tcx, E: TyEncoder<'tcx>, T: Encodable<E>> Encodable<E> for ClearCrossCrate
}
impl<'tcx, D: TyDecoder<'tcx>, T: Decodable<D>> Decodable<D> for ClearCrossCrate<T> {
#[inline]
fn decode(d: &mut D) -> Result<ClearCrossCrate<T>, D::Error> {
fn decode(d: &mut D) -> ClearCrossCrate<T> {
if D::CLEAR_CROSS_CRATE {
return Ok(ClearCrossCrate::Clear);
return ClearCrossCrate::Clear;
}
let discr = u8::decode(d)?;
let discr = u8::decode(d);
match discr {
TAG_CLEAR_CROSS_CRATE_CLEAR => Ok(ClearCrossCrate::Clear),
TAG_CLEAR_CROSS_CRATE_CLEAR => ClearCrossCrate::Clear,
TAG_CLEAR_CROSS_CRATE_SET => {
let val = T::decode(d)?;
Ok(ClearCrossCrate::Set(val))
let val = T::decode(d);
ClearCrossCrate::Set(val)
}
tag => Err(d.error(&format!("Invalid tag for ClearCrossCrate: {:?}", tag))),
tag => panic!("Invalid tag for ClearCrossCrate: {:?}", tag),
}
}
}

View File

@ -57,14 +57,15 @@ impl PredecessorCache {
impl<S: serialize::Encoder> serialize::Encodable<S> for PredecessorCache {
#[inline]
fn encode(&self, s: &mut S) -> Result<(), S::Error> {
serialize::Encodable::encode(&(), s)
s.emit_unit()
}
}
impl<D: serialize::Decoder> serialize::Decodable<D> for PredecessorCache {
#[inline]
fn decode(d: &mut D) -> Result<Self, D::Error> {
serialize::Decodable::decode(d).map(|_v: ()| Self::new())
fn decode(d: &mut D) -> Self {
let () = d.read_unit();
Self::new()
}
}

View File

@ -14,7 +14,7 @@ use crate::mir::{
};
use crate::thir;
use crate::ty::subst::SubstsRef;
use crate::ty::{self, List, Ty, TyCtxt};
use crate::ty::{self, Ty, TyCtxt};
use rustc_data_structures::fx::FxHashMap;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_span::Span;
@ -71,7 +71,7 @@ pub trait TyEncoder<'tcx>: Encoder {
/// `Decodable` can still be implemented in cases where `Decodable` is required
/// by a trait bound.
pub trait RefDecodable<'tcx, D: TyDecoder<'tcx>> {
fn decode(d: &mut D) -> Result<&'tcx Self, D::Error>;
fn decode(d: &mut D) -> &'tcx Self;
}
/// Encode the given value or a previously cached shorthand.
@ -172,13 +172,9 @@ pub trait TyDecoder<'tcx>: Decoder {
fn position(&self) -> usize;
fn cached_ty_for_shorthand<F>(
&mut self,
shorthand: usize,
or_insert_with: F,
) -> Result<Ty<'tcx>, Self::Error>
fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx>
where
F: FnOnce(&mut Self) -> Result<Ty<'tcx>, Self::Error>;
F: FnOnce(&mut Self) -> Ty<'tcx>;
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
where
@ -188,35 +184,35 @@ pub trait TyDecoder<'tcx>: Decoder {
(self.peek_byte() & (SHORTHAND_OFFSET as u8)) != 0
}
fn decode_alloc_id(&mut self) -> Result<AllocId, Self::Error>;
fn decode_alloc_id(&mut self) -> AllocId;
}
#[inline]
fn decode_arena_allocable<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable<D>>(
decoder: &mut D,
) -> Result<&'tcx T, D::Error>
) -> &'tcx T
where
D: TyDecoder<'tcx>,
{
Ok(decoder.tcx().arena.alloc(Decodable::decode(decoder)?))
decoder.tcx().arena.alloc(Decodable::decode(decoder))
}
#[inline]
fn decode_arena_allocable_slice<'tcx, D, T: ArenaAllocatable<'tcx> + Decodable<D>>(
decoder: &mut D,
) -> Result<&'tcx [T], D::Error>
) -> &'tcx [T]
where
D: TyDecoder<'tcx>,
{
Ok(decoder.tcx().arena.alloc_from_iter(<Vec<T> as Decodable<D>>::decode(decoder)?))
decoder.tcx().arena.alloc_from_iter(<Vec<T> as Decodable<D>>::decode(decoder))
}
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for Ty<'tcx> {
#[allow(rustc::usage_of_ty_tykind)]
fn decode(decoder: &mut D) -> Result<Ty<'tcx>, D::Error> {
fn decode(decoder: &mut D) -> Ty<'tcx> {
// Handle shorthands first, if we have a usize > 0x80.
if decoder.positioned_at_shorthand() {
let pos = decoder.read_usize()?;
let pos = decoder.read_usize();
assert!(pos >= SHORTHAND_OFFSET);
let shorthand = pos - SHORTHAND_OFFSET;
@ -225,87 +221,89 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for Ty<'tcx> {
})
} else {
let tcx = decoder.tcx();
Ok(tcx.mk_ty(ty::TyKind::decode(decoder)?))
tcx.mk_ty(ty::TyKind::decode(decoder))
}
}
}
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Binder<'tcx, ty::PredicateKind<'tcx>> {
fn decode(decoder: &mut D) -> Result<ty::Binder<'tcx, ty::PredicateKind<'tcx>>, D::Error> {
let bound_vars = Decodable::decode(decoder)?;
fn decode(decoder: &mut D) -> ty::Binder<'tcx, ty::PredicateKind<'tcx>> {
let bound_vars = Decodable::decode(decoder);
// Handle shorthands first, if we have a usize > 0x80.
Ok(ty::Binder::bind_with_vars(
ty::Binder::bind_with_vars(
if decoder.positioned_at_shorthand() {
let pos = decoder.read_usize()?;
let pos = decoder.read_usize();
assert!(pos >= SHORTHAND_OFFSET);
let shorthand = pos - SHORTHAND_OFFSET;
decoder.with_position(shorthand, ty::PredicateKind::decode)?
decoder.with_position(shorthand, ty::PredicateKind::decode)
} else {
ty::PredicateKind::decode(decoder)?
ty::PredicateKind::decode(decoder)
},
bound_vars,
))
)
}
}
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Predicate<'tcx> {
fn decode(decoder: &mut D) -> Result<ty::Predicate<'tcx>, D::Error> {
let predicate_kind = Decodable::decode(decoder)?;
let predicate = decoder.tcx().mk_predicate(predicate_kind);
Ok(predicate)
fn decode(decoder: &mut D) -> ty::Predicate<'tcx> {
let predicate_kind = Decodable::decode(decoder);
decoder.tcx().mk_predicate(predicate_kind)
}
}
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for SubstsRef<'tcx> {
fn decode(decoder: &mut D) -> Result<Self, D::Error> {
let len = decoder.read_usize()?;
fn decode(decoder: &mut D) -> Self {
let len = decoder.read_usize();
let tcx = decoder.tcx();
tcx.mk_substs((0..len).map(|_| Decodable::decode(decoder)))
tcx.mk_substs(
(0..len).map::<ty::subst::GenericArg<'tcx>, _>(|_| Decodable::decode(decoder)),
)
}
}
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for mir::Place<'tcx> {
fn decode(decoder: &mut D) -> Result<Self, D::Error> {
let local: mir::Local = Decodable::decode(decoder)?;
let len = decoder.read_usize()?;
let projection: &'tcx List<mir::PlaceElem<'tcx>> =
decoder.tcx().mk_place_elems((0..len).map(|_| Decodable::decode(decoder)))?;
Ok(mir::Place { local, projection })
fn decode(decoder: &mut D) -> Self {
let local: mir::Local = Decodable::decode(decoder);
let len = decoder.read_usize();
let projection = decoder.tcx().mk_place_elems(
(0..len).map::<mir::PlaceElem<'tcx>, _>(|_| Decodable::decode(decoder)),
);
mir::Place { local, projection }
}
}
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Region<'tcx> {
fn decode(decoder: &mut D) -> Result<Self, D::Error> {
Ok(decoder.tcx().mk_region(Decodable::decode(decoder)?))
fn decode(decoder: &mut D) -> Self {
decoder.tcx().mk_region(Decodable::decode(decoder))
}
}
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for CanonicalVarInfos<'tcx> {
fn decode(decoder: &mut D) -> Result<Self, D::Error> {
let len = decoder.read_usize()?;
let interned: Result<Vec<CanonicalVarInfo<'tcx>>, _> =
fn decode(decoder: &mut D) -> Self {
let len = decoder.read_usize();
let interned: Vec<CanonicalVarInfo<'tcx>> =
(0..len).map(|_| Decodable::decode(decoder)).collect();
Ok(decoder.tcx().intern_canonical_var_infos(interned?.as_slice()))
decoder.tcx().intern_canonical_var_infos(interned.as_slice())
}
}
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for AllocId {
fn decode(decoder: &mut D) -> Result<Self, D::Error> {
fn decode(decoder: &mut D) -> Self {
decoder.decode_alloc_id()
}
}
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::SymbolName<'tcx> {
fn decode(decoder: &mut D) -> Result<Self, D::Error> {
Ok(ty::SymbolName::new(decoder.tcx(), &decoder.read_str()?))
fn decode(decoder: &mut D) -> Self {
ty::SymbolName::new(decoder.tcx(), &decoder.read_str())
}
}
macro_rules! impl_decodable_via_ref {
($($t:ty),+) => {
$(impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for $t {
fn decode(decoder: &mut D) -> Result<Self, D::Error> {
fn decode(decoder: &mut D) -> Self {
RefDecodable::decode(decoder)
}
})*
@ -313,77 +311,73 @@ macro_rules! impl_decodable_via_ref {
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<Ty<'tcx>> {
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
let len = decoder.read_usize()?;
decoder.tcx().mk_type_list((0..len).map(|_| Decodable::decode(decoder)))
fn decode(decoder: &mut D) -> &'tcx Self {
let len = decoder.read_usize();
decoder.tcx().mk_type_list((0..len).map::<Ty<'tcx>, _>(|_| Decodable::decode(decoder)))
}
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D>
for ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>
{
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
let len = decoder.read_usize()?;
decoder.tcx().mk_poly_existential_predicates((0..len).map(|_| Decodable::decode(decoder)))
fn decode(decoder: &mut D) -> &'tcx Self {
let len = decoder.read_usize();
decoder.tcx().mk_poly_existential_predicates(
(0..len).map::<ty::Binder<'tcx, _>, _>(|_| Decodable::decode(decoder)),
)
}
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::Const<'tcx> {
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
Ok(decoder.tcx().mk_const(Decodable::decode(decoder)?))
fn decode(decoder: &mut D) -> &'tcx Self {
decoder.tcx().mk_const(Decodable::decode(decoder))
}
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [ty::ValTree<'tcx>] {
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
Ok(decoder.tcx().arena.alloc_from_iter(
(0..decoder.read_usize()?)
.map(|_| Decodable::decode(decoder))
.collect::<Result<Vec<_>, _>>()?,
))
fn decode(decoder: &mut D) -> &'tcx Self {
decoder.tcx().arena.alloc_from_iter(
(0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
)
}
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for Allocation {
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
Ok(decoder.tcx().intern_const_alloc(Decodable::decode(decoder)?))
fn decode(decoder: &mut D) -> &'tcx Self {
decoder.tcx().intern_const_alloc(Decodable::decode(decoder))
}
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [(ty::Predicate<'tcx>, Span)] {
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
Ok(decoder.tcx().arena.alloc_from_iter(
(0..decoder.read_usize()?)
.map(|_| Decodable::decode(decoder))
.collect::<Result<Vec<_>, _>>()?,
))
fn decode(decoder: &mut D) -> &'tcx Self {
decoder.tcx().arena.alloc_from_iter(
(0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
)
}
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [thir::abstract_const::Node<'tcx>] {
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
Ok(decoder.tcx().arena.alloc_from_iter(
(0..decoder.read_usize()?)
.map(|_| Decodable::decode(decoder))
.collect::<Result<Vec<_>, _>>()?,
))
fn decode(decoder: &mut D) -> &'tcx Self {
decoder.tcx().arena.alloc_from_iter(
(0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
)
}
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [thir::abstract_const::NodeId] {
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
Ok(decoder.tcx().arena.alloc_from_iter(
(0..decoder.read_usize()?)
.map(|_| Decodable::decode(decoder))
.collect::<Result<Vec<_>, _>>()?,
))
fn decode(decoder: &mut D) -> &'tcx Self {
decoder.tcx().arena.alloc_from_iter(
(0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::<Vec<_>>(),
)
}
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::List<ty::BoundVariableKind> {
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
let len = decoder.read_usize()?;
decoder.tcx().mk_bound_variable_kinds((0..len).map(|_| Decodable::decode(decoder)))
fn decode(decoder: &mut D) -> &'tcx Self {
let len = decoder.read_usize();
decoder.tcx().mk_bound_variable_kinds(
(0..len).map::<ty::BoundVariableKind, _>(|_| Decodable::decode(decoder)),
)
}
}
@ -405,7 +399,7 @@ macro_rules! __impl_decoder_methods {
($($name:ident -> $ty:ty;)*) => {
$(
#[inline]
fn $name(&mut self) -> Result<$ty, Self::Error> {
fn $name(&mut self) -> $ty {
self.opaque.$name()
}
)*
@ -418,14 +412,14 @@ macro_rules! impl_arena_allocatable_decoder {
[$name:ident: $ty:ty]) => {
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for $ty {
#[inline]
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
fn decode(decoder: &mut D) -> &'tcx Self {
decode_arena_allocable(decoder)
}
}
impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [$ty] {
#[inline]
fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> {
fn decode(decoder: &mut D) -> &'tcx Self {
decode_arena_allocable_slice(decoder)
}
}
@ -456,8 +450,6 @@ macro_rules! implement_ty_decoder {
use super::$DecoderName;
impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> {
type Error = String;
$crate::__impl_decoder_methods! {
read_unit -> ();
@ -483,13 +475,9 @@ macro_rules! implement_ty_decoder {
}
#[inline]
fn read_raw_bytes_into(&mut self, bytes: &mut [u8]) -> Result<(), Self::Error> {
fn read_raw_bytes_into(&mut self, bytes: &mut [u8]) -> () {
self.opaque.read_raw_bytes_into(bytes)
}
fn error(&mut self, err: &str) -> Self::Error {
self.opaque.error(err)
}
}
}
}
@ -505,9 +493,9 @@ macro_rules! impl_binder_encode_decode {
}
}
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Binder<'tcx, $t> {
fn decode(decoder: &mut D) -> Result<Self, D::Error> {
let bound_vars = Decodable::decode(decoder)?;
Ok(ty::Binder::bind_with_vars(Decodable::decode(decoder)?, bound_vars))
fn decode(decoder: &mut D) -> Self {
let bound_vars = Decodable::decode(decoder);
ty::Binder::bind_with_vars(Decodable::decode(decoder), bound_vars)
}
}
)*

View File

@ -147,8 +147,8 @@ impl<S: Encoder> Encodable<S> for ScalarInt {
}
impl<D: Decoder> Decodable<D> for ScalarInt {
fn decode(d: &mut D) -> Result<ScalarInt, D::Error> {
Ok(ScalarInt { data: d.read_u128()?, size: d.read_u8()? })
fn decode(d: &mut D) -> ScalarInt {
ScalarInt { data: d.read_u128(), size: d.read_u8() }
}
}

View File

@ -2786,8 +2786,33 @@ pub trait InternIteratorElement<T, R>: Sized {
impl<T, R> InternIteratorElement<T, R> for T {
type Output = R;
fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
f(&iter.collect::<SmallVec<[_; 8]>>())
fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(
mut iter: I,
f: F,
) -> Self::Output {
// This code is hot enough that it's worth specializing for the most
// common length lists, to avoid the overhead of `SmallVec` creation.
// Lengths 0, 1, and 2 typically account for ~95% of cases. We assume
// that if the upper and lower bounds from `size_hint` agree they are
// correct.
match iter.size_hint() {
(0, Some(0)) => {
assert!(iter.next().is_none());
f(&[])
}
(1, Some(1)) => {
let t0 = iter.next().unwrap();
assert!(iter.next().is_none());
f(&[t0])
}
(2, Some(2)) => {
let t0 = iter.next().unwrap();
let t1 = iter.next().unwrap();
assert!(iter.next().is_none());
f(&[t0, t1])
}
_ => f(&iter.collect::<SmallVec<[_; 8]>>()),
}
}
}
@ -2797,6 +2822,7 @@ where
{
type Output = R;
fn intern_with<I: Iterator<Item = Self>, F: FnOnce(&[T]) -> R>(iter: I, f: F) -> Self::Output {
// This code isn't hot.
f(&iter.cloned().collect::<SmallVec<[_; 8]>>())
}
}
@ -2809,10 +2835,14 @@ impl<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
) -> Self::Output {
// This code is hot enough that it's worth specializing for the most
// common length lists, to avoid the overhead of `SmallVec` creation.
// The match arms are in order of frequency. The 1, 2, and 0 cases are
// typically hit in ~95% of cases. We assume that if the upper and
// lower bounds from `size_hint` agree they are correct.
// Lengths 0, 1, and 2 typically account for ~95% of cases. We assume
// that if the upper and lower bounds from `size_hint` agree they are
// correct.
Ok(match iter.size_hint() {
(0, Some(0)) => {
assert!(iter.next().is_none());
f(&[])
}
(1, Some(1)) => {
let t0 = iter.next().unwrap()?;
assert!(iter.next().is_none());
@ -2824,10 +2854,6 @@ impl<T, R, E> InternIteratorElement<T, R> for Result<T, E> {
assert!(iter.next().is_none());
f(&[t0, t1])
}
(0, Some(0)) => {
assert!(iter.next().is_none());
f(&[])
}
_ => f(&iter.collect::<Result<SmallVec<[_; 8]>, _>>()?),
})
}

View File

@ -180,8 +180,8 @@ impl<'tcx, E: TyEncoder<'tcx>> Encodable<E> for GenericArg<'tcx> {
}
impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for GenericArg<'tcx> {
fn decode(d: &mut D) -> Result<GenericArg<'tcx>, D::Error> {
Ok(GenericArgKind::decode(d)?.pack())
fn decode(d: &mut D) -> GenericArg<'tcx> {
GenericArgKind::decode(d).pack()
}
}

View File

@ -163,15 +163,12 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
// Decode the *position* of the footer, which can be found in the
// last 8 bytes of the file.
decoder.set_position(data.len() - IntEncodedWithFixedSize::ENCODED_SIZE);
let footer_pos = IntEncodedWithFixedSize::decode(&mut decoder)
.expect("error while trying to decode footer position")
.0 as usize;
let footer_pos = IntEncodedWithFixedSize::decode(&mut decoder).0 as usize;
// Decode the file footer, which contains all the lookup tables, etc.
decoder.set_position(footer_pos);
decode_tagged(&mut decoder, TAG_FILE_FOOTER)
.expect("error while trying to decode footer position")
};
Self {
@ -372,7 +369,7 @@ impl<'sess> OnDiskCache<'sess> {
dep_node_index: SerializedDepNodeIndex,
) -> QuerySideEffects {
let side_effects: Option<QuerySideEffects> =
self.load_indexed(tcx, dep_node_index, &self.prev_side_effects_index, "side_effects");
self.load_indexed(tcx, dep_node_index, &self.prev_side_effects_index);
side_effects.unwrap_or_default()
}
@ -398,7 +395,7 @@ impl<'sess> OnDiskCache<'sess> {
where
T: for<'a> Decodable<CacheDecoder<'a, 'tcx>>,
{
self.load_indexed(tcx, dep_node_index, &self.query_result_index, "query result")
self.load_indexed(tcx, dep_node_index, &self.query_result_index)
}
/// Stores side effect emitted during computation of an anonymous query.
@ -423,17 +420,13 @@ impl<'sess> OnDiskCache<'sess> {
tcx: TyCtxt<'tcx>,
dep_node_index: SerializedDepNodeIndex,
index: &FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
debug_tag: &'static str,
) -> Option<T>
where
T: for<'a> Decodable<CacheDecoder<'a, 'tcx>>,
{
let pos = index.get(&dep_node_index).cloned()?;
self.with_decoder(tcx, pos, |decoder| match decode_tagged(decoder, dep_node_index) {
Ok(v) => Some(v),
Err(e) => bug!("could not decode cached {}: {}", debug_tag, e),
})
self.with_decoder(tcx, pos, |decoder| Some(decode_tagged(decoder, dep_node_index)))
}
fn with_decoder<'a, 'tcx, T, F: for<'s> FnOnce(&mut CacheDecoder<'s, 'tcx>) -> T>(
@ -535,7 +528,7 @@ impl<'a, 'tcx> DecoderWithPosition for CacheDecoder<'a, 'tcx> {
// Decodes something that was encoded with `encode_tagged()` and verify that the
// tag matches and the correct amount of bytes was read.
fn decode_tagged<D, T, V>(decoder: &mut D, expected_tag: T) -> Result<V, D::Error>
fn decode_tagged<D, T, V>(decoder: &mut D, expected_tag: T) -> V
where
T: Decodable<D> + Eq + std::fmt::Debug,
V: Decodable<D>,
@ -543,15 +536,15 @@ where
{
let start_pos = decoder.position();
let actual_tag = T::decode(decoder)?;
let actual_tag = T::decode(decoder);
assert_eq!(actual_tag, expected_tag);
let value = V::decode(decoder)?;
let value = V::decode(decoder);
let end_pos = decoder.position();
let expected_len: u64 = Decodable::decode(decoder)?;
let expected_len: u64 = Decodable::decode(decoder);
assert_eq!((end_pos - start_pos) as u64, expected_len);
Ok(value)
value
}
impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
@ -572,26 +565,22 @@ impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
self.opaque.data[self.opaque.position()]
}
fn cached_ty_for_shorthand<F>(
&mut self,
shorthand: usize,
or_insert_with: F,
) -> Result<Ty<'tcx>, Self::Error>
fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx>
where
F: FnOnce(&mut Self) -> Result<Ty<'tcx>, Self::Error>,
F: FnOnce(&mut Self) -> Ty<'tcx>,
{
let tcx = self.tcx();
let cache_key = ty::CReaderCacheKey { cnum: None, pos: shorthand };
if let Some(&ty) = tcx.ty_rcache.borrow().get(&cache_key) {
return Ok(ty);
return ty;
}
let ty = or_insert_with(self)?;
let ty = or_insert_with(self);
// This may overwrite the entry, but it should overwrite with the same value.
tcx.ty_rcache.borrow_mut().insert_same(cache_key, ty);
Ok(ty)
ty
}
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
@ -607,7 +596,7 @@ impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
r
}
fn decode_alloc_id(&mut self) -> Result<interpret::AllocId, Self::Error> {
fn decode_alloc_id(&mut self) -> interpret::AllocId {
let alloc_decoding_session = self.alloc_decoding_session;
alloc_decoding_session.decode_alloc_id(self)
}
@ -619,35 +608,35 @@ rustc_middle::implement_ty_decoder!(CacheDecoder<'a, 'tcx>);
// when a `CacheDecoder` is passed to `Decodable::decode`. Unfortunately, we have to manually opt
// into specializations this way, given how `CacheDecoder` and the decoding traits currently work.
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Vec<u8> {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
Decodable::decode(&mut d.opaque)
}
}
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for SyntaxContext {
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Self {
let syntax_contexts = decoder.syntax_contexts;
rustc_span::hygiene::decode_syntax_context(decoder, decoder.hygiene_context, |this, id| {
// This closure is invoked if we haven't already decoded the data for the `SyntaxContext` we are deserializing.
// We look up the position of the associated `SyntaxData` and decode it.
let pos = syntax_contexts.get(&id).unwrap();
this.with_position(pos.to_usize(), |decoder| {
let data: SyntaxContextData = decode_tagged(decoder, TAG_SYNTAX_CONTEXT)?;
Ok(data)
let data: SyntaxContextData = decode_tagged(decoder, TAG_SYNTAX_CONTEXT);
data
})
})
}
}
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
let hash = ExpnHash::decode(decoder)?;
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Self {
let hash = ExpnHash::decode(decoder);
if hash.is_root() {
return Ok(ExpnId::root());
return ExpnId::root();
}
if let Some(expn_id) = ExpnId::from_hash(hash) {
return Ok(expn_id);
return expn_id;
}
let krate = decoder.tcx.stable_crate_id_to_crate_num(hash.stable_crate_id());
@ -660,7 +649,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
.unwrap_or_else(|| panic!("Bad hash {:?} (map {:?})", hash, decoder.expn_data));
let data: ExpnData = decoder
.with_position(pos.to_usize(), |decoder| decode_tagged(decoder, TAG_EXPN_DATA))?;
.with_position(pos.to_usize(), |decoder| decode_tagged(decoder, TAG_EXPN_DATA));
let expn_id = rustc_span::hygiene::register_local_expn_id(data, hash);
#[cfg(debug_assertions)]
@ -687,21 +676,21 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
};
debug_assert_eq!(expn_id.krate, krate);
Ok(expn_id)
expn_id
}
}
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
let ctxt = SyntaxContext::decode(decoder)?;
let parent = Option::<LocalDefId>::decode(decoder)?;
let tag: u8 = Decodable::decode(decoder)?;
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Self {
let ctxt = SyntaxContext::decode(decoder);
let parent = Option::<LocalDefId>::decode(decoder);
let tag: u8 = Decodable::decode(decoder);
if tag == TAG_PARTIAL_SPAN {
return Ok(Span::new(BytePos(0), BytePos(0), ctxt, parent));
return Span::new(BytePos(0), BytePos(0), ctxt, parent);
} else if tag == TAG_RELATIVE_SPAN {
let dlo = u32::decode(decoder)?;
let dto = u32::decode(decoder)?;
let dlo = u32::decode(decoder);
let dto = u32::decode(decoder);
let enclosing =
decoder.tcx.definitions_untracked().def_span(parent.unwrap()).data_untracked();
@ -712,29 +701,29 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
parent,
);
return Ok(span);
return span;
} else {
debug_assert_eq!(tag, TAG_FULL_SPAN);
}
let file_lo_index = SourceFileIndex::decode(decoder)?;
let line_lo = usize::decode(decoder)?;
let col_lo = BytePos::decode(decoder)?;
let len = BytePos::decode(decoder)?;
let file_lo_index = SourceFileIndex::decode(decoder);
let line_lo = usize::decode(decoder);
let col_lo = BytePos::decode(decoder);
let len = BytePos::decode(decoder);
let file_lo = decoder.file_index_to_file(file_lo_index);
let lo = file_lo.lines[line_lo - 1] + col_lo;
let hi = lo + len;
Ok(Span::new(lo, hi, ctxt, parent))
Span::new(lo, hi, ctxt, parent)
}
}
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for CrateNum {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
let stable_id = StableCrateId::decode(d)?;
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
let stable_id = StableCrateId::decode(d);
let cnum = d.tcx.stable_crate_id_to_crate_num(stable_id);
Ok(cnum)
cnum
}
}
@ -743,8 +732,8 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for CrateNum {
// because we would not know how to transform the `DefIndex` to the current
// context.
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for DefIndex {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<DefIndex, String> {
Err(d.error("trying to decode `DefIndex` outside the context of a `DefId`"))
fn decode(_d: &mut CacheDecoder<'a, 'tcx>) -> DefIndex {
panic!("trying to decode `DefIndex` outside the context of a `DefId`")
}
}
@ -752,23 +741,23 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for DefIndex {
// compilation sessions. We use the `DefPathHash`, which is stable across
// sessions, to map the old `DefId` to the new one.
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for DefId {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
// Load the `DefPathHash` which is was we encoded the `DefId` as.
let def_path_hash = DefPathHash::decode(d)?;
let def_path_hash = DefPathHash::decode(d);
// Using the `DefPathHash`, we can lookup the new `DefId`.
// Subtle: We only encode a `DefId` as part of a query result.
// If we get to this point, then all of the query inputs were green,
// which means that the definition with this hash is guaranteed to
// still exist in the current compilation session.
Ok(d.tcx().def_path_hash_to_def_id(def_path_hash, &mut || {
d.tcx().def_path_hash_to_def_id(def_path_hash, &mut || {
panic!("Failed to convert DefPathHash {:?}", def_path_hash)
}))
})
}
}
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashSet<LocalDefId> {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
RefDecodable::decode(d)
}
}
@ -776,31 +765,31 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashSet<LocalDefId>
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
for &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>>
{
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
RefDecodable::decode(d)
}
}
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [thir::abstract_const::Node<'tcx>] {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
RefDecodable::decode(d)
}
}
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx>, Span)] {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
RefDecodable::decode(d)
}
}
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [rustc_ast::InlineAsmTemplatePiece] {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
RefDecodable::decode(d)
}
}
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [Span] {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Result<Self, String> {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
RefDecodable::decode(d)
}
}

View File

@ -100,7 +100,7 @@ impl<'a, K: DepKind + Decodable<opaque::Decoder<'a>>> Decodable<opaque::Decoder<
for SerializedDepGraph<K>
{
#[instrument(level = "debug", skip(d))]
fn decode(d: &mut opaque::Decoder<'a>) -> Result<SerializedDepGraph<K>, String> {
fn decode(d: &mut opaque::Decoder<'a>) -> SerializedDepGraph<K> {
let start_position = d.position();
// The last 16 bytes are the node count and edge count.
@ -108,8 +108,8 @@ impl<'a, K: DepKind + Decodable<opaque::Decoder<'a>>> Decodable<opaque::Decoder<
d.set_position(d.data.len() - 2 * IntEncodedWithFixedSize::ENCODED_SIZE);
debug!("position: {:?}", d.position());
let node_count = IntEncodedWithFixedSize::decode(d)?.0 as usize;
let edge_count = IntEncodedWithFixedSize::decode(d)?.0 as usize;
let node_count = IntEncodedWithFixedSize::decode(d).0 as usize;
let edge_count = IntEncodedWithFixedSize::decode(d).0 as usize;
debug!(?node_count, ?edge_count);
debug!("position: {:?}", d.position());
@ -123,12 +123,12 @@ impl<'a, K: DepKind + Decodable<opaque::Decoder<'a>>> Decodable<opaque::Decoder<
for _index in 0..node_count {
d.read_struct(|d| {
let dep_node: DepNode<K> = d.read_struct_field("node", Decodable::decode)?;
let dep_node: DepNode<K> = d.read_struct_field("node", Decodable::decode);
let _i: SerializedDepNodeIndex = nodes.push(dep_node);
debug_assert_eq!(_i.index(), _index);
let fingerprint: Fingerprint =
d.read_struct_field("fingerprint", Decodable::decode)?;
d.read_struct_field("fingerprint", Decodable::decode);
let _i: SerializedDepNodeIndex = fingerprints.push(fingerprint);
debug_assert_eq!(_i.index(), _index);
@ -136,22 +136,22 @@ impl<'a, K: DepKind + Decodable<opaque::Decoder<'a>>> Decodable<opaque::Decoder<
d.read_seq(|d, len| {
let start = edge_list_data.len().try_into().unwrap();
for _ in 0..len {
let edge = d.read_seq_elt(Decodable::decode)?;
let edge = d.read_seq_elt(Decodable::decode);
edge_list_data.push(edge);
}
let end = edge_list_data.len().try_into().unwrap();
let _i: SerializedDepNodeIndex = edge_list_indices.push((start, end));
debug_assert_eq!(_i.index(), _index);
Ok(())
()
})
})
})?;
});
}
let index: FxHashMap<_, _> =
nodes.iter_enumerated().map(|(idx, &dep_node)| (dep_node, idx)).collect();
Ok(SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data, index })
SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data, index }
}
}

View File

@ -17,15 +17,8 @@ impl<S: Encoder, A: Array<Item: Encodable<S>>> Encodable<S> for SmallVec<A> {
}
impl<D: Decoder, A: Array<Item: Decodable<D>>> Decodable<D> for SmallVec<A> {
fn decode(d: &mut D) -> Result<SmallVec<A>, D::Error> {
d.read_seq(|d, len| {
let mut vec = SmallVec::with_capacity(len);
// FIXME(#48994) - could just be collected into a Result<SmallVec, D::Error>
for _ in 0..len {
vec.push(d.read_seq_elt(|d| Decodable::decode(d))?);
}
Ok(vec)
})
fn decode(d: &mut D) -> SmallVec<A> {
d.read_seq(|d, len| (0..len).map(|_| d.read_seq_elt(|d| Decodable::decode(d))).collect())
}
}
@ -41,14 +34,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for LinkedList<T> {
}
impl<D: Decoder, T: Decodable<D>> Decodable<D> for LinkedList<T> {
fn decode(d: &mut D) -> Result<LinkedList<T>, D::Error> {
d.read_seq(|d, len| {
let mut list = LinkedList::new();
for _ in 0..len {
list.push_back(d.read_seq_elt(|d| Decodable::decode(d))?);
}
Ok(list)
})
fn decode(d: &mut D) -> LinkedList<T> {
d.read_seq(|d, len| (0..len).map(|_| d.read_seq_elt(|d| Decodable::decode(d))).collect())
}
}
@ -64,14 +51,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for VecDeque<T> {
}
impl<D: Decoder, T: Decodable<D>> Decodable<D> for VecDeque<T> {
fn decode(d: &mut D) -> Result<VecDeque<T>, D::Error> {
d.read_seq(|d, len| {
let mut deque: VecDeque<T> = VecDeque::with_capacity(len);
for _ in 0..len {
deque.push_back(d.read_seq_elt(|d| Decodable::decode(d))?);
}
Ok(deque)
})
fn decode(d: &mut D) -> VecDeque<T> {
d.read_seq(|d, len| (0..len).map(|_| d.read_seq_elt(|d| Decodable::decode(d))).collect())
}
}
@ -96,15 +77,15 @@ where
K: Decodable<D> + PartialEq + Ord,
V: Decodable<D>,
{
fn decode(d: &mut D) -> Result<BTreeMap<K, V>, D::Error> {
fn decode(d: &mut D) -> BTreeMap<K, V> {
d.read_map(|d, len| {
let mut map = BTreeMap::new();
for _ in 0..len {
let key = d.read_map_elt_key(|d| Decodable::decode(d))?;
let val = d.read_map_elt_val(|d| Decodable::decode(d))?;
let key = d.read_map_elt_key(|d| Decodable::decode(d));
let val = d.read_map_elt_val(|d| Decodable::decode(d));
map.insert(key, val);
}
Ok(map)
map
})
}
}
@ -127,13 +108,13 @@ impl<D: Decoder, T> Decodable<D> for BTreeSet<T>
where
T: Decodable<D> + PartialEq + Ord,
{
fn decode(d: &mut D) -> Result<BTreeSet<T>, D::Error> {
fn decode(d: &mut D) -> BTreeSet<T> {
d.read_seq(|d, len| {
let mut set = BTreeSet::new();
for _ in 0..len {
set.insert(d.read_seq_elt(|d| Decodable::decode(d))?);
set.insert(d.read_seq_elt(|d| Decodable::decode(d)));
}
Ok(set)
set
})
}
}
@ -161,16 +142,16 @@ where
V: Decodable<D>,
S: BuildHasher + Default,
{
fn decode(d: &mut D) -> Result<HashMap<K, V, S>, D::Error> {
fn decode(d: &mut D) -> HashMap<K, V, S> {
d.read_map(|d, len| {
let state = Default::default();
let mut map = HashMap::with_capacity_and_hasher(len, state);
for _ in 0..len {
let key = d.read_map_elt_key(|d| Decodable::decode(d))?;
let val = d.read_map_elt_val(|d| Decodable::decode(d))?;
let key = d.read_map_elt_key(|d| Decodable::decode(d));
let val = d.read_map_elt_val(|d| Decodable::decode(d));
map.insert(key, val);
}
Ok(map)
map
})
}
}
@ -205,14 +186,14 @@ where
T: Decodable<D> + Hash + Eq,
S: BuildHasher + Default,
{
fn decode(d: &mut D) -> Result<HashSet<T, S>, D::Error> {
fn decode(d: &mut D) -> HashSet<T, S> {
d.read_seq(|d, len| {
let state = Default::default();
let mut set = HashSet::with_capacity_and_hasher(len, state);
for _ in 0..len {
set.insert(d.read_seq_elt(|d| Decodable::decode(d))?);
set.insert(d.read_seq_elt(|d| Decodable::decode(d)));
}
Ok(set)
set
})
}
}
@ -240,16 +221,16 @@ where
V: Decodable<D>,
S: BuildHasher + Default,
{
fn decode(d: &mut D) -> Result<indexmap::IndexMap<K, V, S>, D::Error> {
fn decode(d: &mut D) -> indexmap::IndexMap<K, V, S> {
d.read_map(|d, len| {
let state = Default::default();
let mut map = indexmap::IndexMap::with_capacity_and_hasher(len, state);
for _ in 0..len {
let key = d.read_map_elt_key(|d| Decodable::decode(d))?;
let val = d.read_map_elt_val(|d| Decodable::decode(d))?;
let key = d.read_map_elt_key(|d| Decodable::decode(d));
let val = d.read_map_elt_val(|d| Decodable::decode(d));
map.insert(key, val);
}
Ok(map)
map
})
}
}
@ -274,14 +255,14 @@ where
T: Decodable<D> + Hash + Eq,
S: BuildHasher + Default,
{
fn decode(d: &mut D) -> Result<indexmap::IndexSet<T, S>, D::Error> {
fn decode(d: &mut D) -> indexmap::IndexSet<T, S> {
d.read_seq(|d, len| {
let state = Default::default();
let mut set = indexmap::IndexSet::with_capacity_and_hasher(len, state);
for _ in 0..len {
set.insert(d.read_seq_elt(|d| Decodable::decode(d))?);
set.insert(d.read_seq_elt(|d| Decodable::decode(d)));
}
Ok(set)
set
})
}
}
@ -294,9 +275,9 @@ impl<E: Encoder, T: Encodable<E>> Encodable<E> for Rc<[T]> {
}
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Rc<[T]> {
fn decode(d: &mut D) -> Result<Rc<[T]>, D::Error> {
let vec: Vec<T> = Decodable::decode(d)?;
Ok(vec.into())
fn decode(d: &mut D) -> Rc<[T]> {
let vec: Vec<T> = Decodable::decode(d);
vec.into()
}
}
@ -308,8 +289,8 @@ impl<E: Encoder, T: Encodable<E>> Encodable<E> for Arc<[T]> {
}
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Arc<[T]> {
fn decode(d: &mut D) -> Result<Arc<[T]>, D::Error> {
let vec: Vec<T> = Decodable::decode(d)?;
Ok(vec.into())
fn decode(d: &mut D) -> Arc<[T]> {
let vec: Vec<T> = Decodable::decode(d);
vec.into()
}
}

View File

@ -89,7 +89,7 @@
//! let encoded = json::encode(&object).unwrap();
//!
//! // Deserialize using `json::decode`
//! let decoded: TestStruct = json::decode(&encoded[..]).unwrap();
//! let decoded: TestStruct = json::decode(&encoded[..]);
//! ```
//!
//! ## Using the `ToJson` trait
@ -173,7 +173,7 @@
//! let json_str: String = json_obj.to_string();
//!
//! // Deserialize like before
//! let decoded: TestStruct = json::decode(&json_str).unwrap();
//! let decoded: TestStruct = json::decode(&json_str);
//! ```
use self::DecoderError::*;
@ -265,6 +265,12 @@ pub enum DecoderError {
ApplicationError(string::String),
}
macro_rules! bad {
($e:expr) => {{
panic!("json decode error: {:?}", $e);
}};
}
#[derive(Copy, Clone, Debug)]
pub enum EncoderError {
FmtError(fmt::Error),
@ -295,10 +301,10 @@ pub fn error_str(error: ErrorCode) -> &'static str {
}
/// Shortcut function to decode a JSON `&str` into an object
pub fn decode<T: crate::Decodable<Decoder>>(s: &str) -> DecodeResult<T> {
pub fn decode<T: crate::Decodable<Decoder>>(s: &str) -> T {
let json = match from_str(s) {
Ok(x) => x,
Err(e) => return Err(ParseError(e)),
Err(e) => bad!(ParseError(e)),
};
let mut decoder = Decoder::new(json);
@ -334,15 +340,6 @@ impl fmt::Display for ParserError {
}
}
impl fmt::Display for DecoderError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// FIXME this should be a nicer error
fmt::Debug::fmt(self, f)
}
}
impl std::error::Error for DecoderError {}
impl fmt::Display for EncoderError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// FIXME this should be a nicer error
@ -2206,41 +2203,39 @@ impl Decoder {
macro_rules! expect {
($e:expr, Null) => {{
match $e {
Json::Null => Ok(()),
other => Err(ExpectedError("Null".to_owned(), other.to_string())),
Json::Null => (),
other => bad!(ExpectedError("Null".to_owned(), other.to_string())),
}
}};
($e:expr, $t:ident) => {{
match $e {
Json::$t(v) => Ok(v),
other => Err(ExpectedError(stringify!($t).to_owned(), other.to_string())),
Json::$t(v) => v,
other => bad!(ExpectedError(stringify!($t).to_owned(), other.to_string())),
}
}};
}
macro_rules! read_primitive {
($name:ident, $ty:ty) => {
fn $name(&mut self) -> DecodeResult<$ty> {
fn $name(&mut self) -> $ty {
match self.pop() {
Json::I64(f) => Ok(f as $ty),
Json::U64(f) => Ok(f as $ty),
Json::F64(f) => Err(ExpectedError("Integer".to_owned(), f.to_string())),
Json::I64(f) => f as $ty,
Json::U64(f) => f as $ty,
Json::F64(f) => bad!(ExpectedError("Integer".to_owned(), f.to_string())),
// re: #12967.. a type w/ numeric keys (ie HashMap<usize, V> etc)
// is going to have a string here, as per JSON spec.
Json::String(s) => match s.parse().ok() {
Some(f) => Ok(f),
None => Err(ExpectedError("Number".to_owned(), s)),
Some(f) => f,
None => bad!(ExpectedError("Number".to_owned(), s)),
},
value => Err(ExpectedError("Number".to_owned(), value.to_string())),
value => bad!(ExpectedError("Number".to_owned(), value.to_string())),
}
}
};
}
impl crate::Decoder for Decoder {
type Error = DecoderError;
fn read_unit(&mut self) -> DecodeResult<()> {
fn read_unit(&mut self) -> () {
expect!(self.pop(), Null)
}
@ -2257,156 +2252,151 @@ impl crate::Decoder for Decoder {
read_primitive! { read_i64, i64 }
read_primitive! { read_i128, i128 }
fn read_f32(&mut self) -> DecodeResult<f32> {
self.read_f64().map(|x| x as f32)
fn read_f32(&mut self) -> f32 {
self.read_f64() as f32
}
fn read_f64(&mut self) -> DecodeResult<f64> {
fn read_f64(&mut self) -> f64 {
match self.pop() {
Json::I64(f) => Ok(f as f64),
Json::U64(f) => Ok(f as f64),
Json::F64(f) => Ok(f),
Json::I64(f) => f as f64,
Json::U64(f) => f as f64,
Json::F64(f) => f,
Json::String(s) => {
// re: #12967.. a type w/ numeric keys (ie HashMap<usize, V> etc)
// is going to have a string here, as per JSON spec.
match s.parse().ok() {
Some(f) => Ok(f),
None => Err(ExpectedError("Number".to_owned(), s)),
Some(f) => f,
None => bad!(ExpectedError("Number".to_owned(), s)),
}
}
Json::Null => Ok(f64::NAN),
value => Err(ExpectedError("Number".to_owned(), value.to_string())),
Json::Null => f64::NAN,
value => bad!(ExpectedError("Number".to_owned(), value.to_string())),
}
}
fn read_bool(&mut self) -> DecodeResult<bool> {
fn read_bool(&mut self) -> bool {
expect!(self.pop(), Boolean)
}
fn read_char(&mut self) -> DecodeResult<char> {
let s = self.read_str()?;
{
fn read_char(&mut self) -> char {
let s = self.read_str();
let mut it = s.chars();
if let (Some(c), None) = (it.next(), it.next()) {
// exactly one character
return Ok(c);
return c;
}
}
Err(ExpectedError("single character string".to_owned(), s.to_string()))
bad!(ExpectedError("single character string".to_owned(), s.to_string()));
}
fn read_str(&mut self) -> DecodeResult<Cow<'_, str>> {
expect!(self.pop(), String).map(Cow::Owned)
fn read_str(&mut self) -> Cow<'_, str> {
Cow::Owned(expect!(self.pop(), String))
}
fn read_raw_bytes_into(&mut self, s: &mut [u8]) -> Result<(), Self::Error> {
fn read_raw_bytes_into(&mut self, s: &mut [u8]) {
for c in s.iter_mut() {
*c = self.read_u8()?;
*c = self.read_u8();
}
Ok(())
()
}
fn read_enum<T, F>(&mut self, f: F) -> DecodeResult<T>
fn read_enum<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
F: FnOnce(&mut Decoder) -> T,
{
f(self)
}
fn read_enum_variant<T, F>(&mut self, names: &[&str], mut f: F) -> DecodeResult<T>
fn read_enum_variant<T, F>(&mut self, names: &[&str], mut f: F) -> T
where
F: FnMut(&mut Decoder, usize) -> DecodeResult<T>,
F: FnMut(&mut Decoder, usize) -> T,
{
let name = match self.pop() {
Json::String(s) => s,
Json::Object(mut o) => {
let n = match o.remove("variant") {
Some(Json::String(s)) => s,
Some(val) => return Err(ExpectedError("String".to_owned(), val.to_string())),
None => return Err(MissingFieldError("variant".to_owned())),
Some(val) => bad!(ExpectedError("String".to_owned(), val.to_string())),
None => bad!(MissingFieldError("variant".to_owned())),
};
match o.remove("fields") {
Some(Json::Array(l)) => {
self.stack.extend(l.into_iter().rev());
}
Some(val) => return Err(ExpectedError("Array".to_owned(), val.to_string())),
None => return Err(MissingFieldError("fields".to_owned())),
Some(val) => bad!(ExpectedError("Array".to_owned(), val.to_string())),
None => bad!(MissingFieldError("fields".to_owned())),
}
n
}
json => return Err(ExpectedError("String or Object".to_owned(), json.to_string())),
json => bad!(ExpectedError("String or Object".to_owned(), json.to_string())),
};
let idx = match names.iter().position(|n| *n == &name[..]) {
Some(idx) => idx,
None => return Err(UnknownVariantError(name)),
None => bad!(UnknownVariantError(name)),
};
f(self, idx)
}
fn read_enum_variant_arg<T, F>(&mut self, f: F) -> DecodeResult<T>
fn read_enum_variant_arg<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
F: FnOnce(&mut Decoder) -> T,
{
f(self)
}
fn read_struct<T, F>(&mut self, f: F) -> DecodeResult<T>
fn read_struct<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
F: FnOnce(&mut Decoder) -> T,
{
let value = f(self)?;
let value = f(self);
self.pop();
Ok(value)
value
}
fn read_struct_field<T, F>(&mut self, name: &str, f: F) -> DecodeResult<T>
fn read_struct_field<T, F>(&mut self, name: &str, f: F) -> T
where
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
F: FnOnce(&mut Decoder) -> T,
{
let mut obj = expect!(self.pop(), Object)?;
let mut obj = expect!(self.pop(), Object);
let value = match obj.remove(name) {
None => {
// Add a Null and try to parse it as an Option<_>
// to get None as a default value.
self.stack.push(Json::Null);
match f(self) {
Ok(x) => x,
Err(_) => return Err(MissingFieldError(name.to_string())),
}
f(self)
}
Some(json) => {
self.stack.push(json);
f(self)?
f(self)
}
};
self.stack.push(Json::Object(obj));
Ok(value)
value
}
fn read_tuple<T, F>(&mut self, tuple_len: usize, f: F) -> DecodeResult<T>
fn read_tuple<T, F>(&mut self, tuple_len: usize, f: F) -> T
where
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
F: FnOnce(&mut Decoder) -> T,
{
self.read_seq(move |d, len| {
if len == tuple_len {
f(d)
} else {
Err(ExpectedError(format!("Tuple{}", tuple_len), format!("Tuple{}", len)))
bad!(ExpectedError(format!("Tuple{}", tuple_len), format!("Tuple{}", len)));
}
})
}
fn read_tuple_arg<T, F>(&mut self, f: F) -> DecodeResult<T>
fn read_tuple_arg<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
F: FnOnce(&mut Decoder) -> T,
{
self.read_seq_elt(f)
}
fn read_option<T, F>(&mut self, mut f: F) -> DecodeResult<T>
fn read_option<T, F>(&mut self, mut f: F) -> T
where
F: FnMut(&mut Decoder, bool) -> DecodeResult<T>,
F: FnMut(&mut Decoder, bool) -> T,
{
match self.pop() {
Json::Null => f(self, false),
@ -2417,28 +2407,28 @@ impl crate::Decoder for Decoder {
}
}
fn read_seq<T, F>(&mut self, f: F) -> DecodeResult<T>
fn read_seq<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Decoder, usize) -> DecodeResult<T>,
F: FnOnce(&mut Decoder, usize) -> T,
{
let array = expect!(self.pop(), Array)?;
let array = expect!(self.pop(), Array);
let len = array.len();
self.stack.extend(array.into_iter().rev());
f(self, len)
}
fn read_seq_elt<T, F>(&mut self, f: F) -> DecodeResult<T>
fn read_seq_elt<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
F: FnOnce(&mut Decoder) -> T,
{
f(self)
}
fn read_map<T, F>(&mut self, f: F) -> DecodeResult<T>
fn read_map<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Decoder, usize) -> DecodeResult<T>,
F: FnOnce(&mut Decoder, usize) -> T,
{
let obj = expect!(self.pop(), Object)?;
let obj = expect!(self.pop(), Object);
let len = obj.len();
for (key, value) in obj {
self.stack.push(value);
@ -2447,23 +2437,19 @@ impl crate::Decoder for Decoder {
f(self, len)
}
fn read_map_elt_key<T, F>(&mut self, f: F) -> DecodeResult<T>
fn read_map_elt_key<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
F: FnOnce(&mut Decoder) -> T,
{
f(self)
}
fn read_map_elt_val<T, F>(&mut self, f: F) -> DecodeResult<T>
fn read_map_elt_val<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Decoder) -> DecodeResult<T>,
F: FnOnce(&mut Decoder) -> T,
{
f(self)
}
fn error(&mut self, err: &str) -> DecoderError {
ApplicationError(err.to_string())
}
}
/// A trait for converting values to JSON

View File

@ -560,134 +560,127 @@ impl<'a> Decoder<'a> {
}
macro_rules! read_leb128 {
($dec:expr, $fun:ident) => {{ Ok(leb128::$fun($dec.data, &mut $dec.position)) }};
($dec:expr, $fun:ident) => {{ leb128::$fun($dec.data, &mut $dec.position) }};
}
impl<'a> serialize::Decoder for Decoder<'a> {
type Error = String;
#[inline]
fn read_unit(&mut self) -> Result<(), Self::Error> {
Ok(())
fn read_unit(&mut self) -> () {
()
}
#[inline]
fn read_u128(&mut self) -> Result<u128, Self::Error> {
fn read_u128(&mut self) -> u128 {
read_leb128!(self, read_u128_leb128)
}
#[inline]
fn read_u64(&mut self) -> Result<u64, Self::Error> {
fn read_u64(&mut self) -> u64 {
read_leb128!(self, read_u64_leb128)
}
#[inline]
fn read_u32(&mut self) -> Result<u32, Self::Error> {
fn read_u32(&mut self) -> u32 {
read_leb128!(self, read_u32_leb128)
}
#[inline]
fn read_u16(&mut self) -> Result<u16, Self::Error> {
fn read_u16(&mut self) -> u16 {
let bytes = [self.data[self.position], self.data[self.position + 1]];
let value = u16::from_le_bytes(bytes);
self.position += 2;
Ok(value)
value
}
#[inline]
fn read_u8(&mut self) -> Result<u8, Self::Error> {
fn read_u8(&mut self) -> u8 {
let value = self.data[self.position];
self.position += 1;
Ok(value)
value
}
#[inline]
fn read_usize(&mut self) -> Result<usize, Self::Error> {
fn read_usize(&mut self) -> usize {
read_leb128!(self, read_usize_leb128)
}
#[inline]
fn read_i128(&mut self) -> Result<i128, Self::Error> {
fn read_i128(&mut self) -> i128 {
read_leb128!(self, read_i128_leb128)
}
#[inline]
fn read_i64(&mut self) -> Result<i64, Self::Error> {
fn read_i64(&mut self) -> i64 {
read_leb128!(self, read_i64_leb128)
}
#[inline]
fn read_i32(&mut self) -> Result<i32, Self::Error> {
fn read_i32(&mut self) -> i32 {
read_leb128!(self, read_i32_leb128)
}
#[inline]
fn read_i16(&mut self) -> Result<i16, Self::Error> {
fn read_i16(&mut self) -> i16 {
let bytes = [self.data[self.position], self.data[self.position + 1]];
let value = i16::from_le_bytes(bytes);
self.position += 2;
Ok(value)
value
}
#[inline]
fn read_i8(&mut self) -> Result<i8, Self::Error> {
fn read_i8(&mut self) -> i8 {
let as_u8 = self.data[self.position];
self.position += 1;
unsafe { Ok(::std::mem::transmute(as_u8)) }
unsafe { ::std::mem::transmute(as_u8) }
}
#[inline]
fn read_isize(&mut self) -> Result<isize, Self::Error> {
fn read_isize(&mut self) -> isize {
read_leb128!(self, read_isize_leb128)
}
#[inline]
fn read_bool(&mut self) -> Result<bool, Self::Error> {
let value = self.read_u8()?;
Ok(value != 0)
fn read_bool(&mut self) -> bool {
let value = self.read_u8();
value != 0
}
#[inline]
fn read_f64(&mut self) -> Result<f64, Self::Error> {
let bits = self.read_u64()?;
Ok(f64::from_bits(bits))
fn read_f64(&mut self) -> f64 {
let bits = self.read_u64();
f64::from_bits(bits)
}
#[inline]
fn read_f32(&mut self) -> Result<f32, Self::Error> {
let bits = self.read_u32()?;
Ok(f32::from_bits(bits))
fn read_f32(&mut self) -> f32 {
let bits = self.read_u32();
f32::from_bits(bits)
}
#[inline]
fn read_char(&mut self) -> Result<char, Self::Error> {
let bits = self.read_u32()?;
Ok(std::char::from_u32(bits).unwrap())
fn read_char(&mut self) -> char {
let bits = self.read_u32();
std::char::from_u32(bits).unwrap()
}
#[inline]
fn read_str(&mut self) -> Result<Cow<'_, str>, Self::Error> {
let len = self.read_usize()?;
fn read_str(&mut self) -> Cow<'_, str> {
let len = self.read_usize();
let sentinel = self.data[self.position + len];
assert!(sentinel == STR_SENTINEL);
let s = unsafe {
std::str::from_utf8_unchecked(&self.data[self.position..self.position + len])
};
self.position += len + 1;
Ok(Cow::Borrowed(s))
Cow::Borrowed(s)
}
#[inline]
fn error(&mut self, err: &str) -> Self::Error {
err.to_string()
}
#[inline]
fn read_raw_bytes_into(&mut self, s: &mut [u8]) -> Result<(), String> {
fn read_raw_bytes_into(&mut self, s: &mut [u8]) -> () {
let start = self.position;
self.position += s.len();
s.copy_from_slice(&self.data[start..self.position]);
Ok(())
()
}
}
@ -715,9 +708,9 @@ impl serialize::Encodable<FileEncoder> for [u8] {
// Specialize decoding `Vec<u8>`. This specialization also applies to decoding `Box<[u8]>`s, etc.,
// since the default implementations call `decode` to produce a `Vec<u8>` internally.
impl<'a> serialize::Decodable<Decoder<'a>> for Vec<u8> {
fn decode(d: &mut Decoder<'a>) -> Result<Self, String> {
let len = serialize::Decoder::read_usize(d)?;
Ok(d.read_raw_bytes(len).to_owned())
fn decode(d: &mut Decoder<'a>) -> Self {
let len = serialize::Decoder::read_usize(d);
d.read_raw_bytes(len).to_owned()
}
}
@ -752,13 +745,13 @@ impl serialize::Encodable<FileEncoder> for IntEncodedWithFixedSize {
impl<'a> serialize::Decodable<Decoder<'a>> for IntEncodedWithFixedSize {
#[inline]
fn decode(decoder: &mut Decoder<'a>) -> Result<IntEncodedWithFixedSize, String> {
fn decode(decoder: &mut Decoder<'a>) -> IntEncodedWithFixedSize {
let _start_pos = decoder.position();
let bytes = decoder.read_raw_bytes(IntEncodedWithFixedSize::ENCODED_SIZE);
let _end_pos = decoder.position();
debug_assert_eq!((_end_pos - _start_pos), IntEncodedWithFixedSize::ENCODED_SIZE);
let value = u64::from_le_bytes(bytes.try_into().unwrap());
Ok(IntEncodedWithFixedSize(value))
IntEncodedWithFixedSize(value)
}
}

View File

@ -173,144 +173,145 @@ pub trait Encoder {
}
}
// Note: all the methods in this trait are infallible, which may be surprising.
// They used to be fallible (i.e. return a `Result`) but many of the impls just
// panicked when something went wrong, and for the cases that didn't the
// top-level invocation would also just panic on failure. Switching to
// infallibility made things faster and lots of code a little simpler and more
// concise.
pub trait Decoder {
type Error;
// Primitive types:
fn read_unit(&mut self) -> Result<(), Self::Error>;
fn read_usize(&mut self) -> Result<usize, Self::Error>;
fn read_u128(&mut self) -> Result<u128, Self::Error>;
fn read_u64(&mut self) -> Result<u64, Self::Error>;
fn read_u32(&mut self) -> Result<u32, Self::Error>;
fn read_u16(&mut self) -> Result<u16, Self::Error>;
fn read_u8(&mut self) -> Result<u8, Self::Error>;
fn read_isize(&mut self) -> Result<isize, Self::Error>;
fn read_i128(&mut self) -> Result<i128, Self::Error>;
fn read_i64(&mut self) -> Result<i64, Self::Error>;
fn read_i32(&mut self) -> Result<i32, Self::Error>;
fn read_i16(&mut self) -> Result<i16, Self::Error>;
fn read_i8(&mut self) -> Result<i8, Self::Error>;
fn read_bool(&mut self) -> Result<bool, Self::Error>;
fn read_f64(&mut self) -> Result<f64, Self::Error>;
fn read_f32(&mut self) -> Result<f32, Self::Error>;
fn read_char(&mut self) -> Result<char, Self::Error>;
fn read_str(&mut self) -> Result<Cow<'_, str>, Self::Error>;
fn read_raw_bytes_into(&mut self, s: &mut [u8]) -> Result<(), Self::Error>;
fn read_unit(&mut self) -> ();
fn read_usize(&mut self) -> usize;
fn read_u128(&mut self) -> u128;
fn read_u64(&mut self) -> u64;
fn read_u32(&mut self) -> u32;
fn read_u16(&mut self) -> u16;
fn read_u8(&mut self) -> u8;
fn read_isize(&mut self) -> isize;
fn read_i128(&mut self) -> i128;
fn read_i64(&mut self) -> i64;
fn read_i32(&mut self) -> i32;
fn read_i16(&mut self) -> i16;
fn read_i8(&mut self) -> i8;
fn read_bool(&mut self) -> bool;
fn read_f64(&mut self) -> f64;
fn read_f32(&mut self) -> f32;
fn read_char(&mut self) -> char;
fn read_str(&mut self) -> Cow<'_, str>;
fn read_raw_bytes_into(&mut self, s: &mut [u8]);
// Compound types:
#[inline]
fn read_enum<T, F>(&mut self, f: F) -> Result<T, Self::Error>
fn read_enum<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
F: FnOnce(&mut Self) -> T,
{
f(self)
}
#[inline]
fn read_enum_variant<T, F>(&mut self, _names: &[&str], mut f: F) -> Result<T, Self::Error>
fn read_enum_variant<T, F>(&mut self, _names: &[&str], mut f: F) -> T
where
F: FnMut(&mut Self, usize) -> Result<T, Self::Error>,
F: FnMut(&mut Self, usize) -> T,
{
let disr = self.read_usize()?;
let disr = self.read_usize();
f(self, disr)
}
#[inline]
fn read_enum_variant_arg<T, F>(&mut self, f: F) -> Result<T, Self::Error>
fn read_enum_variant_arg<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
F: FnOnce(&mut Self) -> T,
{
f(self)
}
#[inline]
fn read_struct<T, F>(&mut self, f: F) -> Result<T, Self::Error>
fn read_struct<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
F: FnOnce(&mut Self) -> T,
{
f(self)
}
#[inline]
fn read_struct_field<T, F>(&mut self, _f_name: &str, f: F) -> Result<T, Self::Error>
fn read_struct_field<T, F>(&mut self, _f_name: &str, f: F) -> T
where
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
F: FnOnce(&mut Self) -> T,
{
f(self)
}
#[inline]
fn read_tuple<T, F>(&mut self, _len: usize, f: F) -> Result<T, Self::Error>
fn read_tuple<T, F>(&mut self, _len: usize, f: F) -> T
where
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
F: FnOnce(&mut Self) -> T,
{
f(self)
}
#[inline]
fn read_tuple_arg<T, F>(&mut self, f: F) -> Result<T, Self::Error>
fn read_tuple_arg<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
F: FnOnce(&mut Self) -> T,
{
f(self)
}
// Specialized types:
fn read_option<T, F>(&mut self, mut f: F) -> Result<T, Self::Error>
fn read_option<T, F>(&mut self, mut f: F) -> T
where
F: FnMut(&mut Self, bool) -> Result<T, Self::Error>,
F: FnMut(&mut Self, bool) -> T,
{
self.read_enum(move |this| {
this.read_enum_variant(&["None", "Some"], move |this, idx| match idx {
0 => f(this, false),
1 => f(this, true),
_ => Err(this.error("read_option: expected 0 for None or 1 for Some")),
_ => panic!("read_option: expected 0 for None or 1 for Some"),
})
})
}
fn read_seq<T, F>(&mut self, f: F) -> Result<T, Self::Error>
fn read_seq<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Self, usize) -> Result<T, Self::Error>,
F: FnOnce(&mut Self, usize) -> T,
{
let len = self.read_usize()?;
let len = self.read_usize();
f(self, len)
}
#[inline]
fn read_seq_elt<T, F>(&mut self, f: F) -> Result<T, Self::Error>
fn read_seq_elt<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
F: FnOnce(&mut Self) -> T,
{
f(self)
}
fn read_map<T, F>(&mut self, f: F) -> Result<T, Self::Error>
fn read_map<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Self, usize) -> Result<T, Self::Error>,
F: FnOnce(&mut Self, usize) -> T,
{
let len = self.read_usize()?;
let len = self.read_usize();
f(self, len)
}
#[inline]
fn read_map_elt_key<T, F>(&mut self, f: F) -> Result<T, Self::Error>
fn read_map_elt_key<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
F: FnOnce(&mut Self) -> T,
{
f(self)
}
#[inline]
fn read_map_elt_val<T, F>(&mut self, f: F) -> Result<T, Self::Error>
fn read_map_elt_val<T, F>(&mut self, f: F) -> T
where
F: FnOnce(&mut Self) -> Result<T, Self::Error>,
F: FnOnce(&mut Self) -> T,
{
f(self)
}
// Failure
fn error(&mut self, err: &str) -> Self::Error;
}
/// Trait for types that can be serialized
@ -340,7 +341,7 @@ pub trait Encodable<S: Encoder> {
/// * `TyDecodable` should be used for types that are only serialized in crate
/// metadata or the incremental cache. This is most types in `rustc_middle`.
pub trait Decodable<D: Decoder>: Sized {
fn decode(d: &mut D) -> Result<Self, D::Error>;
fn decode(d: &mut D) -> Self;
}
macro_rules! direct_serialize_impls {
@ -353,7 +354,7 @@ macro_rules! direct_serialize_impls {
}
impl<D: Decoder> Decodable<D> for $ty {
fn decode(d: &mut D) -> Result<$ty, D::Error> {
fn decode(d: &mut D) -> $ty {
d.$read_method()
}
}
@ -387,7 +388,7 @@ impl<S: Encoder> Encodable<S> for ! {
}
impl<D: Decoder> Decodable<D> for ! {
fn decode(_d: &mut D) -> Result<!, D::Error> {
fn decode(_d: &mut D) -> ! {
unreachable!()
}
}
@ -399,8 +400,8 @@ impl<S: Encoder> Encodable<S> for ::std::num::NonZeroU32 {
}
impl<D: Decoder> Decodable<D> for ::std::num::NonZeroU32 {
fn decode(d: &mut D) -> Result<Self, D::Error> {
d.read_u32().map(|d| ::std::num::NonZeroU32::new(d).unwrap())
fn decode(d: &mut D) -> Self {
::std::num::NonZeroU32::new(d.read_u32()).unwrap()
}
}
@ -423,8 +424,8 @@ impl<S: Encoder> Encodable<S> for String {
}
impl<D: Decoder> Decodable<D> for String {
fn decode(d: &mut D) -> Result<String, D::Error> {
Ok(d.read_str()?.into_owned())
fn decode(d: &mut D) -> String {
d.read_str().into_owned()
}
}
@ -435,7 +436,7 @@ impl<S: Encoder> Encodable<S> for () {
}
impl<D: Decoder> Decodable<D> for () {
fn decode(d: &mut D) -> Result<(), D::Error> {
fn decode(d: &mut D) -> () {
d.read_unit()
}
}
@ -447,16 +448,16 @@ impl<S: Encoder, T> Encodable<S> for PhantomData<T> {
}
impl<D: Decoder, T> Decodable<D> for PhantomData<T> {
fn decode(d: &mut D) -> Result<PhantomData<T>, D::Error> {
d.read_unit()?;
Ok(PhantomData)
fn decode(d: &mut D) -> PhantomData<T> {
d.read_unit();
PhantomData
}
}
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Box<[T]> {
fn decode(d: &mut D) -> Result<Box<[T]>, D::Error> {
let v: Vec<T> = Decodable::decode(d)?;
Ok(v.into_boxed_slice())
fn decode(d: &mut D) -> Box<[T]> {
let v: Vec<T> = Decodable::decode(d);
v.into_boxed_slice()
}
}
@ -467,8 +468,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Rc<T> {
}
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Rc<T> {
fn decode(d: &mut D) -> Result<Rc<T>, D::Error> {
Ok(Rc::new(Decodable::decode(d)?))
fn decode(d: &mut D) -> Rc<T> {
Rc::new(Decodable::decode(d))
}
}
@ -491,13 +492,22 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Vec<T> {
}
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Vec<T> {
default fn decode(d: &mut D) -> Result<Vec<T>, D::Error> {
default fn decode(d: &mut D) -> Vec<T> {
d.read_seq(|d, len| {
let mut v = Vec::with_capacity(len);
for _ in 0..len {
v.push(d.read_seq_elt(|d| Decodable::decode(d))?);
// SAFETY: we set the capacity in advance, only write elements, and
// only set the length at the end once the writing has succeeded.
let mut vec = Vec::with_capacity(len);
unsafe {
let ptr: *mut T = vec.as_mut_ptr();
for i in 0..len {
std::ptr::write(
ptr.offset(i as isize),
d.read_seq_elt(|d| Decodable::decode(d)),
);
}
Ok(v)
vec.set_len(len);
}
vec
})
}
}
@ -510,14 +520,14 @@ impl<S: Encoder, T: Encodable<S>, const N: usize> Encodable<S> for [T; N] {
}
impl<D: Decoder, const N: usize> Decodable<D> for [u8; N] {
fn decode(d: &mut D) -> Result<[u8; N], D::Error> {
fn decode(d: &mut D) -> [u8; N] {
d.read_seq(|d, len| {
assert!(len == N);
let mut v = [0u8; N];
for i in 0..len {
v[i] = d.read_seq_elt(|d| Decodable::decode(d))?;
v[i] = d.read_seq_elt(|d| Decodable::decode(d));
}
Ok(v)
v
})
}
}
@ -536,9 +546,9 @@ impl<D: Decoder, T: Decodable<D> + ToOwned> Decodable<D> for Cow<'static, [T]>
where
[T]: ToOwned<Owned = Vec<T>>,
{
fn decode(d: &mut D) -> Result<Cow<'static, [T]>, D::Error> {
let v: Vec<T> = Decodable::decode(d)?;
Ok(Cow::Owned(v))
fn decode(d: &mut D) -> Cow<'static, [T]> {
let v: Vec<T> = Decodable::decode(d);
Cow::Owned(v)
}
}
@ -552,8 +562,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Option<T> {
}
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Option<T> {
fn decode(d: &mut D) -> Result<Option<T>, D::Error> {
d.read_option(|d, b| if b { Ok(Some(Decodable::decode(d)?)) } else { Ok(None) })
fn decode(d: &mut D) -> Option<T> {
d.read_option(|d, b| if b { Some(Decodable::decode(d)) } else { None })
}
}
@ -571,17 +581,12 @@ impl<S: Encoder, T1: Encodable<S>, T2: Encodable<S>> Encodable<S> for Result<T1,
}
impl<D: Decoder, T1: Decodable<D>, T2: Decodable<D>> Decodable<D> for Result<T1, T2> {
fn decode(d: &mut D) -> Result<Result<T1, T2>, D::Error> {
fn decode(d: &mut D) -> Result<T1, T2> {
d.read_enum(|d| {
d.read_enum_variant(&["Ok", "Err"], |d, disr| match disr {
0 => Ok(Ok(d.read_enum_variant_arg(|d| T1::decode(d))?)),
1 => Ok(Err(d.read_enum_variant_arg(|d| T2::decode(d))?)),
_ => {
panic!(
"Encountered invalid discriminant while \
decoding `Result`."
);
}
0 => Ok(d.read_enum_variant_arg(|d| T1::decode(d))),
1 => Err(d.read_enum_variant_arg(|d| T2::decode(d))),
_ => panic!("Encountered invalid discriminant while decoding `Result`."),
})
})
}
@ -609,13 +614,13 @@ macro_rules! tuple {
( $($name:ident,)+ ) => (
impl<D: Decoder, $($name: Decodable<D>),+> Decodable<D> for ($($name,)+) {
#[allow(non_snake_case)]
fn decode(d: &mut D) -> Result<($($name,)+), D::Error> {
fn decode(d: &mut D) -> ($($name,)+) {
let len: usize = count!($($name)+);
d.read_tuple(len, |d| {
let ret = ($(d.read_tuple_arg(|d| -> Result<$name, D::Error> {
let ret = ($(d.read_tuple_arg(|d| -> $name {
Decodable::decode(d)
})?,)+);
Ok(ret)
}),)+);
ret
})
}
}
@ -651,9 +656,9 @@ impl<S: Encoder> Encodable<S> for path::PathBuf {
}
impl<D: Decoder> Decodable<D> for path::PathBuf {
fn decode(d: &mut D) -> Result<path::PathBuf, D::Error> {
let bytes: String = Decodable::decode(d)?;
Ok(path::PathBuf::from(bytes))
fn decode(d: &mut D) -> path::PathBuf {
let bytes: String = Decodable::decode(d);
path::PathBuf::from(bytes)
}
}
@ -664,8 +669,8 @@ impl<S: Encoder, T: Encodable<S> + Copy> Encodable<S> for Cell<T> {
}
impl<D: Decoder, T: Decodable<D> + Copy> Decodable<D> for Cell<T> {
fn decode(d: &mut D) -> Result<Cell<T>, D::Error> {
Ok(Cell::new(Decodable::decode(d)?))
fn decode(d: &mut D) -> Cell<T> {
Cell::new(Decodable::decode(d))
}
}
@ -681,8 +686,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for RefCell<T> {
}
impl<D: Decoder, T: Decodable<D>> Decodable<D> for RefCell<T> {
fn decode(d: &mut D) -> Result<RefCell<T>, D::Error> {
Ok(RefCell::new(Decodable::decode(d)?))
fn decode(d: &mut D) -> RefCell<T> {
RefCell::new(Decodable::decode(d))
}
}
@ -693,8 +698,8 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for Arc<T> {
}
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Arc<T> {
fn decode(d: &mut D) -> Result<Arc<T>, D::Error> {
Ok(Arc::new(Decodable::decode(d)?))
fn decode(d: &mut D) -> Arc<T> {
Arc::new(Decodable::decode(d))
}
}
@ -704,7 +709,7 @@ impl<S: Encoder, T: ?Sized + Encodable<S>> Encodable<S> for Box<T> {
}
}
impl<D: Decoder, T: Decodable<D>> Decodable<D> for Box<T> {
fn decode(d: &mut D) -> Result<Box<T>, D::Error> {
Ok(Box::new(Decodable::decode(d)?))
fn decode(d: &mut D) -> Box<T> {
Box::new(Decodable::decode(d))
}
}

View File

@ -1,14 +1,10 @@
#![allow(rustc::internal)]
use json::DecoderError::*;
use json::ErrorCode::*;
use json::Json::*;
use json::JsonEvent::*;
use json::ParserError::*;
use json::{
from_str, DecodeResult, Decoder, DecoderError, Encoder, EncoderError, Json, JsonEvent, Parser,
StackElement,
};
use json::{from_str, Decoder, Encoder, EncoderError, Json, JsonEvent, Parser, StackElement};
use rustc_macros::{Decodable, Encodable};
use rustc_serialize::json;
use rustc_serialize::{Decodable, Encodable};
@ -26,27 +22,27 @@ struct OptionData {
#[test]
fn test_decode_option_none() {
let s = "{}";
let obj: OptionData = json::decode(s).unwrap();
let obj: OptionData = json::decode(s);
assert_eq!(obj, OptionData { opt: None });
}
#[test]
fn test_decode_option_some() {
let s = "{ \"opt\": 10 }";
let obj: OptionData = json::decode(s).unwrap();
let obj: OptionData = json::decode(s);
assert_eq!(obj, OptionData { opt: Some(10) });
}
#[test]
fn test_decode_option_malformed() {
check_err::<OptionData>(
"{ \"opt\": [] }",
ExpectedError("Number".to_string(), "[]".to_string()),
);
check_err::<OptionData>(
"{ \"opt\": false }",
ExpectedError("Number".to_string(), "false".to_string()),
);
#[should_panic(expected = r#"ExpectedError("Number", "[]")"#)]
fn test_decode_option_malformed1() {
check_err::<OptionData>(r#"{ "opt": [] }"#);
}
#[test]
#[should_panic(expected = r#"ExpectedError("Number", "false")"#)]
fn test_decode_option_malformed2() {
check_err::<OptionData>(r#"{ "opt": false }"#);
}
#[derive(PartialEq, Encodable, Decodable, Debug)]
@ -329,13 +325,13 @@ fn test_read_identifiers() {
#[test]
fn test_decode_identifiers() {
let v: () = json::decode("null").unwrap();
let v: () = json::decode("null");
assert_eq!(v, ());
let v: bool = json::decode("true").unwrap();
let v: bool = json::decode("true");
assert_eq!(v, true);
let v: bool = json::decode("false").unwrap();
let v: bool = json::decode("false");
assert_eq!(v, false);
}
@ -368,42 +364,42 @@ fn test_read_number() {
}
#[test]
#[should_panic(expected = r#"ExpectedError("Integer", "765.25")"#)]
fn test_decode_numbers() {
let v: f64 = json::decode("3").unwrap();
let v: f64 = json::decode("3");
assert_eq!(v, 3.0);
let v: f64 = json::decode("3.1").unwrap();
let v: f64 = json::decode("3.1");
assert_eq!(v, 3.1);
let v: f64 = json::decode("-1.2").unwrap();
let v: f64 = json::decode("-1.2");
assert_eq!(v, -1.2);
let v: f64 = json::decode("0.4").unwrap();
let v: f64 = json::decode("0.4");
assert_eq!(v, 0.4);
let v: f64 = json::decode("0.4e5").unwrap();
let v: f64 = json::decode("0.4e5");
assert_eq!(v, 0.4e5);
let v: f64 = json::decode("0.4e15").unwrap();
let v: f64 = json::decode("0.4e15");
assert_eq!(v, 0.4e15);
let v: f64 = json::decode("0.4e-01").unwrap();
let v: f64 = json::decode("0.4e-01");
assert_eq!(v, 0.4e-01);
let v: u64 = json::decode("0").unwrap();
let v: u64 = json::decode("0");
assert_eq!(v, 0);
let v: u64 = json::decode("18446744073709551615").unwrap();
let v: u64 = json::decode("18446744073709551615");
assert_eq!(v, u64::MAX);
let v: i64 = json::decode("-9223372036854775808").unwrap();
let v: i64 = json::decode("-9223372036854775808");
assert_eq!(v, i64::MIN);
let v: i64 = json::decode("9223372036854775807").unwrap();
let v: i64 = json::decode("9223372036854775807");
assert_eq!(v, i64::MAX);
let res: DecodeResult<i64> = json::decode("765.25");
assert_eq!(res, Err(ExpectedError("Integer".to_string(), "765.25".to_string())));
json::decode::<i64>("765.25");
}
#[test]
@ -438,7 +434,7 @@ fn test_decode_str() {
];
for (i, o) in s {
let v: string::String = json::decode(i).unwrap();
let v: string::String = json::decode(i);
assert_eq!(v, o);
}
}
@ -463,39 +459,41 @@ fn test_read_array() {
#[test]
fn test_decode_array() {
let v: Vec<()> = json::decode("[]").unwrap();
let v: Vec<()> = json::decode("[]");
assert_eq!(v, []);
let v: Vec<()> = json::decode("[null]").unwrap();
let v: Vec<()> = json::decode("[null]");
assert_eq!(v, [()]);
let v: Vec<bool> = json::decode("[true]").unwrap();
let v: Vec<bool> = json::decode("[true]");
assert_eq!(v, [true]);
let v: Vec<isize> = json::decode("[3, 1]").unwrap();
let v: Vec<isize> = json::decode("[3, 1]");
assert_eq!(v, [3, 1]);
let v: Vec<Vec<usize>> = json::decode("[[3], [1, 2]]").unwrap();
let v: Vec<Vec<usize>> = json::decode("[[3], [1, 2]]");
assert_eq!(v, [vec![3], vec![1, 2]]);
}
#[test]
fn test_decode_tuple() {
let t: (usize, usize, usize) = json::decode("[1, 2, 3]").unwrap();
let t: (usize, usize, usize) = json::decode("[1, 2, 3]");
assert_eq!(t, (1, 2, 3));
let t: (usize, string::String) = json::decode("[1, \"two\"]").unwrap();
let t: (usize, string::String) = json::decode("[1, \"two\"]");
assert_eq!(t, (1, "two".to_string()));
}
#[test]
#[should_panic]
fn test_decode_tuple_malformed_types() {
assert!(json::decode::<(usize, string::String)>("[1, 2]").is_err());
json::decode::<(usize, string::String)>("[1, 2]");
}
#[test]
#[should_panic]
fn test_decode_tuple_malformed_length() {
assert!(json::decode::<(usize, usize)>("[1, 2, 3]").is_err());
json::decode::<(usize, usize)>("[1, 2, 3]");
}
#[test]
@ -562,7 +560,7 @@ fn test_decode_struct() {
]
}";
let v: Outer = json::decode(s).unwrap();
let v: Outer = json::decode(s);
assert_eq!(
v,
Outer { inner: vec![Inner { a: (), b: 2, c: vec!["abc".to_string(), "xyz".to_string()] }] }
@ -577,7 +575,7 @@ struct FloatStruct {
#[test]
fn test_decode_struct_with_nan() {
let s = "{\"f\":null,\"a\":[null,123]}";
let obj: FloatStruct = json::decode(s).unwrap();
let obj: FloatStruct = json::decode(s);
assert!(obj.f.is_nan());
assert!(obj.a[0].is_nan());
assert_eq!(obj.a[1], 123f64);
@ -585,20 +583,20 @@ fn test_decode_struct_with_nan() {
#[test]
fn test_decode_option() {
let value: Option<string::String> = json::decode("null").unwrap();
let value: Option<string::String> = json::decode("null");
assert_eq!(value, None);
let value: Option<string::String> = json::decode("\"jodhpurs\"").unwrap();
let value: Option<string::String> = json::decode("\"jodhpurs\"");
assert_eq!(value, Some("jodhpurs".to_string()));
}
#[test]
fn test_decode_enum() {
let value: Animal = json::decode("\"Dog\"").unwrap();
let value: Animal = json::decode("\"Dog\"");
assert_eq!(value, Dog);
let s = "{\"variant\":\"Frog\",\"fields\":[\"Henry\",349]}";
let value: Animal = json::decode(s).unwrap();
let value: Animal = json::decode(s);
assert_eq!(value, Frog("Henry".to_string(), 349));
}
@ -606,7 +604,7 @@ fn test_decode_enum() {
fn test_decode_map() {
let s = "{\"a\": \"Dog\", \"b\": {\"variant\":\"Frog\",\
\"fields\":[\"Henry\", 349]}}";
let mut map: BTreeMap<string::String, Animal> = json::decode(s).unwrap();
let mut map: BTreeMap<string::String, Animal> = json::decode(s);
assert_eq!(map.remove(&"a".to_string()), Some(Dog));
assert_eq!(map.remove(&"b".to_string()), Some(Frog("Henry".to_string(), 349)));
@ -630,59 +628,65 @@ enum DecodeEnum {
A(f64),
B(string::String),
}
fn check_err<T: Decodable<Decoder>>(to_parse: &'static str, expected: DecoderError) {
let res: DecodeResult<T> = match from_str(to_parse) {
Err(e) => Err(ParseError(e)),
Ok(json) => Decodable::decode(&mut Decoder::new(json)),
};
match res {
Ok(_) => panic!("`{:?}` parsed & decoded ok, expecting error `{:?}`", to_parse, expected),
Err(ParseError(e)) => panic!("`{:?}` is not valid json: {:?}", to_parse, e),
Err(e) => {
assert_eq!(e, expected);
}
}
fn check_err<T: Decodable<Decoder>>(to_parse: &str) {
let json = from_str(to_parse).unwrap();
let _: T = Decodable::decode(&mut Decoder::new(json));
}
#[test]
fn test_decode_errors_struct() {
check_err::<DecodeStruct>("[]", ExpectedError("Object".to_string(), "[]".to_string()));
check_err::<DecodeStruct>(
"{\"x\": true, \"y\": true, \"z\": \"\", \"w\": []}",
ExpectedError("Number".to_string(), "true".to_string()),
);
check_err::<DecodeStruct>(
"{\"x\": 1, \"y\": [], \"z\": \"\", \"w\": []}",
ExpectedError("Boolean".to_string(), "[]".to_string()),
);
check_err::<DecodeStruct>(
"{\"x\": 1, \"y\": true, \"z\": {}, \"w\": []}",
ExpectedError("String".to_string(), "{}".to_string()),
);
check_err::<DecodeStruct>(
"{\"x\": 1, \"y\": true, \"z\": \"\", \"w\": null}",
ExpectedError("Array".to_string(), "null".to_string()),
);
check_err::<DecodeStruct>(
"{\"x\": 1, \"y\": true, \"z\": \"\"}",
MissingFieldError("w".to_string()),
);
#[should_panic(expected = r#"ExpectedError("Object", "[]")"#)]
fn test_decode_errors_struct1() {
check_err::<DecodeStruct>("[]");
}
#[test]
fn test_decode_errors_enum() {
check_err::<DecodeEnum>("{}", MissingFieldError("variant".to_string()));
check_err::<DecodeEnum>(
"{\"variant\": 1}",
ExpectedError("String".to_string(), "1".to_string()),
);
check_err::<DecodeEnum>("{\"variant\": \"A\"}", MissingFieldError("fields".to_string()));
check_err::<DecodeEnum>(
"{\"variant\": \"A\", \"fields\": null}",
ExpectedError("Array".to_string(), "null".to_string()),
);
check_err::<DecodeEnum>(
"{\"variant\": \"C\", \"fields\": []}",
UnknownVariantError("C".to_string()),
);
#[should_panic(expected = r#"ExpectedError("Number", "true")"#)]
fn test_decode_errors_struct2() {
check_err::<DecodeStruct>(r#"{"x": true, "y": true, "z": "", "w": []}"#);
}
#[test]
#[should_panic(expected = r#"ExpectedError("Boolean", "[]")"#)]
fn test_decode_errors_struct3() {
check_err::<DecodeStruct>(r#"{"x": 1, "y": [], "z": "", "w": []}"#);
}
#[test]
#[should_panic(expected = r#"ExpectedError("String", "{}")"#)]
fn test_decode_errors_struct4() {
check_err::<DecodeStruct>(r#"{"x": 1, "y": true, "z": {}, "w": []}"#);
}
#[test]
#[should_panic(expected = r#"ExpectedError("Array", "null")"#)]
fn test_decode_errors_struct5() {
check_err::<DecodeStruct>(r#"{"x": 1, "y": true, "z": "", "w": null}"#);
}
#[test]
#[should_panic(expected = r#"ExpectedError("Array", "null")"#)]
fn test_decode_errors_struct6() {
check_err::<DecodeStruct>(r#"{"x": 1, "y": true, "z": ""}"#);
}
#[test]
#[should_panic(expected = r#"MissingFieldError("variant")"#)]
fn test_decode_errors_enum1() {
check_err::<DecodeEnum>(r#"{}"#);
}
#[test]
#[should_panic(expected = r#"ExpectedError("String", "1")"#)]
fn test_decode_errors_enum2() {
check_err::<DecodeEnum>(r#"{"variant": 1}"#);
}
#[test]
#[should_panic(expected = r#"MissingFieldError("fields")"#)]
fn test_decode_errors_enum3() {
check_err::<DecodeEnum>(r#"{"variant": "A"}"#);
}
#[test]
#[should_panic(expected = r#"ExpectedError("Array", "null")"#)]
fn test_decode_errors_enum4() {
check_err::<DecodeEnum>(r#"{"variant": "A", "fields": null}"#);
}
#[test]
#[should_panic(expected = r#"UnknownVariantError("C")"#)]
fn test_decode_errors_enum5() {
check_err::<DecodeEnum>(r#"{"variant": "C", "fields": []}"#);
}
#[test]
@ -944,7 +948,7 @@ fn test_hashmap_with_enum_key() {
map.insert(Enum::Foo, 0);
let result = json::encode(&map).unwrap();
assert_eq!(&result[..], r#"{"Foo":0}"#);
let decoded: HashMap<Enum, _> = json::decode(&result).unwrap();
let decoded: HashMap<Enum, _> = json::decode(&result);
assert_eq!(map, decoded);
}
@ -957,10 +961,11 @@ fn test_hashmap_with_numeric_key_can_handle_double_quote_delimited_key() {
Ok(o) => o,
};
let mut decoder = Decoder::new(json_obj);
let _hm: HashMap<usize, bool> = Decodable::decode(&mut decoder).unwrap();
let _hm: HashMap<usize, bool> = Decodable::decode(&mut decoder);
}
#[test]
#[should_panic(expected = r#"ExpectedError("Number", "a")"#)]
fn test_hashmap_with_numeric_key_will_error_with_string_keys() {
use std::collections::HashMap;
let json_str = "{\"a\":true}";
@ -969,8 +974,7 @@ fn test_hashmap_with_numeric_key_will_error_with_string_keys() {
Ok(o) => o,
};
let mut decoder = Decoder::new(json_obj);
let result: Result<HashMap<usize, bool>, DecoderError> = Decodable::decode(&mut decoder);
assert_eq!(result, Err(ExpectedError("Number".to_string(), "a".to_string())));
let _: HashMap<usize, bool> = Decodable::decode(&mut decoder);
}
fn assert_stream_equal(src: &str, expected: Vec<(JsonEvent, Vec<StackElement<'_>>)>) {

View File

@ -41,7 +41,7 @@ fn check_round_trip<T: Encodable<Encoder> + for<'a> Decodable<Decoder<'a>> + Par
let mut decoder = Decoder::new(&data[..], 0);
for value in values {
let decoded = Decodable::decode(&mut decoder).unwrap();
let decoded = Decodable::decode(&mut decoder);
assert_eq!(value, decoded);
}
}

View File

@ -47,8 +47,8 @@ impl<E: Encoder> Encodable<E> for CrateNum {
}
impl<D: Decoder> Decodable<D> for CrateNum {
default fn decode(d: &mut D) -> Result<CrateNum, D::Error> {
Ok(CrateNum::from_u32(d.read_u32()?))
default fn decode(d: &mut D) -> CrateNum {
CrateNum::from_u32(d.read_u32())
}
}
@ -209,7 +209,7 @@ impl<E: Encoder> Encodable<E> for DefIndex {
}
impl<D: Decoder> Decodable<D> for DefIndex {
default fn decode(_: &mut D) -> Result<DefIndex, D::Error> {
default fn decode(_: &mut D) -> DefIndex {
panic!("cannot decode `DefIndex` with `{}`", std::any::type_name::<D>());
}
}
@ -298,12 +298,10 @@ impl<E: Encoder> Encodable<E> for DefId {
}
impl<D: Decoder> Decodable<D> for DefId {
default fn decode(d: &mut D) -> Result<DefId, D::Error> {
d.read_struct(|d| {
Ok(DefId {
krate: d.read_struct_field("krate", Decodable::decode)?,
index: d.read_struct_field("index", Decodable::decode)?,
})
default fn decode(d: &mut D) -> DefId {
d.read_struct(|d| DefId {
krate: d.read_struct_field("krate", Decodable::decode),
index: d.read_struct_field("index", Decodable::decode),
})
}
}
@ -378,8 +376,8 @@ impl<E: Encoder> Encodable<E> for LocalDefId {
}
impl<D: Decoder> Decodable<D> for LocalDefId {
fn decode(d: &mut D) -> Result<LocalDefId, D::Error> {
DefId::decode(d).map(|d| d.expect_local())
fn decode(d: &mut D) -> LocalDefId {
DefId::decode(d).expect_local()
}
}

View File

@ -1314,19 +1314,16 @@ pub fn decode_expn_id(
// to track which `SyntaxContext`s we have already decoded.
// The provided closure will be invoked to deserialize a `SyntaxContextData`
// if we haven't already seen the id of the `SyntaxContext` we are deserializing.
pub fn decode_syntax_context<
D: Decoder,
F: FnOnce(&mut D, u32) -> Result<SyntaxContextData, D::Error>,
>(
pub fn decode_syntax_context<D: Decoder, F: FnOnce(&mut D, u32) -> SyntaxContextData>(
d: &mut D,
context: &HygieneDecodeContext,
decode_data: F,
) -> Result<SyntaxContext, D::Error> {
let raw_id: u32 = Decodable::decode(d)?;
) -> SyntaxContext {
let raw_id: u32 = Decodable::decode(d);
if raw_id == 0 {
debug!("decode_syntax_context: deserialized root");
// The root is special
return Ok(SyntaxContext::root());
return SyntaxContext::root();
}
let outer_ctxts = &context.remapped_ctxts;
@ -1334,7 +1331,7 @@ pub fn decode_syntax_context<
// Ensure that the lock() temporary is dropped early
{
if let Some(ctxt) = outer_ctxts.lock().get(raw_id as usize).copied().flatten() {
return Ok(ctxt);
return ctxt;
}
}
@ -1364,7 +1361,7 @@ pub fn decode_syntax_context<
// Don't try to decode data while holding the lock, since we need to
// be able to recursively decode a SyntaxContext
let mut ctxt_data = decode_data(d, raw_id)?;
let mut ctxt_data = decode_data(d, raw_id);
// Reset `dollar_crate_name` so that it will be updated by `update_dollar_crate_names`
// We don't care what the encoding crate set this to - we want to resolve it
// from the perspective of the current compilation session
@ -1380,7 +1377,7 @@ pub fn decode_syntax_context<
assert_eq!(dummy.dollar_crate_name, kw::Empty);
});
Ok(new_ctxt)
new_ctxt
}
fn for_all_ctxts_in<E, F: FnMut(u32, SyntaxContext, &SyntaxContextData) -> Result<(), E>>(
@ -1422,13 +1419,13 @@ impl<E: Encoder> Encodable<E> for ExpnId {
}
impl<D: Decoder> Decodable<D> for LocalExpnId {
fn decode(d: &mut D) -> Result<Self, D::Error> {
ExpnId::decode(d).map(ExpnId::expect_local)
fn decode(d: &mut D) -> Self {
ExpnId::expect_local(ExpnId::decode(d))
}
}
impl<D: Decoder> Decodable<D> for ExpnId {
default fn decode(_: &mut D) -> Result<Self, D::Error> {
default fn decode(_: &mut D) -> Self {
panic!("cannot decode `ExpnId` with `{}`", std::any::type_name::<D>());
}
}
@ -1451,7 +1448,7 @@ impl<E: Encoder> Encodable<E> for SyntaxContext {
}
impl<D: Decoder> Decodable<D> for SyntaxContext {
default fn decode(_: &mut D) -> Result<Self, D::Error> {
default fn decode(_: &mut D) -> Self {
panic!("cannot decode `SyntaxContext` with `{}`", std::any::type_name::<D>());
}
}

View File

@ -975,12 +975,12 @@ impl<E: Encoder> Encodable<E> for Span {
}
}
impl<D: Decoder> Decodable<D> for Span {
default fn decode(s: &mut D) -> Result<Span, D::Error> {
default fn decode(s: &mut D) -> Span {
s.read_struct(|d| {
let lo = d.read_struct_field("lo", Decodable::decode)?;
let hi = d.read_struct_field("hi", Decodable::decode)?;
let lo = d.read_struct_field("lo", Decodable::decode);
let hi = d.read_struct_field("hi", Decodable::decode);
Ok(Span::new(lo, hi, SyntaxContext::root(), None))
Span::new(lo, hi, SyntaxContext::root(), None)
})
}
}
@ -1448,30 +1448,30 @@ impl<S: Encoder> Encodable<S> for SourceFile {
}
impl<D: Decoder> Decodable<D> for SourceFile {
fn decode(d: &mut D) -> Result<SourceFile, D::Error> {
fn decode(d: &mut D) -> SourceFile {
d.read_struct(|d| {
let name: FileName = d.read_struct_field("name", |d| Decodable::decode(d))?;
let name: FileName = d.read_struct_field("name", |d| Decodable::decode(d));
let src_hash: SourceFileHash =
d.read_struct_field("src_hash", |d| Decodable::decode(d))?;
let start_pos: BytePos = d.read_struct_field("start_pos", |d| Decodable::decode(d))?;
let end_pos: BytePos = d.read_struct_field("end_pos", |d| Decodable::decode(d))?;
d.read_struct_field("src_hash", |d| Decodable::decode(d));
let start_pos: BytePos = d.read_struct_field("start_pos", |d| Decodable::decode(d));
let end_pos: BytePos = d.read_struct_field("end_pos", |d| Decodable::decode(d));
let lines: Vec<BytePos> = d.read_struct_field("lines", |d| {
let num_lines: u32 = Decodable::decode(d)?;
let num_lines: u32 = Decodable::decode(d);
let mut lines = Vec::with_capacity(num_lines as usize);
if num_lines > 0 {
// Read the number of bytes used per diff.
let bytes_per_diff: u8 = Decodable::decode(d)?;
let bytes_per_diff: u8 = Decodable::decode(d);
// Read the first element.
let mut line_start: BytePos = Decodable::decode(d)?;
let mut line_start: BytePos = Decodable::decode(d);
lines.push(line_start);
for _ in 1..num_lines {
let diff = match bytes_per_diff {
1 => d.read_u8()? as u32,
2 => d.read_u16()? as u32,
4 => d.read_u32()?,
1 => d.read_u8() as u32,
2 => d.read_u16() as u32,
4 => d.read_u32(),
_ => unreachable!(),
};
@ -1481,17 +1481,17 @@ impl<D: Decoder> Decodable<D> for SourceFile {
}
}
Ok(lines)
})?;
lines
});
let multibyte_chars: Vec<MultiByteChar> =
d.read_struct_field("multibyte_chars", |d| Decodable::decode(d))?;
d.read_struct_field("multibyte_chars", |d| Decodable::decode(d));
let non_narrow_chars: Vec<NonNarrowChar> =
d.read_struct_field("non_narrow_chars", |d| Decodable::decode(d))?;
let name_hash: u128 = d.read_struct_field("name_hash", |d| Decodable::decode(d))?;
d.read_struct_field("non_narrow_chars", |d| Decodable::decode(d));
let name_hash: u128 = d.read_struct_field("name_hash", |d| Decodable::decode(d));
let normalized_pos: Vec<NormalizedPos> =
d.read_struct_field("normalized_pos", |d| Decodable::decode(d))?;
let cnum: CrateNum = d.read_struct_field("cnum", |d| Decodable::decode(d))?;
Ok(SourceFile {
d.read_struct_field("normalized_pos", |d| Decodable::decode(d));
let cnum: CrateNum = d.read_struct_field("cnum", |d| Decodable::decode(d));
SourceFile {
name,
start_pos,
end_pos,
@ -1506,7 +1506,7 @@ impl<D: Decoder> Decodable<D> for SourceFile {
normalized_pos,
name_hash,
cnum,
})
}
})
}
}
@ -1949,8 +1949,8 @@ impl<S: rustc_serialize::Encoder> Encodable<S> for BytePos {
}
impl<D: rustc_serialize::Decoder> Decodable<D> for BytePos {
fn decode(d: &mut D) -> Result<BytePos, D::Error> {
Ok(BytePos(d.read_u32()?))
fn decode(d: &mut D) -> BytePos {
BytePos(d.read_u32())
}
}

View File

@ -1755,8 +1755,8 @@ impl<S: Encoder> Encodable<S> for Symbol {
impl<D: Decoder> Decodable<D> for Symbol {
#[inline]
fn decode(d: &mut D) -> Result<Symbol, D::Error> {
Ok(Symbol::intern(&d.read_str()?))
fn decode(d: &mut D) -> Symbol {
Symbol::intern(&d.read_str())
}
}

View File

@ -292,7 +292,7 @@ crate fn load_call_locations(
for path in with_examples {
let bytes = fs::read(&path).map_err(|e| format!("{} (for path {})", e, path))?;
let mut decoder = Decoder::new(&bytes, 0);
let calls = AllCallLocations::decode(&mut decoder)?;
let calls = AllCallLocations::decode(&mut decoder);
for (function, fn_calls) in calls.into_iter() {
all_calls.entry(function).or_default().extend(fn_calls.into_iter());

View File

@ -18,6 +18,6 @@ struct A {
fn main() {
let obj = A { foo: Box::new([true, false]) };
let s = json::encode(&obj).unwrap();
let obj2: A = json::decode(&s).unwrap();
let obj2: A = json::decode(&s);
assert_eq!(obj.foo, obj2.foo);
}

View File

@ -27,7 +27,7 @@ struct B {
fn main() {
let obj = B { foo: Cell::new(true), bar: RefCell::new(A { baz: 2 }) };
let s = json::encode(&obj).unwrap();
let obj2: B = json::decode(&s).unwrap();
let obj2: B = json::decode(&s);
assert_eq!(obj.foo.get(), obj2.foo.get());
assert_eq!(obj.bar.borrow().baz, obj2.bar.borrow().baz);
}

View File

@ -20,7 +20,7 @@ pub fn main() {
let json_object = json::from_str(&json_str);
let mut decoder = json::Decoder::new(json_object.unwrap());
let mut decoded_obj: UnitLikeStruct = Decodable::decode(&mut decoder).unwrap();
let mut decoded_obj: UnitLikeStruct = Decodable::decode(&mut decoder);
assert_eq!(obj, decoded_obj);
}

View File

@ -12,7 +12,7 @@ trait JD: Decodable<json::Decoder> {}
fn exec<T: JD>() {
let doc = json::from_str("").unwrap();
let mut decoder = json::Decoder::new(doc);
let _v: T = Decodable::decode(&mut decoder).unwrap();
let _v: T = Decodable::decode(&mut decoder);
panic!()
}

View File

@ -13,5 +13,5 @@ use rustc_serialize::{json, Decodable};
pub fn main() {
let json = json::from_str("[1]").unwrap();
let mut decoder = json::Decoder::new(json);
let _x: Vec<isize> = Decodable::decode(&mut decoder).unwrap();
let _x: Vec<isize> = Decodable::decode(&mut decoder);
}