提交 417ffc98 编写于 作者: B bors

Auto merge of #44890 - nvzqz:str-box-transmute, r=alexcrichton

Remove mem::transmute used in Box<str> conversions

Given that https://github.com/rust-lang/rust/pull/44877 is failing, I decided to make a separate PR. This is done with the same motivation: to avoid `mem::transmute`-ing non `#[repr(C)]` types.
......@@ -528,9 +528,7 @@ fn from(s: &'a str) -> Box<str> {
#[stable(feature = "boxed_str_conv", since = "1.19.0")]
impl From<Box<str>> for Box<[u8]> {
fn from(s: Box<str>) -> Self {
unsafe {
mem::transmute(s)
}
unsafe { Box::from_raw(Box::into_raw(s) as *mut [u8]) }
}
}
......
......@@ -2047,10 +2047,8 @@ pub fn escape_unicode(&self) -> String {
/// ```
#[stable(feature = "box_str", since = "1.4.0")]
pub fn into_string(self: Box<str>) -> String {
unsafe {
let slice = mem::transmute::<Box<str>, Box<[u8]>>(self);
String::from_utf8_unchecked(slice.into_vec())
}
let slice = Box::<[u8]>::from(self);
unsafe { String::from_utf8_unchecked(slice.into_vec()) }
}
/// Create a [`String`] by repeating a string `n` times.
......@@ -2087,5 +2085,5 @@ pub fn repeat(&self, n: usize) -> String {
/// ```
#[stable(feature = "str_box_extras", since = "1.20.0")]
pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box<str> {
mem::transmute(v)
Box::from_raw(Box::into_raw(v) as *mut str)
}
......@@ -311,8 +311,8 @@ pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
#[stable(feature = "cstr_memory", since = "1.4.0")]
pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
let len = libc::strlen(ptr) + 1; // Including the NUL byte
let slice = slice::from_raw_parts(ptr, len as usize);
CString { inner: mem::transmute(slice) }
let slice = slice::from_raw_parts_mut(ptr, len as usize);
CString { inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]) }
}
/// Transfers ownership of the string to a C caller.
......@@ -480,7 +480,7 @@ pub fn as_c_str(&self) -> &CStr {
/// ```
#[stable(feature = "into_boxed_c_str", since = "1.20.0")]
pub fn into_boxed_c_str(self) -> Box<CStr> {
unsafe { mem::transmute(self.into_inner()) }
unsafe { Box::from_raw(Box::into_raw(self.into_inner()) as *mut CStr) }
}
// Bypass "move out of struct which implements [`Drop`] trait" restriction.
......@@ -569,7 +569,7 @@ fn borrow(&self) -> &CStr { self }
impl<'a> From<&'a CStr> for Box<CStr> {
fn from(s: &'a CStr) -> Box<CStr> {
let boxed: Box<[u8]> = Box::from(s.to_bytes_with_nul());
unsafe { mem::transmute(boxed) }
unsafe { Box::from_raw(Box::into_raw(boxed) as *mut CStr) }
}
}
......@@ -593,7 +593,7 @@ fn from(s: CString) -> Box<CStr> {
impl Default for Box<CStr> {
fn default() -> Box<CStr> {
let boxed: Box<[u8]> = Box::from([0]);
unsafe { mem::transmute(boxed) }
unsafe { Box::from_raw(Box::into_raw(boxed) as *mut CStr) }
}
}
......@@ -817,7 +817,7 @@ pub fn from_bytes_with_nul(bytes: &[u8])
#[inline]
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
pub unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
mem::transmute(bytes)
&*(bytes as *const [u8] as *const CStr)
}
/// Returns the inner pointer to this C string.
......@@ -913,7 +913,7 @@ pub fn to_bytes(&self) -> &[u8] {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn to_bytes_with_nul(&self) -> &[u8] {
unsafe { mem::transmute(&self.inner) }
unsafe { &*(&self.inner as *const [c_char] as *const [u8]) }
}
/// Yields a [`&str`] slice if the `CStr` contains valid UTF-8.
......@@ -1005,7 +1005,8 @@ pub fn to_string_lossy(&self) -> Cow<str> {
/// ```
#[stable(feature = "into_boxed_c_str", since = "1.20.0")]
pub fn into_c_string(self: Box<CStr>) -> CString {
unsafe { mem::transmute(self) }
let raw = Box::into_raw(self) as *mut [u8];
CString { inner: unsafe { Box::from_raw(raw) } }
}
}
......
......@@ -10,7 +10,6 @@
use borrow::{Borrow, Cow};
use fmt;
use mem;
use ops;
use cmp;
use hash::{Hash, Hasher};
......@@ -260,7 +259,8 @@ pub fn shrink_to_fit(&mut self) {
/// ```
#[stable(feature = "into_boxed_os_str", since = "1.20.0")]
pub fn into_boxed_os_str(self) -> Box<OsStr> {
unsafe { mem::transmute(self.inner.into_box()) }
let rw = Box::into_raw(self.inner.into_box()) as *mut OsStr;
unsafe { Box::from_raw(rw) }
}
}
......@@ -394,7 +394,7 @@ pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
}
fn from_inner(inner: &Slice) -> &OsStr {
unsafe { mem::transmute(inner) }
unsafe { &*(inner as *const Slice as *const OsStr) }
}
/// Yields a [`&str`] slice if the `OsStr` is valid Unicode.
......@@ -511,8 +511,8 @@ pub fn len(&self) -> usize {
/// [`OsString`]: struct.OsString.html
#[stable(feature = "into_boxed_os_str", since = "1.20.0")]
pub fn into_os_string(self: Box<OsStr>) -> OsString {
let inner: Box<Slice> = unsafe { mem::transmute(self) };
OsString { inner: Buf::from_box(inner) }
let boxed = unsafe { Box::from_raw(Box::into_raw(self) as *mut Slice) };
OsString { inner: Buf::from_box(boxed) }
}
/// Gets the underlying byte representation.
......@@ -520,14 +520,15 @@ pub fn into_os_string(self: Box<OsStr>) -> OsString {
/// Note: it is *crucial* that this API is private, to avoid
/// revealing the internal, platform-specific encodings.
fn bytes(&self) -> &[u8] {
unsafe { mem::transmute(&self.inner) }
unsafe { &*(&self.inner as *const _ as *const [u8]) }
}
}
#[stable(feature = "box_from_os_str", since = "1.17.0")]
impl<'a> From<&'a OsStr> for Box<OsStr> {
fn from(s: &'a OsStr) -> Box<OsStr> {
unsafe { mem::transmute(s.inner.into_box()) }
let rw = Box::into_raw(s.inner.into_box()) as *mut OsStr;
unsafe { Box::from_raw(rw) }
}
}
......@@ -548,7 +549,8 @@ fn from(s: OsString) -> Box<OsStr> {
#[stable(feature = "box_default_extra", since = "1.17.0")]
impl Default for Box<OsStr> {
fn default() -> Box<OsStr> {
unsafe { mem::transmute(Slice::empty_box()) }
let rw = Box::into_raw(Slice::empty_box()) as *mut OsStr;
unsafe { Box::from_raw(rw) }
}
}
......
......@@ -86,7 +86,6 @@
use hash::{Hash, Hasher};
use io;
use iter::{self, FusedIterator};
use mem;
use ops::{self, Deref};
use ffi::{OsStr, OsString};
......@@ -317,10 +316,10 @@ fn iter_after<A, I, J>(mut iter: I, mut prefix: J) -> Option<I>
// See note at the top of this module to understand why these are used:
fn os_str_as_u8_slice(s: &OsStr) -> &[u8] {
unsafe { mem::transmute(s) }
unsafe { &*(s as *const OsStr as *const [u8]) }
}
unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr {
mem::transmute(s)
&*(s as *const [u8] as *const OsStr)
}
// Detect scheme on Redox
......@@ -1334,7 +1333,8 @@ pub fn into_os_string(self) -> OsString {
/// [`Path`]: struct.Path.html
#[stable(feature = "into_boxed_path", since = "1.20.0")]
pub fn into_boxed_path(self) -> Box<Path> {
unsafe { mem::transmute(self.inner.into_boxed_os_str()) }
let rw = Box::into_raw(self.inner.into_boxed_os_str()) as *mut Path;
unsafe { Box::from_raw(rw) }
}
}
......@@ -1342,7 +1342,8 @@ pub fn into_boxed_path(self) -> Box<Path> {
impl<'a> From<&'a Path> for Box<Path> {
fn from(path: &'a Path) -> Box<Path> {
let boxed: Box<OsStr> = path.inner.into();
unsafe { mem::transmute(boxed) }
let rw = Box::into_raw(boxed) as *mut Path;
unsafe { Box::from_raw(rw) }
}
}
......@@ -1589,7 +1590,7 @@ fn as_u8_slice(&self) -> &[u8] {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &Path {
unsafe { mem::transmute(s.as_ref()) }
unsafe { &*(s.as_ref() as *const OsStr as *const Path) }
}
/// Yields the underlying [`OsStr`] slice.
......@@ -2312,7 +2313,8 @@ pub fn is_dir(&self) -> bool {
/// [`PathBuf`]: struct.PathBuf.html
#[stable(feature = "into_boxed_path", since = "1.20.0")]
pub fn into_path_buf(self: Box<Path>) -> PathBuf {
let inner: Box<OsStr> = unsafe { mem::transmute(self) };
let rw = Box::into_raw(self) as *mut OsStr;
let inner = unsafe { Box::from_raw(rw) };
PathBuf { inner: OsString::from(inner) }
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册