diff options
| author | bors <bors@rust-lang.org> | 2021-03-26 01:28:59 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-03-26 01:28:59 +0000 |
| commit | 0ced530534de1a77504b6229e6303d37a12282ee (patch) | |
| tree | 57f7a07189e5b8761db60756feb05de6d1be9537 /compiler/rustc_serialize/src | |
| parent | 3debe9acb8df363e0b5363f23f8218c2d7919904 (diff) | |
| parent | 517d5ac230ab11ba5e8810dacc5878065fcdd08e (diff) | |
| download | rust-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.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_serialize/src/opaque.rs | 44 | ||||
| -rw-r--r-- | compiler/rustc_serialize/src/serialize.rs | 3 |
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] |
