about summary refs log tree commit diff
path: root/compiler/rustc_serialize/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-03-26 01:28:59 +0000
committerbors <bors@rust-lang.org>2021-03-26 01:28:59 +0000
commit0ced530534de1a77504b6229e6303d37a12282ee (patch)
tree57f7a07189e5b8761db60756feb05de6d1be9537 /compiler/rustc_serialize/src
parent3debe9acb8df363e0b5363f23f8218c2d7919904 (diff)
parent517d5ac230ab11ba5e8810dacc5878065fcdd08e (diff)
downloadrust-0ced530534de1a77504b6229e6303d37a12282ee.tar.gz
rust-0ced530534de1a77504b6229e6303d37a12282ee.zip
Auto merge of #83465 - michaelwoerister:safe-read_raw_bytes, r=cjgillot
Allow for reading raw bytes from rustc_serialize::Decoder without unsafe code

The current `read_raw_bytes` method requires using `MaybeUninit` and `unsafe`. I don't think this is necessary. Let's see if a safe interface has any performance drawbacks.

This is a followup to #83273 and will make it easier to rebase #82183.

r? `@cjgillot`
Diffstat (limited to 'compiler/rustc_serialize/src')
-rw-r--r--compiler/rustc_serialize/src/json.rs6
-rw-r--r--compiler/rustc_serialize/src/opaque.rs44
-rw-r--r--compiler/rustc_serialize/src/serialize.rs3
3 files changed, 18 insertions, 35 deletions
diff --git a/compiler/rustc_serialize/src/json.rs b/compiler/rustc_serialize/src/json.rs
index 51945ab435e..78a102c5c23 100644
--- a/compiler/rustc_serialize/src/json.rs
+++ b/compiler/rustc_serialize/src/json.rs
@@ -188,7 +188,6 @@ use std::collections::{BTreeMap, HashMap};
 use std::io;
 use std::io::prelude::*;
 use std::mem::swap;
-use std::mem::MaybeUninit;
 use std::num::FpCategory as Fp;
 use std::ops::Index;
 use std::str::FromStr;
@@ -2367,10 +2366,9 @@ impl crate::Decoder for Decoder {
         expect!(self.pop(), String).map(Cow::Owned)
     }
 
-    fn read_raw_bytes(&mut self, s: &mut [MaybeUninit<u8>]) -> Result<(), Self::Error> {
+    fn read_raw_bytes_into(&mut self, s: &mut [u8]) -> Result<(), Self::Error> {
         for c in s.iter_mut() {
-            let h = self.read_u8()?;
-            unsafe { *c.as_mut_ptr() = h };
+            *c = self.read_u8()?;
         }
         Ok(())
     }
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index c171593ebdc..6e36184aff0 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -1,6 +1,7 @@
 use crate::leb128::{self, max_leb128_len};
-use crate::serialize::{self, Decoder as _, Encoder as _};
+use crate::serialize::{self, Encoder as _};
 use std::borrow::Cow;
+use std::convert::TryInto;
 use std::fs::File;
 use std::io::{self, Write};
 use std::mem::MaybeUninit;
@@ -539,6 +540,13 @@ impl<'a> Decoder<'a> {
     pub fn advance(&mut self, bytes: usize) {
         self.position += bytes;
     }
+
+    #[inline]
+    pub fn read_raw_bytes(&mut self, bytes: usize) -> &'a [u8] {
+        let start = self.position;
+        self.position += bytes;
+        &self.data[start..self.position]
+    }
 }
 
 macro_rules! read_leb128 {
@@ -659,22 +667,10 @@ impl<'a> serialize::Decoder for Decoder<'a> {
     }
 
     #[inline]
-    fn read_raw_bytes(&mut self, s: &mut [MaybeUninit<u8>]) -> Result<(), String> {
+    fn read_raw_bytes_into(&mut self, s: &mut [u8]) -> Result<(), String> {
         let start = self.position;
-        let end = start + s.len();
-        assert!(end <= self.data.len());
-
-        // SAFETY: Both `src` and `dst` point to at least `s.len()` elements:
-        // `src` points to at least `s.len()` elements by above assert, and
-        // `dst` points to `s.len()` elements by derivation from `s`.
-        unsafe {
-            let src = self.data.as_ptr().add(start);
-            let dst = s.as_mut_ptr() as *mut u8;
-            ptr::copy_nonoverlapping(src, dst, s.len());
-        }
-
-        self.position = end;
-
+        self.position += s.len();
+        s.copy_from_slice(&self.data[start..self.position]);
         Ok(())
     }
 }
@@ -705,16 +701,7 @@ impl serialize::Encodable<FileEncoder> for [u8] {
 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)?;
-
-        let mut v = Vec::with_capacity(len);
-        let buf = &mut v.spare_capacity_mut()[..len];
-        d.read_raw_bytes(buf)?;
-
-        unsafe {
-            v.set_len(len);
-        }
-
-        Ok(v)
+        Ok(d.read_raw_bytes(len).to_owned())
     }
 }
 
@@ -750,13 +737,12 @@ impl serialize::Encodable<FileEncoder> for IntEncodedWithFixedSize {
 impl<'a> serialize::Decodable<Decoder<'a>> for IntEncodedWithFixedSize {
     #[inline]
     fn decode(decoder: &mut Decoder<'a>) -> Result<IntEncodedWithFixedSize, String> {
-        let mut bytes = MaybeUninit::uninit_array();
         let _start_pos = decoder.position();
-        decoder.read_raw_bytes(&mut bytes)?;
+        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(unsafe { MaybeUninit::array_assume_init(bytes) });
+        let value = u64::from_le_bytes(bytes.try_into().unwrap());
         Ok(IntEncodedWithFixedSize(value))
     }
 }
diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs
index a3b02b7c34a..d3e5f306970 100644
--- a/compiler/rustc_serialize/src/serialize.rs
+++ b/compiler/rustc_serialize/src/serialize.rs
@@ -7,7 +7,6 @@ Core encoding and decoding interfaces.
 use std::borrow::Cow;
 use std::cell::{Cell, RefCell};
 use std::marker::PhantomData;
-use std::mem::MaybeUninit;
 use std::path;
 use std::rc::Rc;
 use std::sync::Arc;
@@ -226,7 +225,7 @@ pub trait Decoder {
     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(&mut self, s: &mut [MaybeUninit<u8>]) -> Result<(), Self::Error>;
+    fn read_raw_bytes_into(&mut self, s: &mut [u8]) -> Result<(), Self::Error>;
 
     // Compound types:
     #[inline]