]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #51356 - Zoxc:encode-cleanup, r=michaelwoerister
authorbors <bors@rust-lang.org>
Wed, 27 Jun 2018 14:25:52 +0000 (14:25 +0000)
committerbors <bors@rust-lang.org>
Wed, 27 Jun 2018 14:25:52 +0000 (14:25 +0000)
Make opaque::Encoder append-only and make it infallible

12 files changed:
src/librustc/ich/fingerprint.rs
src/librustc/ty/codec.rs
src/librustc/ty/query/on_disk_cache.rs
src/librustc_codegen_llvm/back/wasm.rs
src/librustc_incremental/persist/file_format.rs
src/librustc_incremental/persist/save.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/index.rs
src/libserialize/leb128.rs
src/libserialize/lib.rs
src/libserialize/opaque.rs
src/test/run-pass-fulldeps/issue-11881.rs

index f56f4e12e7a02b9b16ffa34c2f9119ad0c492235..2a3b1ce6a36a5075fcf33ff85b6224cfe705baf0 100644 (file)
@@ -52,7 +52,8 @@ pub fn to_hex(&self) -> String {
     pub fn encode_opaque(&self, encoder: &mut Encoder) -> EncodeResult {
         let bytes: [u8; 16] = unsafe { mem::transmute([self.0.to_le(), self.1.to_le()]) };
 
-        encoder.emit_raw_bytes(&bytes)
+        encoder.emit_raw_bytes(&bytes);
+        Ok(())
     }
 
     pub fn decode_opaque<'a>(decoder: &mut Decoder<'a>) -> Result<Fingerprint, String> {
@@ -92,7 +93,7 @@ impl serialize::UseSpecializedEncodable for Fingerprint { }
 
 impl serialize::UseSpecializedDecodable for Fingerprint { }
 
-impl<'a> serialize::SpecializedEncoder<Fingerprint> for serialize::opaque::Encoder<'a> {
+impl serialize::SpecializedEncoder<Fingerprint> for serialize::opaque::Encoder {
     fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
         f.encode_opaque(self)
     }
index d911f32ed3f1f7bc227d5f08ab4854de38011233..967a3324cfb2a92113d202133085d0b80df2d9bb 100644 (file)
@@ -54,7 +54,7 @@ pub trait TyEncoder: Encoder {
     fn position(&self) -> usize;
 }
 
-impl<'buf> TyEncoder for opaque::Encoder<'buf> {
+impl TyEncoder for opaque::Encoder {
     #[inline]
     fn position(&self) -> usize {
         self.position()
index 3285380c823922b2cf74ccc8b602c0f7be21644c..c42323e3d4a23de4695d376b57569ce7d287f53f 100644 (file)
@@ -979,7 +979,7 @@ fn specialized_encode(&mut self, node_id: &NodeId) -> Result<(), Self::Error> {
 }
 
 impl<'enc, 'a, 'tcx> SpecializedEncoder<Fingerprint>
-for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder<'enc>>
+for CacheEncoder<'enc, 'a, 'tcx, opaque::Encoder>
 {
     fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
         f.encode_opaque(&mut self.encoder)
@@ -1057,7 +1057,7 @@ impl IntEncodedWithFixedSize {
 impl UseSpecializedEncodable for IntEncodedWithFixedSize {}
 impl UseSpecializedDecodable for IntEncodedWithFixedSize {}
 
-impl<'enc> SpecializedEncoder<IntEncodedWithFixedSize> for opaque::Encoder<'enc> {
+impl SpecializedEncoder<IntEncodedWithFixedSize> for opaque::Encoder {
     fn specialized_encode(&mut self, x: &IntEncodedWithFixedSize) -> Result<(), Self::Error> {
         let start_pos = self.position();
         for i in 0 .. IntEncodedWithFixedSize::ENCODED_SIZE {
index d6d386c9fbe77d74cd3468c1aed99fdf985c1704..c553eca08e6b4979a929d9dafbf49c3c40e6727d 100644 (file)
@@ -230,8 +230,7 @@ fn new() -> WasmEncoder {
     }
 
     fn u32(&mut self, val: u32) {
-        let at = self.data.len();
-        leb128::write_u32_leb128(&mut self.data, at, val);
+        leb128::write_u32_leb128(&mut self.data, val);
     }
 
     fn byte(&mut self, val: u8) {
index d45994adeb67bcf2da10fcbfed2c587ff9632c90..98f7873fda0e41da5c569fcb237117881aaed3f0 100644 (file)
@@ -25,6 +25,7 @@
 use std::env;
 
 use rustc::session::config::nightly_options;
+use rustc_serialize::opaque::Encoder;
 
 /// The first few bytes of files generated by incremental compilation
 const FILE_MAGIC: &'static [u8] = b"RSIC";
 /// the git commit hash.
 const RUSTC_VERSION: Option<&'static str> = option_env!("CFG_VERSION");
 
-pub fn write_file_header<W: io::Write>(stream: &mut W) -> io::Result<()> {
-    stream.write_all(FILE_MAGIC)?;
-    stream.write_all(&[(HEADER_FORMAT_VERSION >> 0) as u8,
-                       (HEADER_FORMAT_VERSION >> 8) as u8])?;
+pub fn write_file_header(stream: &mut Encoder) {
+    stream.emit_raw_bytes(FILE_MAGIC);
+    stream.emit_raw_bytes(&[(HEADER_FORMAT_VERSION >> 0) as u8,
+                       (HEADER_FORMAT_VERSION >> 8) as u8]);
 
     let rustc_version = rustc_version();
     assert_eq!(rustc_version.len(), (rustc_version.len() as u8) as usize);
-    stream.write_all(&[rustc_version.len() as u8])?;
-    stream.write_all(rustc_version.as_bytes())?;
-
-    Ok(())
+    stream.emit_raw_bytes(&[rustc_version.len() as u8]);
+    stream.emit_raw_bytes(rustc_version.as_bytes());
 }
 
 /// Reads the contents of a file with a file header as defined in this module.
index dcef0c662c3a1164ca53bbf87b24fa9f07d68400..06b0ea946d778fc99847092fbb00a60a054923dd 100644 (file)
@@ -16,7 +16,6 @@
 use rustc_data_structures::sync::join;
 use rustc_serialize::Encodable as RustcEncodable;
 use rustc_serialize::opaque::Encoder;
-use std::io::{self, Cursor};
 use std::fs;
 use std::path::PathBuf;
 
@@ -98,7 +97,7 @@ pub fn save_work_product_index(sess: &Session,
 }
 
 fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
-    where F: FnOnce(&mut Encoder) -> io::Result<()>
+    where F: FnOnce(&mut Encoder)
 {
     debug!("save: storing data in {}", path_buf.display());
 
@@ -121,20 +120,12 @@ fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
     }
 
     // generate the data in a memory buffer
-    let mut wr = Cursor::new(Vec::new());
-    file_format::write_file_header(&mut wr).unwrap();
-    match encode(&mut Encoder::new(&mut wr)) {
-        Ok(()) => {}
-        Err(err) => {
-            sess.err(&format!("could not encode dep-graph to `{}`: {}",
-                              path_buf.display(),
-                              err));
-            return;
-        }
-    }
+    let mut encoder = Encoder::new(Vec::new());
+    file_format::write_file_header(&mut encoder);
+    encode(&mut encoder);
 
     // write the data out
-    let data = wr.into_inner();
+    let data = encoder.into_inner();
     match fs::write(&path_buf, data) {
         Ok(_) => {
             debug!("save: data written to disk successfully");
@@ -149,10 +140,9 @@ fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
 }
 
 fn encode_dep_graph(tcx: TyCtxt,
-                    encoder: &mut Encoder)
-                    -> io::Result<()> {
+                    encoder: &mut Encoder) {
     // First encode the commandline arguments hash
-    tcx.sess.opts.dep_tracking_hash().encode(encoder)?;
+    tcx.sess.opts.dep_tracking_hash().encode(encoder).unwrap();
 
     // Encode the graph data.
     let serialized_graph = time(tcx.sess, "getting serialized graph", || {
@@ -234,14 +224,12 @@ struct Stat {
     }
 
     time(tcx.sess, "encoding serialized graph", || {
-        serialized_graph.encode(encoder)
-    })?;
-
-    Ok(())
+        serialized_graph.encode(encoder).unwrap();
+    });
 }
 
 fn encode_work_product_index(work_products: &FxHashMap<WorkProductId, WorkProduct>,
-                             encoder: &mut Encoder) -> io::Result<()> {
+                             encoder: &mut Encoder) {
     let serialized_products: Vec<_> = work_products
         .iter()
         .map(|(id, work_product)| {
@@ -252,13 +240,12 @@ fn encode_work_product_index(work_products: &FxHashMap<WorkProductId, WorkProduc
         })
         .collect();
 
-    serialized_products.encode(encoder)
+    serialized_products.encode(encoder).unwrap();
 }
 
 fn encode_query_cache(tcx: TyCtxt,
-                      encoder: &mut Encoder)
-                      -> io::Result<()> {
+                      encoder: &mut Encoder) {
     time(tcx.sess, "serialize query result cache", || {
-        tcx.serialize_query_result_cache(encoder)
+        tcx.serialize_query_result_cache(encoder).unwrap();
     })
 }
index ce270006a9d0ad187d1a1e213363238804dbc545..46c4a3a1abe80aff682ce27a2ffc5d17f1118c73 100644 (file)
@@ -35,8 +35,6 @@
 use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque};
 
 use std::hash::Hash;
-use std::io::prelude::*;
-use std::io::Cursor;
 use std::path::Path;
 use rustc_data_structures::sync::Lrc;
 use std::u32;
@@ -52,7 +50,7 @@
 use rustc::hir::intravisit;
 
 pub struct EncodeContext<'a, 'tcx: 'a> {
-    opaque: opaque::Encoder<'a>,
+    opaque: opaque::Encoder,
     pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
     link_meta: &'a LinkMeta,
 
@@ -76,7 +74,7 @@ macro_rules! encoder_methods {
 }
 
 impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
-    type Error = <opaque::Encoder<'a> as Encoder>::Error;
+    type Error = <opaque::Encoder as Encoder>::Error;
 
     fn emit_nil(&mut self) -> Result<(), Self::Error> {
         Ok(())
@@ -480,7 +478,7 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
 
         // Index the items
         i = self.position();
-        let index = items.write_index(&mut self.opaque.cursor);
+        let index = items.write_index(&mut self.opaque);
         let index_bytes = self.position() - i;
 
         let attrs = tcx.hir.krate_attrs();
@@ -537,7 +535,7 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
 
         if self.tcx.sess.meta_stats() {
             let mut zero_bytes = 0;
-            for e in self.opaque.cursor.get_ref() {
+            for e in self.opaque.data.iter() {
                 if *e == 0 {
                     zero_bytes += 1;
                 }
@@ -1797,15 +1795,15 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                  link_meta: &LinkMeta)
                                  -> EncodedMetadata
 {
-    let mut cursor = Cursor::new(vec![]);
-    cursor.write_all(METADATA_HEADER).unwrap();
+    let mut encoder = opaque::Encoder::new(vec![]);
+    encoder.emit_raw_bytes(METADATA_HEADER);
 
     // Will be filled with the root position after encoding everything.
-    cursor.write_all(&[0, 0, 0, 0]).unwrap();
+    encoder.emit_raw_bytes(&[0, 0, 0, 0]);
 
-    let root = {
+    let (root, mut result) = {
         let mut ecx = EncodeContext {
-            opaque: opaque::Encoder::new(&mut cursor),
+            opaque: encoder,
             tcx,
             link_meta,
             lazy_state: LazyState::NoNode,
@@ -1821,9 +1819,9 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
         // Encode all the entries and extra information in the crate,
         // culminating in the `CrateRoot` which points to all of it.
-        ecx.encode_crate_root()
+        let root = ecx.encode_crate_root();
+        (root, ecx.opaque.into_inner())
     };
-    let mut result = cursor.into_inner();
 
     // Encode the root position.
     let header = METADATA_HEADER.len();
index 157b8385a6922e9d3e77e44b4bf0ab238ea89f24..0b4f7e579acb91fb133ee069fd7ab637458fae7c 100644 (file)
@@ -11,7 +11,7 @@
 use schema::*;
 
 use rustc::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace};
-use std::io::{Cursor, Write};
+use rustc_serialize::opaque::Encoder;
 use std::slice;
 use std::u32;
 
@@ -54,15 +54,15 @@ pub fn record_index(&mut self, item: DefIndex, entry: Lazy<Entry>) {
         self.positions[space_index][array_index] = position.to_le();
     }
 
-    pub fn write_index(&self, buf: &mut Cursor<Vec<u8>>) -> LazySeq<Index> {
+    pub fn write_index(&self, buf: &mut Encoder) -> LazySeq<Index> {
         let pos = buf.position();
 
         // First we write the length of the lower range ...
-        buf.write_all(words_to_bytes(&[(self.positions[0].len() as u32).to_le()])).unwrap();
+        buf.emit_raw_bytes(words_to_bytes(&[(self.positions[0].len() as u32).to_le()]));
         // ... then the values in the lower range ...
-        buf.write_all(words_to_bytes(&self.positions[0][..])).unwrap();
+        buf.emit_raw_bytes(words_to_bytes(&self.positions[0][..]));
         // ... then the values in the higher range.
-        buf.write_all(words_to_bytes(&self.positions[1][..])).unwrap();
+        buf.emit_raw_bytes(words_to_bytes(&self.positions[1][..]));
         LazySeq::with_position_and_length(pos as usize,
             self.positions[0].len() + self.positions[1].len() + 1)
     }
index 1786e2960825dfb7b6340c8c8a84872fc2c21a2c..ae7f25c7fedbe43ecfbe5c82de45b8ab4d8c0e85 100644 (file)
@@ -9,12 +9,8 @@
 // except according to those terms.
 
 #[inline]
-pub fn write_to_vec(vec: &mut Vec<u8>, position: usize, byte: u8) {
-    if position == vec.len() {
-        vec.push(byte);
-    } else {
-        vec[position] = byte;
-    }
+pub fn write_to_vec(vec: &mut Vec<u8>, byte: u8) {
+    vec.push(byte);
 }
 
 #[cfg(target_pointer_width = "32")]
@@ -33,8 +29,7 @@ macro_rules! leb128_size {
 macro_rules! impl_write_unsigned_leb128 {
     ($fn_name:ident, $int_ty:ident) => (
         #[inline]
-        pub fn $fn_name(out: &mut Vec<u8>, start_position: usize, mut value: $int_ty) -> usize {
-            let mut position = start_position;
+        pub fn $fn_name(out: &mut Vec<u8>, mut value: $int_ty) {
             for _ in 0 .. leb128_size!($int_ty) {
                 let mut byte = (value & 0x7F) as u8;
                 value >>= 7;
@@ -42,15 +37,12 @@ pub fn $fn_name(out: &mut Vec<u8>, start_position: usize, mut value: $int_ty) ->
                     byte |= 0x80;
                 }
 
-                write_to_vec(out, position, byte);
-                position += 1;
+                write_to_vec(out, byte);
 
                 if value == 0 {
                     break;
                 }
             }
-
-            position - start_position
         }
     )
 }
@@ -105,11 +97,9 @@ pub fn $fn_name(slice: &[u8]) -> ($int_ty, usize) {
 /// The callback `write` is called once for each position
 /// that is to be written to with the byte to be encoded
 /// at that position.
-pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W) -> usize
-    where W: FnMut(usize, u8)
+pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W)
+    where W: FnMut(u8)
 {
-    let mut position = 0;
-
     loop {
         let mut byte = (value as u8) & 0x7f;
         value >>= 7;
@@ -120,18 +110,16 @@ pub fn write_signed_leb128_to<W>(mut value: i128, mut write: W) -> usize
             byte |= 0x80; // Mark this byte to show that more bytes will follow.
         }
 
-        write(position, byte);
-        position += 1;
+        write(byte);
 
         if !more {
             break;
         }
     }
-    position
 }
 
-pub fn write_signed_leb128(out: &mut Vec<u8>, start_position: usize, value: i128) -> usize {
-    write_signed_leb128_to(value, |i, v| write_to_vec(out, start_position+i, v))
+pub fn write_signed_leb128(out: &mut Vec<u8>, value: i128) {
+    write_signed_leb128_to(value, |v| write_to_vec(out, v))
 }
 
 #[inline]
@@ -167,9 +155,7 @@ fn $test_name() {
             let mut stream = Vec::new();
 
             for x in 0..62 {
-                let pos = stream.len();
-                let bytes_written = $write_fn_name(&mut stream, pos, (3u64 << x) as $int_ty);
-                assert_eq!(stream.len(), pos + bytes_written);
+                $write_fn_name(&mut stream, (3u64 << x) as $int_ty);
             }
 
             let mut position = 0;
@@ -195,9 +181,7 @@ fn test_signed_leb128() {
     let values: Vec<_> = (-500..500).map(|i| i * 0x12345789ABCDEF).collect();
     let mut stream = Vec::new();
     for &x in &values {
-        let pos = stream.len();
-        let bytes_written = write_signed_leb128(&mut stream, pos, x);
-        assert_eq!(stream.len(), pos + bytes_written);
+        write_signed_leb128(&mut stream, x);
     }
     let mut pos = 0;
     for &x in &values {
index 22d27b6697a7c8973257ba0c4de88528971f82d4..a5f4b32b329e7c22a51c791035a9cb05d168076d 100644 (file)
@@ -23,6 +23,7 @@
 #![feature(box_syntax)]
 #![feature(core_intrinsics)]
 #![feature(specialization)]
+#![feature(never_type)]
 #![cfg_attr(test, feature(test))]
 
 pub use self::serialize::{Decoder, Encoder, Decodable, Encodable};
index 077efadd60af88823876634ce0524ee0311f060a..a77d1d9b88b89a0e048c6f8123de8386ef727a98 100644 (file)
 
 use leb128::{self, read_signed_leb128, write_signed_leb128};
 use std::borrow::Cow;
-use std::io::{self, Write};
 use serialize;
 
 // -----------------------------------------------------------------------------
 // Encoder
 // -----------------------------------------------------------------------------
 
-pub type EncodeResult = io::Result<()>;
+pub type EncodeResult = Result<(), !>;
 
-pub struct Encoder<'a> {
-    pub cursor: &'a mut io::Cursor<Vec<u8>>,
+pub struct Encoder {
+    pub data: Vec<u8>,
 }
 
-impl<'a> Encoder<'a> {
-    pub fn new(cursor: &'a mut io::Cursor<Vec<u8>>) -> Encoder<'a> {
-        Encoder { cursor: cursor }
+impl Encoder {
+    pub fn new(data: Vec<u8>) -> Encoder {
+        Encoder { data }
     }
 
-    pub fn emit_raw_bytes(&mut self, s: &[u8]) -> EncodeResult {
-        self.cursor.write_all(s)
+    pub fn into_inner(self) -> Vec<u8> {
+        self.data
     }
-}
 
+    pub fn emit_raw_bytes(&mut self, s: &[u8]) {
+        self.data.extend_from_slice(s);
+    }
+}
 
 macro_rules! write_uleb128 {
     ($enc:expr, $value:expr, $fun:ident) => {{
-        let pos = $enc.cursor.position() as usize;
-        let bytes_written = leb128::$fun($enc.cursor.get_mut(), pos, $value);
-        $enc.cursor.set_position((pos + bytes_written) as u64);
+        leb128::$fun(&mut $enc.data, $value);
         Ok(())
     }}
 }
 
 macro_rules! write_sleb128 {
     ($enc:expr, $value:expr) => {{
-        let pos = $enc.cursor.position() as usize;
-        let bytes_written = write_signed_leb128($enc.cursor.get_mut(), pos, $value as i128);
-        $enc.cursor.set_position((pos + bytes_written) as u64);
+        write_signed_leb128(&mut $enc.data, $value as i128);
         Ok(())
     }}
 }
 
-impl<'a> serialize::Encoder for Encoder<'a> {
-    type Error = io::Error;
+impl serialize::Encoder for Encoder {
+    type Error = !;
 
     #[inline]
     fn emit_nil(&mut self) -> EncodeResult {
@@ -87,9 +85,7 @@ fn emit_u16(&mut self, v: u16) -> EncodeResult {
 
     #[inline]
     fn emit_u8(&mut self, v: u8) -> EncodeResult {
-        let pos = self.cursor.position() as usize;
-        leb128::write_to_vec(self.cursor.get_mut(), pos, v);
-        self.cursor.set_position((pos + 1) as u64);
+        self.data.push(v);
         Ok(())
     }
 
@@ -153,15 +149,15 @@ fn emit_char(&mut self, v: char) -> EncodeResult {
     #[inline]
     fn emit_str(&mut self, v: &str) -> EncodeResult {
         self.emit_usize(v.len())?;
-        let _ = self.cursor.write_all(v.as_bytes());
+        self.emit_raw_bytes(v.as_bytes());
         Ok(())
     }
 }
 
-impl<'a> Encoder<'a> {
+impl Encoder {
     #[inline]
     pub fn position(&self) -> usize {
-        self.cursor.position() as usize
+        self.data.len()
     }
 }
 
@@ -339,7 +335,6 @@ fn error(&mut self, err: &str) -> Self::Error {
 #[cfg(test)]
 mod tests {
     use serialize::{Encodable, Decodable};
-    use std::io::Cursor;
     use std::fmt::Debug;
     use super::{Encoder, Decoder};
 
@@ -368,14 +363,13 @@ struct Struct {
 
 
     fn check_round_trip<T: Encodable + Decodable + PartialEq + Debug>(values: Vec<T>) {
-        let mut cursor = Cursor::new(Vec::new());
+        let mut encoder = Encoder::new(Vec::new());
 
         for value in &values {
-            let mut encoder = Encoder::new(&mut cursor);
             Encodable::encode(&value, &mut encoder).unwrap();
         }
 
-        let data = cursor.into_inner();
+        let data = encoder.into_inner();
         let mut decoder = Decoder::new(&data[..], 0);
 
         for value in values {
index 914e3dd4932488b7f8c3dbb49e58b50e4a83c3aa..4f419e70074fc673a329cecb20e89b9f859b2612 100644 (file)
@@ -41,17 +41,16 @@ enum WireProtocol {
 fn encode_json<T: Encodable>(val: &T, wr: &mut Cursor<Vec<u8>>) {
     write!(wr, "{}", json::as_json(val));
 }
-fn encode_opaque<T: Encodable>(val: &T, wr: &mut Cursor<Vec<u8>>) {
+fn encode_opaque<T: Encodable>(val: &T, wr: Vec<u8>) {
     let mut encoder = opaque::Encoder::new(wr);
     val.encode(&mut encoder);
 }
 
 pub fn main() {
     let target = Foo{baz: false,};
-    let mut wr = Cursor::new(Vec::new());
     let proto = WireProtocol::JSON;
     match proto {
-        WireProtocol::JSON => encode_json(&target, &mut wr),
-        WireProtocol::Opaque => encode_opaque(&target, &mut wr)
+        WireProtocol::JSON => encode_json(&target, &mut Cursor::new(Vec::new())),
+        WireProtocol::Opaque => encode_opaque(&target, Vec::new())
     }
 }