From 22ec5f4af7b5a85ad375d672ed727571b49f3cad Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Fri, 24 Jul 2015 03:04:55 +0200 Subject: Replace many uses of `mem::transmute` with more specific functions The replacements are functions that usually use a single `mem::transmute` in their body and restrict input and output via more concrete types than `T` and `U`. Worth noting are the `transmute` functions for slices and the `from_utf8*` family for mutable slices. Additionally, `mem::transmute` was often used for casting raw pointers, when you can already cast raw pointers just fine with `as`. --- src/libstd/ascii.rs | 5 ++--- src/libstd/error.rs | 4 ++-- src/libstd/ffi/c_str.rs | 2 +- src/libstd/ffi/os_str.rs | 10 +++++++--- src/libstd/lib.rs | 2 ++ src/libstd/path.rs | 8 ++++---- src/libstd/rand/reader.rs | 4 ++-- src/libstd/sync/mpsc/select.rs | 5 ++--- src/libstd/sys/unix/backtrace.rs | 3 +-- 9 files changed, 23 insertions(+), 20 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index cd9dadd1be9..f003948be7b 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -15,7 +15,6 @@ use prelude::v1::*; use ops::Range; -use mem; /// Extension methods for ASCII-subset only operations on owned strings #[unstable(feature = "owned_ascii_ext", @@ -186,12 +185,12 @@ impl AsciiExt for str { } fn make_ascii_uppercase(&mut self) { - let me: &mut [u8] = unsafe { mem::transmute(self) }; + let me: &mut [u8] = unsafe { self.as_bytes_mut() }; me.make_ascii_uppercase() } fn make_ascii_lowercase(&mut self) { - let me: &mut [u8] = unsafe { mem::transmute(self) }; + let me: &mut [u8] = unsafe { self.as_bytes_mut() }; me.make_ascii_lowercase() } } diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 4d08f08bb6e..f0f481d3721 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -192,7 +192,7 @@ impl Error + 'static { let to: TraitObject = transmute(self); // Extract the data pointer - Some(transmute(to.data)) + Some(&*(to.data as *const T)) } } else { None @@ -210,7 +210,7 @@ impl Error + 'static { let to: TraitObject = transmute(self); // Extract the data pointer - Some(transmute(to.data)) + Some(&mut *(to.data as *const T as *mut T)) } } else { None diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 6eb0719d9f6..adbda6ae242 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -395,7 +395,7 @@ impl CStr { /// > length calculation whenever this method is called. #[stable(feature = "rust1", since = "1.0.0")] pub fn to_bytes_with_nul(&self) -> &[u8] { - unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.inner) } + unsafe { slice::transmute(&self.inner) } } /// Yields a `&str` slice if the `CStr` contains valid UTF-8. diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 47b8230e430..83d76481d49 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -134,7 +134,7 @@ impl ops::Index for OsString { #[inline] fn index(&self, _index: ops::RangeFull) -> &OsStr { - unsafe { mem::transmute(self.inner.as_slice()) } + OsStr::from_inner(self.inner.as_slice()) } } @@ -226,6 +226,10 @@ impl OsStr { s.as_ref() } + fn from_inner(inner: &Slice) -> &OsStr { + unsafe { mem::transmute(inner) } + } + /// Yields a `&str` slice if the `OsStr` is valid unicode. /// /// This conversion may entail doing a check for UTF-8 validity. @@ -387,14 +391,14 @@ impl AsRef for OsString { #[stable(feature = "rust1", since = "1.0.0")] impl AsRef for str { fn as_ref(&self) -> &OsStr { - unsafe { mem::transmute(Slice::from_str(self)) } + OsStr::from_inner(Slice::from_str(self)) } } #[stable(feature = "rust1", since = "1.0.0")] impl AsRef for String { fn as_ref(&self) -> &OsStr { - unsafe { mem::transmute(Slice::from_str(self)) } + (&**self).as_ref() } } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 7baa7558e52..65f195be4e8 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -234,7 +234,9 @@ #![feature(reflect_marker)] #![feature(slice_bytes)] #![feature(slice_patterns)] +#![feature(slice_transmute)] #![feature(staged_api)] +#![feature(str_as_bytes_mut)] #![feature(str_char)] #![feature(str_internals)] #![feature(unboxed_closures)] diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 4a4db61c3b9..c3a887cbcb8 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -942,7 +942,7 @@ pub struct PathBuf { impl PathBuf { fn as_mut_vec(&mut self) -> &mut Vec { - unsafe { mem::transmute(self) } + unsafe { &mut *(self as *mut PathBuf as *mut Vec) } } /// Allocates an empty `PathBuf`. @@ -1126,7 +1126,7 @@ impl ops::Deref for PathBuf { type Target = Path; fn deref(&self) -> &Path { - unsafe { mem::transmute(&self.inner[..]) } + Path::new(&self.inner) } } @@ -1227,11 +1227,11 @@ impl Path { // The following (private!) function allows construction of a path from a u8 // slice, which is only safe when it is known to follow the OsStr encoding. unsafe fn from_u8_slice(s: &[u8]) -> &Path { - mem::transmute(s) + Path::new(u8_slice_as_os_str(s)) } // The following (private!) function reveals the byte encoding used for OsStr. fn as_u8_slice(&self) -> &[u8] { - unsafe { mem::transmute(self) } + os_str_as_u8_slice(&self.inner) } /// Directly wrap a string slice as a `Path` slice. diff --git a/src/libstd/rand/reader.rs b/src/libstd/rand/reader.rs index 665f423c3f1..8ac2722f65a 100644 --- a/src/libstd/rand/reader.rs +++ b/src/libstd/rand/reader.rs @@ -73,8 +73,8 @@ mod tests { fn test_reader_rng_u64() { // transmute from the target to avoid endianness concerns. let v = &[0, 0, 0, 0, 0, 0, 0, 1, - 0 , 0, 0, 0, 0, 0, 0, 2, - 0, 0, 0, 0, 0, 0, 0, 3][..]; + 0, 0, 0, 0, 0, 0, 0, 2, + 0, 0, 0, 0, 0, 0, 0, 3][..]; let mut rng = ReaderRng::new(v); assert_eq!(rng.next_u64(), 1u64.to_be()); diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs index 1d31ac165f6..c46e61cf414 100644 --- a/src/libstd/sync/mpsc/select.rs +++ b/src/libstd/sync/mpsc/select.rs @@ -62,7 +62,6 @@ use core::prelude::v1::*; use core::cell::{Cell, UnsafeCell}; use core::marker; -use core::mem; use core::ptr; use core::usize; @@ -281,7 +280,7 @@ impl<'rx, T: Send> Handle<'rx, T> { pub unsafe fn add(&mut self) { if self.added { return } let selector = &mut *self.selector; - let me: *mut Handle<'static, ()> = mem::transmute(&*self); + let me = self as *mut Handle<'rx, T> as *mut Handle<'static, ()>; if selector.head.is_null() { selector.head = me; @@ -302,7 +301,7 @@ impl<'rx, T: Send> Handle<'rx, T> { if !self.added { return } let selector = &mut *self.selector; - let me: *mut Handle<'static, ()> = mem::transmute(&*self); + let me = self as *mut Handle<'rx, T> as *mut Handle<'static, ()>; if self.prev.is_null() { assert_eq!(selector.head, me); diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs index ae8bfb07aaf..4128431ee64 100644 --- a/src/libstd/sys/unix/backtrace.rs +++ b/src/libstd/sys/unix/backtrace.rs @@ -90,7 +90,6 @@ use io::prelude::*; use ffi::CStr; use io; use libc; -use mem; use str; use sync::StaticMutex; @@ -168,7 +167,7 @@ pub fn write(w: &mut Write) -> io::Result<()> { extern fn trace_fn(ctx: *mut uw::_Unwind_Context, arg: *mut libc::c_void) -> uw::_Unwind_Reason_Code { - let cx: &mut Context = unsafe { mem::transmute(arg) }; + let cx: &mut Context = unsafe { &mut *(arg as *mut Context) }; let mut ip_before_insn = 0; let mut ip = unsafe { uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void -- cgit 1.4.1-3-g733a5 From 47041fe28920326807b29c1246ca9712e184f885 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Fri, 24 Jul 2015 21:02:05 +0200 Subject: Make `slice::transmute*` private --- src/libcollections/slice.rs | 1 - src/libcore/slice.rs | 6 ++--- src/librustc_trans/lib.rs | 1 - src/librustc_trans/trans/type_.rs | 53 ++++++++------------------------------- src/libstd/ffi/c_str.rs | 2 +- src/libstd/lib.rs | 1 - 6 files changed, 14 insertions(+), 50 deletions(-) (limited to 'src/libstd') diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index b681f7a6341..5ccf3973c28 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -109,7 +109,6 @@ pub use core::slice::{IntSliceExt, SplitMut, ChunksMut, Split}; pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut}; pub use core::slice::{bytes, mut_ref_slice, ref_slice}; pub use core::slice::{from_raw_parts, from_raw_parts_mut}; -pub use core::slice::{transmute, transmute_mut}; //////////////////////////////////////////////////////////////////////////////// // Basic slice extension methods diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 9120da78d25..aa34b651157 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -1455,8 +1455,7 @@ fn check_types() { /// This functions panics if the above preconditions about the types are not /// met. #[inline] -#[unstable(feature = "slice_transmute", reason = "recent API addition")] -pub unsafe fn transmute(slice: &[T]) -> &[U] { +unsafe fn transmute(slice: &[T]) -> &[U] { check_types::(); from_raw_parts(slice.as_ptr() as *const U, slice.len()) } @@ -1466,8 +1465,7 @@ pub unsafe fn transmute(slice: &[T]) -> &[U] { /// /// Equivalent of `slice::transmute` for mutable slices. #[inline] -#[unstable(feature = "slice_transmute", reason = "recent API addition")] -pub unsafe fn transmute_mut(slice: &mut [T]) -> &mut [U] { +unsafe fn transmute_mut(slice: &mut [T]) -> &mut [U] { check_types::(); from_raw_parts_mut(slice.as_mut_ptr() as *mut U, slice.len()) } diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 24f4713cad2..af894b218ef 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -25,7 +25,6 @@ html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] -#![cfg_attr(not(stage0), feature(slice_transmute))] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(const_fn)] diff --git a/src/librustc_trans/trans/type_.rs b/src/librustc_trans/trans/type_.rs index 530b1a8ebc0..bf7c471cd42 100644 --- a/src/librustc_trans/trans/type_.rs +++ b/src/librustc_trans/trans/type_.rs @@ -59,6 +59,10 @@ impl Type { }).expect("non-UTF8 type description from LLVM") } + pub fn to_ref_slice(slice: &[Type]) -> &[TypeRef] { + unsafe { mem::transmute(slice) } + } + pub fn void(ccx: &CrateContext) -> Type { ty!(llvm::LLVMVoidTypeInContext(ccx.llcx())) } @@ -151,45 +155,20 @@ impl Type { } } - #[cfg(stage0)] - pub fn func(args: &[Type], ret: &Type) -> Type { - let vec : &[TypeRef] = unsafe { mem::transmute(args) }; - ty!(llvm::LLVMFunctionType(ret.to_ref(), vec.as_ptr(), - args.len() as c_uint, False)) - } - - #[cfg(not(stage0))] pub fn func(args: &[Type], ret: &Type) -> Type { - let vec: &[TypeRef] = unsafe { slice::transmute(args) }; - ty!(llvm::LLVMFunctionType(ret.to_ref(), vec.as_ptr(), + let slice: &[TypeRef] = Type::to_ref_slice(args); + ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(), args.len() as c_uint, False)) } - #[cfg(stage0)] pub fn variadic_func(args: &[Type], ret: &Type) -> Type { - let vec : &[TypeRef] = unsafe { mem::transmute(args) }; - ty!(llvm::LLVMFunctionType(ret.to_ref(), vec.as_ptr(), + let slice: &[TypeRef] = Type::to_ref_slice(args); + ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(), args.len() as c_uint, True)) } - #[cfg(not(stage0))] - pub fn variadic_func(args: &[Type], ret: &Type) -> Type { - let vec: &[TypeRef] = unsafe { slice::transmute(args) }; - ty!(llvm::LLVMFunctionType(ret.to_ref(), vec.as_ptr(), - args.len() as c_uint, True)) - } - - #[cfg(stage0)] - pub fn struct_(ccx: &CrateContext, els: &[Type], packed: bool) -> Type { - let els : &[TypeRef] = unsafe { mem::transmute(els) }; - ty!(llvm::LLVMStructTypeInContext(ccx.llcx(), els.as_ptr(), - els.len() as c_uint, - packed as Bool)) - } - - #[cfg(not(stage0))] pub fn struct_(ccx: &CrateContext, els: &[Type], packed: bool) -> Type { - let els : &[TypeRef] = unsafe { slice::transmute(els) }; + let els: &[TypeRef] = Type::to_ref_slice(els); ty!(llvm::LLVMStructTypeInContext(ccx.llcx(), els.as_ptr(), els.len() as c_uint, packed as Bool)) @@ -236,20 +215,10 @@ impl Type { } } - #[cfg(stage0)] - pub fn set_struct_body(&mut self, els: &[Type], packed: bool) { - unsafe { - let vec : &[TypeRef] = mem::transmute(els); - llvm::LLVMStructSetBody(self.to_ref(), vec.as_ptr(), - els.len() as c_uint, packed as Bool) - } - } - - #[cfg(not(stage0))] pub fn set_struct_body(&mut self, els: &[Type], packed: bool) { + let slice: &[TypeRef] = Type::to_ref_slice(els); unsafe { - let vec: &[TypeRef] = slice::transmute(els); - llvm::LLVMStructSetBody(self.to_ref(), vec.as_ptr(), + llvm::LLVMStructSetBody(self.to_ref(), slice.as_ptr(), els.len() as c_uint, packed as Bool) } } diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index adbda6ae242..3e503074ab4 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -395,7 +395,7 @@ impl CStr { /// > length calculation whenever this method is called. #[stable(feature = "rust1", since = "1.0.0")] pub fn to_bytes_with_nul(&self) -> &[u8] { - unsafe { slice::transmute(&self.inner) } + unsafe { mem::transmute(&self.inner) } } /// Yields a `&str` slice if the `CStr` contains valid UTF-8. diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 65f195be4e8..b4bbb3f25f7 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -234,7 +234,6 @@ #![feature(reflect_marker)] #![feature(slice_bytes)] #![feature(slice_patterns)] -#![feature(slice_transmute)] #![feature(staged_api)] #![feature(str_as_bytes_mut)] #![feature(str_char)] -- cgit 1.4.1-3-g733a5 From 5309fbb6c91b8667a016647484ab2ab73d8bf0dd Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Fri, 24 Jul 2015 22:10:12 +0200 Subject: Make `str::as_bytes_mut` private --- src/libcollections/str.rs | 13 ------------- src/libcore/str/mod.rs | 6 ------ src/libstd/ascii.rs | 5 +++-- src/libstd/lib.rs | 1 - 4 files changed, 3 insertions(+), 22 deletions(-) (limited to 'src/libstd') diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index d359d7548f3..2d56e6e3c41 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -479,19 +479,6 @@ impl str { core_str::StrExt::as_bytes(self) } - /// Converts `self` to a mutable byte slice. - /// - /// # Unsafety - /// - /// The `str` type guarantees that its contents are UTF-8 bytes, which can - /// be violated using this function, leading to memory-unsafeties in other - /// string functions. - #[unstable(feature = "str_as_bytes_mut")] - #[inline(always)] - pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] { - core_str::StrExt::as_bytes_mut(self) - } - /// Returns a raw pointer to the `&str`'s buffer. /// /// The caller must ensure that the string outlives this pointer, and diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 202fc90b40d..3c9338c2cd2 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1264,7 +1264,6 @@ pub trait StrExt { fn char_at(&self, i: usize) -> char; fn char_at_reverse(&self, i: usize) -> char; fn as_bytes<'a>(&'a self) -> &'a [u8]; - unsafe fn as_bytes_mut<'a>(&'a mut self) -> &'a mut [u8]; fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option; fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option where P::Searcher: ReverseSearcher<'a>; @@ -1557,11 +1556,6 @@ impl StrExt for str { unsafe { mem::transmute(self) } } - #[inline] - unsafe fn as_bytes_mut(&mut self) -> &mut [u8] { - mem::transmute(self) - } - fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option { pat.into_searcher(self).next_match().map(|(i, _)| i) } diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index f003948be7b..ded572e82ff 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -14,6 +14,7 @@ use prelude::v1::*; +use mem; use ops::Range; /// Extension methods for ASCII-subset only operations on owned strings @@ -185,12 +186,12 @@ impl AsciiExt for str { } fn make_ascii_uppercase(&mut self) { - let me: &mut [u8] = unsafe { self.as_bytes_mut() }; + let me: &mut [u8] = unsafe { mem::transmute(self) }; me.make_ascii_uppercase() } fn make_ascii_lowercase(&mut self) { - let me: &mut [u8] = unsafe { self.as_bytes_mut() }; + let me: &mut [u8] = unsafe { mem::transmute(self) }; me.make_ascii_lowercase() } } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index b4bbb3f25f7..7baa7558e52 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -235,7 +235,6 @@ #![feature(slice_bytes)] #![feature(slice_patterns)] #![feature(staged_api)] -#![feature(str_as_bytes_mut)] #![feature(str_char)] #![feature(str_internals)] #![feature(unboxed_closures)] -- cgit 1.4.1-3-g733a5