From cbcef3effcf64bd0d89ea2dc8973e18d7fcf94c3 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Thu, 11 Jun 2020 15:49:57 +0100 Subject: Rework `rustc_serialize` - Move the type parameter from `encode` and `decode` methods to the trait. - Remove `UseSpecialized(En|De)codable` traits. - Remove blanket impls for references. - Add `RefDecodable` trait to allow deserializing to arena-allocated references safely. - Remove ability to (de)serialize HIR. - Create proc-macros `(Ty)?(En|De)codable` to help implement these new traits. --- src/librustc_data_structures/Cargo.toml | 1 + src/librustc_data_structures/fingerprint.rs | 48 ++++++++++++--- src/librustc_data_structures/lib.rs | 2 + src/librustc_data_structures/sorted_map.rs | 13 +--- src/librustc_data_structures/svh.rs | 8 +-- src/librustc_data_structures/thin_vec.rs | 2 +- .../transitive_relation.rs | 69 +--------------------- 7 files changed, 50 insertions(+), 93 deletions(-) (limited to 'src/librustc_data_structures') diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 36c32e60031..1926dbf06e7 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -17,6 +17,7 @@ jobserver_crate = { version = "0.1.13", package = "jobserver" } lazy_static = "1" once_cell = { version = "1", features = ["parking_lot"] } rustc_serialize = { path = "../librustc_serialize" } +rustc_macros = { path = "../librustc_macros" } rustc_graphviz = { path = "../librustc_graphviz" } cfg-if = "0.1.2" crossbeam-utils = { version = "0.7", features = ["nightly"] } diff --git a/src/librustc_data_structures/fingerprint.rs b/src/librustc_data_structures/fingerprint.rs index 282626611d5..f8d631ce01e 100644 --- a/src/librustc_data_structures/fingerprint.rs +++ b/src/librustc_data_structures/fingerprint.rs @@ -1,5 +1,8 @@ use crate::stable_hasher; -use rustc_serialize::opaque::{Decoder, EncodeResult, Encoder}; +use rustc_serialize::{ + opaque::{self, EncodeResult}, + Decodable, Encodable, +}; use std::mem; #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)] @@ -49,14 +52,14 @@ impl Fingerprint { format!("{:x}{:x}", self.0, self.1) } - pub fn encode_opaque(&self, encoder: &mut Encoder) -> EncodeResult { + pub fn encode_opaque(&self, encoder: &mut opaque::Encoder) -> EncodeResult { let bytes: [u8; 16] = unsafe { mem::transmute([self.0.to_le(), self.1.to_le()]) }; encoder.emit_raw_bytes(&bytes); Ok(()) } - pub fn decode_opaque(decoder: &mut Decoder<'_>) -> Result { + pub fn decode_opaque(decoder: &mut opaque::Decoder<'_>) -> Result { let mut bytes = [0; 16]; decoder.read_raw_bytes(&mut bytes)?; @@ -83,18 +86,45 @@ impl stable_hasher::StableHasherResult for Fingerprint { impl_stable_hash_via_hash!(Fingerprint); -impl rustc_serialize::UseSpecializedEncodable for Fingerprint {} +impl Encodable for Fingerprint { + fn encode(&self, s: &mut E) -> Result<(), E::Error> { + s.encode_fingerprint(self) + } +} -impl rustc_serialize::UseSpecializedDecodable for Fingerprint {} +impl Decodable for Fingerprint { + fn decode(d: &mut D) -> Result { + d.decode_fingerprint() + } +} -impl rustc_serialize::SpecializedEncoder for Encoder { - fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> { +pub trait FingerprintEncoder: rustc_serialize::Encoder { + fn encode_fingerprint(&mut self, f: &Fingerprint) -> Result<(), Self::Error>; +} + +pub trait FingerprintDecoder: rustc_serialize::Decoder { + fn decode_fingerprint(&mut self) -> Result; +} + +impl FingerprintEncoder for E { + default fn encode_fingerprint(&mut self, _: &Fingerprint) -> Result<(), E::Error> { + panic!("Cannot encode `Fingerprint` with `{}`", std::any::type_name::()); + } +} + +impl FingerprintEncoder for opaque::Encoder { + fn encode_fingerprint(&mut self, f: &Fingerprint) -> EncodeResult { f.encode_opaque(self) } } -impl<'a> rustc_serialize::SpecializedDecoder for Decoder<'a> { - fn specialized_decode(&mut self) -> Result { +impl FingerprintDecoder for D { + default fn decode_fingerprint(&mut self) -> Result { + panic!("Cannot decode `Fingerprint` with `{}`", std::any::type_name::()); + } +} +impl FingerprintDecoder for opaque::Decoder<'_> { + fn decode_fingerprint(&mut self) -> Result { Fingerprint::decode_opaque(self) } } diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 3884fc05105..017511cc50d 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -29,6 +29,8 @@ extern crate log; #[macro_use] extern crate cfg_if; +#[macro_use] +extern crate rustc_macros; #[inline(never)] #[cold] diff --git a/src/librustc_data_structures/sorted_map.rs b/src/librustc_data_structures/sorted_map.rs index 652268dcee8..856eb73e629 100644 --- a/src/librustc_data_structures/sorted_map.rs +++ b/src/librustc_data_structures/sorted_map.rs @@ -16,18 +16,7 @@ pub use index_map::SortedIndexMultiMap; /// stores data in a more compact way. It also supports accessing contiguous /// ranges of elements as a slice, and slices of already sorted elements can be /// inserted efficiently. -#[derive( - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - Default, - Debug, - RustcEncodable, - RustcDecodable -)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug, Encodable, Decodable)] pub struct SortedMap { data: Vec<(K, V)>, } diff --git a/src/librustc_data_structures/svh.rs b/src/librustc_data_structures/svh.rs index 476eb9e14f9..02103de2e8d 100644 --- a/src/librustc_data_structures/svh.rs +++ b/src/librustc_data_structures/svh.rs @@ -48,14 +48,14 @@ impl fmt::Display for Svh { } } -impl Encodable for Svh { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { +impl Encodable for Svh { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { s.emit_u64(self.as_u64().to_le()) } } -impl Decodable for Svh { - fn decode(d: &mut D) -> Result { +impl Decodable for Svh { + fn decode(d: &mut D) -> Result { d.read_u64().map(u64::from_le).map(Svh::new) } } diff --git a/src/librustc_data_structures/thin_vec.rs b/src/librustc_data_structures/thin_vec.rs index 43002178eb9..4d673fd5cf9 100644 --- a/src/librustc_data_structures/thin_vec.rs +++ b/src/librustc_data_structures/thin_vec.rs @@ -3,7 +3,7 @@ use crate::stable_hasher::{HashStable, StableHasher}; /// A vector type optimized for cases where this size is usually 0 (cf. `SmallVector`). /// The `Option>` wrapping allows us to represent a zero sized vector with `None`, /// which uses only a single (null) pointer. -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, Encodable, Decodable, Debug)] pub struct ThinVec(Option>>); impl ThinVec { diff --git a/src/librustc_data_structures/transitive_relation.rs b/src/librustc_data_structures/transitive_relation.rs index 7d137a55033..fe60a99dde0 100644 --- a/src/librustc_data_structures/transitive_relation.rs +++ b/src/librustc_data_structures/transitive_relation.rs @@ -1,8 +1,6 @@ use crate::fx::FxIndexSet; -use crate::stable_hasher::{HashStable, StableHasher}; use crate::sync::Lock; use rustc_index::bit_set::BitMatrix; -use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::fmt::Debug; use std::hash::Hash; use std::mem; @@ -42,10 +40,10 @@ impl Default for TransitiveRelation { } } -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, RustcEncodable, RustcDecodable, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Debug)] struct Index(usize); -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] +#[derive(Clone, PartialEq, Eq, Debug)] struct Edge { source: Index, target: Index, @@ -402,66 +400,3 @@ fn pare_down(candidates: &mut Vec, closure: &BitMatrix) { candidates.truncate(j - dead); } } - -impl Encodable for TransitiveRelation -where - T: Clone + Encodable + Debug + Eq + Hash + Clone, -{ - fn encode(&self, s: &mut E) -> Result<(), E::Error> { - s.emit_struct("TransitiveRelation", 2, |s| { - s.emit_struct_field("elements", 0, |s| self.elements.encode(s))?; - s.emit_struct_field("edges", 1, |s| self.edges.encode(s))?; - Ok(()) - }) - } -} - -impl Decodable for TransitiveRelation -where - T: Clone + Decodable + Debug + Eq + Hash + Clone, -{ - fn decode(d: &mut D) -> Result { - d.read_struct("TransitiveRelation", 2, |d| { - Ok(TransitiveRelation { - elements: d.read_struct_field("elements", 0, |d| Decodable::decode(d))?, - edges: d.read_struct_field("edges", 1, |d| Decodable::decode(d))?, - closure: Lock::new(None), - }) - }) - } -} - -impl HashStable for TransitiveRelation -where - T: HashStable + Eq + Debug + Clone + Hash, -{ - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { - // We are assuming here that the relation graph has been built in a - // deterministic way and we can just hash it the way it is. - let TransitiveRelation { - ref elements, - ref edges, - // "closure" is just a copy of the data above - closure: _, - } = *self; - - elements.hash_stable(hcx, hasher); - edges.hash_stable(hcx, hasher); - } -} - -impl HashStable for Edge { - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { - let Edge { ref source, ref target } = *self; - - source.hash_stable(hcx, hasher); - target.hash_stable(hcx, hasher); - } -} - -impl HashStable for Index { - fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { - let Index(idx) = *self; - idx.hash_stable(hcx, hasher); - } -} -- cgit 1.4.1-3-g733a5