1
Fork 0

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

@ -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()?;
{
let mut it = s.chars();
if let (Some(c), None) = (it.next(), it.next()) {
// exactly one character
return Ok(c);
}
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 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)),
);
}
vec.set_len(len);
}
Ok(v)
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))
}
}