Skip to content

Commit 417ffc9

Browse files
committed
Auto merge of #44890 - nvzqz:str-box-transmute, r=alexcrichton
Remove mem::transmute used in Box<str> conversions Given that #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.
2 parents fd8099f + f1798d3 commit 417ffc9

File tree

5 files changed

+32
-31
lines changed

5 files changed

+32
-31
lines changed

src/liballoc/boxed.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -528,9 +528,7 @@ impl<'a> From<&'a str> for Box<str> {
528528
#[stable(feature = "boxed_str_conv", since = "1.19.0")]
529529
impl From<Box<str>> for Box<[u8]> {
530530
fn from(s: Box<str>) -> Self {
531-
unsafe {
532-
mem::transmute(s)
533-
}
531+
unsafe { Box::from_raw(Box::into_raw(s) as *mut [u8]) }
534532
}
535533
}
536534

src/liballoc/str.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -2047,10 +2047,8 @@ impl str {
20472047
/// ```
20482048
#[stable(feature = "box_str", since = "1.4.0")]
20492049
pub fn into_string(self: Box<str>) -> String {
2050-
unsafe {
2051-
let slice = mem::transmute::<Box<str>, Box<[u8]>>(self);
2052-
String::from_utf8_unchecked(slice.into_vec())
2053-
}
2050+
let slice = Box::<[u8]>::from(self);
2051+
unsafe { String::from_utf8_unchecked(slice.into_vec()) }
20542052
}
20552053

20562054
/// Create a [`String`] by repeating a string `n` times.
@@ -2087,5 +2085,5 @@ impl str {
20872085
/// ```
20882086
#[stable(feature = "str_box_extras", since = "1.20.0")]
20892087
pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box<str> {
2090-
mem::transmute(v)
2088+
Box::from_raw(Box::into_raw(v) as *mut str)
20912089
}

src/libstd/ffi/c_str.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,8 @@ impl CString {
311311
#[stable(feature = "cstr_memory", since = "1.4.0")]
312312
pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
313313
let len = libc::strlen(ptr) + 1; // Including the NUL byte
314-
let slice = slice::from_raw_parts(ptr, len as usize);
315-
CString { inner: mem::transmute(slice) }
314+
let slice = slice::from_raw_parts_mut(ptr, len as usize);
315+
CString { inner: Box::from_raw(slice as *mut [c_char] as *mut [u8]) }
316316
}
317317

318318
/// Transfers ownership of the string to a C caller.
@@ -480,7 +480,7 @@ impl CString {
480480
/// ```
481481
#[stable(feature = "into_boxed_c_str", since = "1.20.0")]
482482
pub fn into_boxed_c_str(self) -> Box<CStr> {
483-
unsafe { mem::transmute(self.into_inner()) }
483+
unsafe { Box::from_raw(Box::into_raw(self.into_inner()) as *mut CStr) }
484484
}
485485

486486
// Bypass "move out of struct which implements [`Drop`] trait" restriction.
@@ -569,7 +569,7 @@ impl Borrow<CStr> for CString {
569569
impl<'a> From<&'a CStr> for Box<CStr> {
570570
fn from(s: &'a CStr) -> Box<CStr> {
571571
let boxed: Box<[u8]> = Box::from(s.to_bytes_with_nul());
572-
unsafe { mem::transmute(boxed) }
572+
unsafe { Box::from_raw(Box::into_raw(boxed) as *mut CStr) }
573573
}
574574
}
575575

@@ -593,7 +593,7 @@ impl From<CString> for Box<CStr> {
593593
impl Default for Box<CStr> {
594594
fn default() -> Box<CStr> {
595595
let boxed: Box<[u8]> = Box::from([0]);
596-
unsafe { mem::transmute(boxed) }
596+
unsafe { Box::from_raw(Box::into_raw(boxed) as *mut CStr) }
597597
}
598598
}
599599

@@ -817,7 +817,7 @@ impl CStr {
817817
#[inline]
818818
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
819819
pub unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
820-
mem::transmute(bytes)
820+
&*(bytes as *const [u8] as *const CStr)
821821
}
822822

823823
/// Returns the inner pointer to this C string.
@@ -913,7 +913,7 @@ impl CStr {
913913
#[inline]
914914
#[stable(feature = "rust1", since = "1.0.0")]
915915
pub fn to_bytes_with_nul(&self) -> &[u8] {
916-
unsafe { mem::transmute(&self.inner) }
916+
unsafe { &*(&self.inner as *const [c_char] as *const [u8]) }
917917
}
918918

919919
/// Yields a [`&str`] slice if the `CStr` contains valid UTF-8.
@@ -1005,7 +1005,8 @@ impl CStr {
10051005
/// ```
10061006
#[stable(feature = "into_boxed_c_str", since = "1.20.0")]
10071007
pub fn into_c_string(self: Box<CStr>) -> CString {
1008-
unsafe { mem::transmute(self) }
1008+
let raw = Box::into_raw(self) as *mut [u8];
1009+
CString { inner: unsafe { Box::from_raw(raw) } }
10091010
}
10101011
}
10111012

src/libstd/ffi/os_str.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
use borrow::{Borrow, Cow};
1212
use fmt;
13-
use mem;
1413
use ops;
1514
use cmp;
1615
use hash::{Hash, Hasher};
@@ -260,7 +259,8 @@ impl OsString {
260259
/// ```
261260
#[stable(feature = "into_boxed_os_str", since = "1.20.0")]
262261
pub fn into_boxed_os_str(self) -> Box<OsStr> {
263-
unsafe { mem::transmute(self.inner.into_box()) }
262+
let rw = Box::into_raw(self.inner.into_box()) as *mut OsStr;
263+
unsafe { Box::from_raw(rw) }
264264
}
265265
}
266266

@@ -394,7 +394,7 @@ impl OsStr {
394394
}
395395

396396
fn from_inner(inner: &Slice) -> &OsStr {
397-
unsafe { mem::transmute(inner) }
397+
unsafe { &*(inner as *const Slice as *const OsStr) }
398398
}
399399

400400
/// Yields a [`&str`] slice if the `OsStr` is valid Unicode.
@@ -511,23 +511,24 @@ impl OsStr {
511511
/// [`OsString`]: struct.OsString.html
512512
#[stable(feature = "into_boxed_os_str", since = "1.20.0")]
513513
pub fn into_os_string(self: Box<OsStr>) -> OsString {
514-
let inner: Box<Slice> = unsafe { mem::transmute(self) };
515-
OsString { inner: Buf::from_box(inner) }
514+
let boxed = unsafe { Box::from_raw(Box::into_raw(self) as *mut Slice) };
515+
OsString { inner: Buf::from_box(boxed) }
516516
}
517517

518518
/// Gets the underlying byte representation.
519519
///
520520
/// Note: it is *crucial* that this API is private, to avoid
521521
/// revealing the internal, platform-specific encodings.
522522
fn bytes(&self) -> &[u8] {
523-
unsafe { mem::transmute(&self.inner) }
523+
unsafe { &*(&self.inner as *const _ as *const [u8]) }
524524
}
525525
}
526526

527527
#[stable(feature = "box_from_os_str", since = "1.17.0")]
528528
impl<'a> From<&'a OsStr> for Box<OsStr> {
529529
fn from(s: &'a OsStr) -> Box<OsStr> {
530-
unsafe { mem::transmute(s.inner.into_box()) }
530+
let rw = Box::into_raw(s.inner.into_box()) as *mut OsStr;
531+
unsafe { Box::from_raw(rw) }
531532
}
532533
}
533534

@@ -548,7 +549,8 @@ impl From<OsString> for Box<OsStr> {
548549
#[stable(feature = "box_default_extra", since = "1.17.0")]
549550
impl Default for Box<OsStr> {
550551
fn default() -> Box<OsStr> {
551-
unsafe { mem::transmute(Slice::empty_box()) }
552+
let rw = Box::into_raw(Slice::empty_box()) as *mut OsStr;
553+
unsafe { Box::from_raw(rw) }
552554
}
553555
}
554556

src/libstd/path.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ use fs;
8686
use hash::{Hash, Hasher};
8787
use io;
8888
use iter::{self, FusedIterator};
89-
use mem;
9089
use ops::{self, Deref};
9190

9291
use ffi::{OsStr, OsString};
@@ -317,10 +316,10 @@ fn iter_after<A, I, J>(mut iter: I, mut prefix: J) -> Option<I>
317316

318317
// See note at the top of this module to understand why these are used:
319318
fn os_str_as_u8_slice(s: &OsStr) -> &[u8] {
320-
unsafe { mem::transmute(s) }
319+
unsafe { &*(s as *const OsStr as *const [u8]) }
321320
}
322321
unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr {
323-
mem::transmute(s)
322+
&*(s as *const [u8] as *const OsStr)
324323
}
325324

326325
// Detect scheme on Redox
@@ -1334,15 +1333,17 @@ impl PathBuf {
13341333
/// [`Path`]: struct.Path.html
13351334
#[stable(feature = "into_boxed_path", since = "1.20.0")]
13361335
pub fn into_boxed_path(self) -> Box<Path> {
1337-
unsafe { mem::transmute(self.inner.into_boxed_os_str()) }
1336+
let rw = Box::into_raw(self.inner.into_boxed_os_str()) as *mut Path;
1337+
unsafe { Box::from_raw(rw) }
13381338
}
13391339
}
13401340

13411341
#[stable(feature = "box_from_path", since = "1.17.0")]
13421342
impl<'a> From<&'a Path> for Box<Path> {
13431343
fn from(path: &'a Path) -> Box<Path> {
13441344
let boxed: Box<OsStr> = path.inner.into();
1345-
unsafe { mem::transmute(boxed) }
1345+
let rw = Box::into_raw(boxed) as *mut Path;
1346+
unsafe { Box::from_raw(rw) }
13461347
}
13471348
}
13481349

@@ -1589,7 +1590,7 @@ impl Path {
15891590
/// ```
15901591
#[stable(feature = "rust1", since = "1.0.0")]
15911592
pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &Path {
1592-
unsafe { mem::transmute(s.as_ref()) }
1593+
unsafe { &*(s.as_ref() as *const OsStr as *const Path) }
15931594
}
15941595

15951596
/// Yields the underlying [`OsStr`] slice.
@@ -2312,7 +2313,8 @@ impl Path {
23122313
/// [`PathBuf`]: struct.PathBuf.html
23132314
#[stable(feature = "into_boxed_path", since = "1.20.0")]
23142315
pub fn into_path_buf(self: Box<Path>) -> PathBuf {
2315-
let inner: Box<OsStr> = unsafe { mem::transmute(self) };
2316+
let rw = Box::into_raw(self) as *mut OsStr;
2317+
let inner = unsafe { Box::from_raw(rw) };
23162318
PathBuf { inner: OsString::from(inner) }
23172319
}
23182320
}

0 commit comments

Comments
 (0)