diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 1e59239701422..56c7324090e4c 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -193,7 +193,7 @@ impl Arc { weak: atomic::AtomicUsize::new(1), data: data, }; - Arc { _ptr: unsafe { NonZero::new(mem::transmute(x)) } } + Arc { _ptr: unsafe { NonZero::new(Box::into_raw(x)) } } } } diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 4d064b16ad027..54df3b35bdb8f 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -152,7 +152,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) { let fill = chunk.fill.get(); while idx < fill { - let tydesc_data: *const usize = mem::transmute(buf.offset(idx as isize)); + let tydesc_data = buf.offset(idx as isize) as *const usize; let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data); let (size, align) = ((*tydesc).size, (*tydesc).align); @@ -305,7 +305,7 @@ impl<'longer_than_self> Arena<'longer_than_self> { let ptr = ptr as *mut T; // Write in our tydesc along with a bit indicating that it // has *not* been initialized yet. - *ty_ptr = mem::transmute(tydesc); + *ty_ptr = bitpack_tydesc_ptr(tydesc, false); // Actually initialize it ptr::write(&mut(*ptr), op()); // Now that we are done, update the tydesc to indicate that @@ -443,8 +443,7 @@ impl TypedArenaChunk { fn start(&self) -> *const u8 { let this: *const TypedArenaChunk = self; unsafe { - mem::transmute(round_up(this.offset(1) as usize, - mem::align_of::())) + round_up(this.offset(1) as usize, mem::align_of::()) as *const u8 } } @@ -488,7 +487,7 @@ impl TypedArena { } let ptr: &mut T = unsafe { - let ptr: &mut T = mem::transmute(self.ptr.clone()); + let ptr: &mut T = &mut *(self.ptr.get() as *mut T); ptr::write(ptr, object); self.ptr.set(self.ptr.get().offset(1)); ptr diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index 9f2e1db42c938..e0018efe9e0dd 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -25,7 +25,7 @@ use core::iter::Zip; use core::marker::PhantomData; use core::ops::{Deref, DerefMut, Index, IndexMut}; use core::ptr::Unique; -use core::{slice, mem, ptr, cmp, raw}; +use core::{slice, mem, ptr, cmp}; use alloc::heap::{self, EMPTY}; use borrow::Borrow; @@ -357,7 +357,10 @@ impl Node { #[inline] pub fn as_slices_mut<'a>(&'a mut self) -> (&'a mut [K], &'a mut [V]) { - unsafe { mem::transmute(self.as_slices()) } + unsafe {( + slice::from_raw_parts_mut(*self.keys, self.len()), + slice::from_raw_parts_mut(*self.vals, self.len()), + )} } #[inline] @@ -372,10 +375,7 @@ impl Node { None => heap::EMPTY as *const Node, Some(ref p) => **p as *const Node, }; - mem::transmute(raw::Slice { - data: data, - len: self.len() + 1 - }) + slice::from_raw_parts(data, self.len() + 1) } }; NodeSlice { @@ -390,6 +390,7 @@ impl Node { #[inline] pub fn as_slices_internal_mut<'b>(&'b mut self) -> MutNodeSlice<'b, K, V> { + // FIXME(#27620): Bad: This relies on structure layout! unsafe { mem::transmute(self.as_slices_internal()) } } diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 5fb28d67974e3..3be5f32d6c2d5 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -47,7 +47,6 @@ #![feature(oom)] #![feature(pattern)] #![feature(ptr_as_ref)] -#![feature(raw)] #![feature(slice_patterns)] #![feature(staged_api)] #![feature(step_by)] diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 670d99bae4049..2d56e6e3c417a 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -504,8 +504,7 @@ impl str { /// # Unsafety /// /// Caller must check both UTF-8 sequence boundaries and the boundaries - /// of the entire slice as - /// well. + /// of the entire slice as well. /// /// # Examples /// diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index b323ab03ec6f3..2bd5b315c4c0d 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -977,7 +977,7 @@ impl ops::Index for String { #[inline] fn index(&self, _index: ops::RangeFull) -> &str { - unsafe { mem::transmute(&*self.vec) } + unsafe { str::from_utf8_unchecked(&self.vec) } } } @@ -1016,7 +1016,7 @@ impl ops::Deref for String { #[inline] fn deref(&self) -> &str { - unsafe { mem::transmute(&self.vec[..]) } + unsafe { str::from_utf8_unchecked(&self.vec) } } } @@ -1024,7 +1024,7 @@ impl ops::Deref for String { impl ops::DerefMut for String { #[inline] fn deref_mut(&mut self) -> &mut str { - unsafe { mem::transmute(&mut self.vec[..]) } + unsafe { mem::transmute(&mut *self.vec) } } } diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 9a29f6f9b8284..83786648ea049 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1714,7 +1714,7 @@ impl DoubleEndedIterator for IntoIter { } else { self.end = self.end.offset(-1); - Some(ptr::read(mem::transmute(self.end))) + Some(ptr::read(self.end)) } } } diff --git a/src/libcore/any.rs b/src/libcore/any.rs index e7b39c11f4c1b..ed912d59ce687 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -146,7 +146,7 @@ impl Any { let to: TraitObject = transmute(self); // Extract the data pointer - Some(transmute(to.data)) + Some(&*(to.data as *const T)) } } else { None @@ -164,7 +164,7 @@ impl Any { 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/libcore/cmp.rs b/src/libcore/cmp.rs index 9d151abea787c..da4bb41fd9c3d 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -19,6 +19,7 @@ use self::Ordering::*; +use mem; use marker::Sized; use option::Option::{self, Some, None}; @@ -114,6 +115,10 @@ pub enum Ordering { } impl Ordering { + unsafe fn from_i8_unchecked(v: i8) -> Ordering { + mem::transmute(v) + } + /// Reverse the `Ordering`. /// /// * `Less` becomes `Greater`. @@ -155,7 +160,7 @@ impl Ordering { // // NB. it is safe because of the explicit discriminants // given above. - ::mem::transmute::<_, Ordering>(-(self as i8)) + Ordering::from_i8_unchecked(-(self as i8)) } } } diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 668e2ecf1c637..ea2a9d1cfaf60 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -90,7 +90,7 @@ pub trait Write { fn write_char(&mut self, c: char) -> Result { let mut utf_8 = [0u8; 4]; let bytes_written = c.encode_utf8(&mut utf_8).unwrap_or(0); - self.write_str(unsafe { mem::transmute(&utf_8[..bytes_written]) }) + self.write_str(unsafe { str::from_utf8_unchecked(&utf_8[..bytes_written]) }) } /// Glue for usage of the `write!` macro with implementers of this trait. @@ -1320,7 +1320,7 @@ impl Display for char { } else { let mut utf8 = [0; 4]; let amt = self.encode_utf8(&mut utf8).unwrap_or(0); - let s: &str = unsafe { mem::transmute(&utf8[..amt]) }; + let s: &str = unsafe { str::from_utf8_unchecked(&utf8[..amt]) }; f.pad(s) } } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 116c1dfaa3e83..64727242b9c96 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -16,13 +16,13 @@ #![stable(feature = "rust1", since = "1.0.0")] -use mem; use clone::Clone; use intrinsics; use ops::Deref; use fmt; use option::Option::{self, Some, None}; use marker::{PhantomData, Send, Sized, Sync}; +use mem; use nonzero::NonZero; use cmp::{PartialEq, Eq, Ord, PartialOrd}; @@ -100,7 +100,7 @@ pub unsafe fn swap(x: *mut T, y: *mut T) { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn replace(dest: *mut T, mut src: T) -> T { - mem::swap(mem::transmute(dest), &mut src); // cannot overlap + mem::swap(&mut *dest, &mut src); // cannot overlap src } @@ -327,15 +327,14 @@ impl Clone for *mut T { // Equality for extern "C" fn pointers mod externfnpointers { - use mem; use cmp::PartialEq; #[stable(feature = "rust1", since = "1.0.0")] impl<_R> PartialEq for extern "C" fn() -> _R { #[inline] fn eq(&self, other: &extern "C" fn() -> _R) -> bool { - let self_: *const () = unsafe { mem::transmute(*self) }; - let other_: *const () = unsafe { mem::transmute(*other) }; + let self_ = *self as usize; + let other_ = *other as usize; self_ == other_ } } @@ -345,9 +344,9 @@ mod externfnpointers { impl<_R,$($p),*> PartialEq for extern "C" fn($($p),*) -> _R { #[inline] fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool { - let self_: *const () = unsafe { mem::transmute(*self) }; + let self_ = *self as usize; - let other_: *const () = unsafe { mem::transmute(*other) }; + let other_ = *other as usize; self_ == other_ } } diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index f765cdc54d89b..aa34b65115767 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -33,7 +33,6 @@ // * The `raw` and `bytes` submodules. // * Boilerplate trait implementations. -use mem::transmute; use clone::Clone; use cmp::{Ordering, PartialEq, PartialOrd, Eq, Ord}; use cmp::Ordering::{Less, Equal, Greater}; @@ -148,7 +147,7 @@ macro_rules! slice_ref { // Use a non-null pointer value &mut *(1 as *mut _) } else { - transmute(ptr) + mem::transmute(ptr) } }}; } @@ -261,7 +260,7 @@ impl SliceExt for [T] { #[inline] unsafe fn get_unchecked(&self, index: usize) -> &T { - transmute(self.repr().data.offset(index as isize)) + &*(self.repr().data.offset(index as isize)) } #[inline] @@ -430,7 +429,7 @@ impl SliceExt for [T] { #[inline] unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T { - transmute((self.repr().data as *mut T).offset(index as isize)) + &mut *(self.repr().data as *mut T).offset(index as isize) } #[inline] @@ -547,8 +546,7 @@ impl ops::Index for [T] { fn index(&self, index: usize) -> &T { assert!(index < self.len()); - - unsafe { mem::transmute(self.repr().data.offset(index as isize)) } + unsafe { self.get_unchecked(index) } } } @@ -557,8 +555,7 @@ impl ops::IndexMut for [T] { #[inline] fn index_mut(&mut self, index: usize) -> &mut T { assert!(index < self.len()); - - unsafe { mem::transmute(self.repr().data.offset(index as isize)) } + unsafe { self.get_unchecked_mut(index) } } } @@ -1427,7 +1424,7 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_raw_parts<'a, T>(p: *const T, len: usize) -> &'a [T] { - transmute(RawSlice { data: p, len: len }) + mem::transmute(RawSlice { data: p, len: len }) } /// Performs the same functionality as `from_raw_parts`, except that a mutable @@ -1439,7 +1436,38 @@ pub unsafe fn from_raw_parts<'a, T>(p: *const T, len: usize) -> &'a [T] { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] { - transmute(RawSlice { data: p, len: len }) + mem::transmute(RawSlice { data: p, len: len }) +} + +#[inline] +fn check_types() { + assert!(mem::size_of::() == mem::size_of::()); + assert!(mem::align_of::() % mem::align_of::() == 0) +} + +/// Reinterprets a slice of one type as a slice of another type. +/// +/// Both types have to have the same size and the type that is converted to +/// must have equal or less restrictive alignment. +/// +/// # Panics +/// +/// This functions panics if the above preconditions about the types are not +/// met. +#[inline] +unsafe fn transmute(slice: &[T]) -> &[U] { + check_types::(); + from_raw_parts(slice.as_ptr() as *const U, slice.len()) +} + +/// Reinterprets a mutable slice of one type as a mutable slice of another +/// type. +/// +/// Equivalent of `slice::transmute` for mutable slices. +#[inline] +unsafe fn transmute_mut(slice: &mut [T]) -> &mut [U] { + check_types::(); + from_raw_parts_mut(slice.as_mut_ptr() as *mut U, slice.len()) } // @@ -1580,9 +1608,9 @@ macro_rules! impl_int_slice { #[inline] fn as_signed(&self) -> &[$s] { unsafe { transmute(self) } } #[inline] - fn as_unsigned_mut(&mut self) -> &mut [$u] { unsafe { transmute(self) } } + fn as_unsigned_mut(&mut self) -> &mut [$u] { unsafe { transmute_mut(self) } } #[inline] - fn as_signed_mut(&mut self) -> &mut [$s] { unsafe { transmute(self) } } + fn as_signed_mut(&mut self) -> &mut [$s] { unsafe { transmute_mut(self) } } } } } diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 4f0b881c5cd60..3c9338c2cd29c 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -17,7 +17,7 @@ use self::pattern::Pattern; use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher}; -use char::CharExt; +use char::{self, CharExt}; use clone::Clone; use cmp::Eq; use convert::AsRef; @@ -123,13 +123,13 @@ impl Utf8Error { /// Converts a slice of bytes to a string slice without performing any /// allocations. /// -/// Once the slice has been validated as utf-8, it is transmuted in-place and +/// Once the slice has been validated as UTF-8, it is transmuted in-place and /// returned as a '&str' instead of a '&[u8]' /// /// # Failure /// -/// Returns `Err` if the slice is not utf-8 with a description as to why the -/// provided slice is not utf-8. +/// Returns `Err` if the slice is not UTF-8 with a description as to why the +/// provided slice is not UTF-8. #[stable(feature = "rust1", since = "1.0.0")] pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { try!(run_utf8_validation_iterator(&mut v.iter())); @@ -262,7 +262,7 @@ impl<'a> Iterator for Chars<'a> { next_code_point(&mut self.iter).map(|ch| { // str invariant says `ch` is a valid Unicode Scalar Value unsafe { - mem::transmute(ch) + char::from_u32_unchecked(ch) } }) } @@ -284,7 +284,7 @@ impl<'a> DoubleEndedIterator for Chars<'a> { next_code_point_reverse(&mut self.iter).map(|ch| { // str invariant says `ch` is a valid Unicode Scalar Value unsafe { - mem::transmute(ch) + char::from_u32_unchecked(ch) } }) } @@ -1507,7 +1507,7 @@ impl StrExt for str { #[inline] fn char_range_at(&self, i: usize) -> CharRange { let (c, n) = char_range_at_raw(self.as_bytes(), i); - CharRange { ch: unsafe { mem::transmute(c) }, next: n } + CharRange { ch: unsafe { char::from_u32_unchecked(c) }, next: n } } #[inline] @@ -1535,7 +1535,7 @@ impl StrExt for str { if w > 2 { val = utf8_acc_cont_byte(val, s.as_bytes()[i + 2]); } if w > 3 { val = utf8_acc_cont_byte(val, s.as_bytes()[i + 3]); } - return CharRange {ch: unsafe { mem::transmute(val) }, next: i}; + return CharRange {ch: unsafe { char::from_u32_unchecked(val) }, next: i}; } return multibyte_char_range_at_reverse(self, prev); diff --git a/src/libcoretest/hash/mod.rs b/src/libcoretest/hash/mod.rs index 697c3ee254b98..595bce682010b 100644 --- a/src/libcoretest/hash/mod.rs +++ b/src/libcoretest/hash/mod.rs @@ -10,7 +10,6 @@ mod sip; -use std::mem; use std::hash::{Hash, Hasher}; use std::default::Default; @@ -72,15 +71,11 @@ fn test_writer_hasher() { // FIXME (#18248) Add tests for hashing Rc and Rc<[T]> - unsafe { - let ptr: *const i32 = mem::transmute(5_usize); - assert_eq!(hash(&ptr), 5); - } + let ptr = 5_usize as *const i32; + assert_eq!(hash(&ptr), 5); - unsafe { - let ptr: *mut i32 = mem::transmute(5_usize); - assert_eq!(hash(&ptr), 5); - } + let ptr = 5_usize as *mut i32; + assert_eq!(hash(&ptr), 5); } struct Custom { hash: u64 } diff --git a/src/libcoretest/ptr.rs b/src/libcoretest/ptr.rs index 865b049aae55a..343db93d4a970 100644 --- a/src/libcoretest/ptr.rs +++ b/src/libcoretest/ptr.rs @@ -9,7 +9,6 @@ // except according to those terms. use core::ptr::*; -use core::mem; #[test] fn test() { @@ -20,7 +19,7 @@ fn test() { }; let mut p = Pair {fst: 10, snd: 20}; let pptr: *mut Pair = &mut p; - let iptr: *mut isize = mem::transmute(pptr); + let iptr: *mut isize = pptr as *mut isize; assert_eq!(*iptr, 10); *iptr = 30; assert_eq!(*iptr, 30); diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index 7bafd9382f059..bec4f24a565b4 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -294,7 +294,7 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) { 1 => panic!("cannot log after main thread has exited"), n => { let filter = mem::transmute::<_, &String>(n); - if !args.to_string().contains(&filter[..]) { + if !args.to_string().contains(filter) { return } } diff --git a/src/librand/distributions/exponential.rs b/src/librand/distributions/exponential.rs index f46d35a33db1a..c3a02ec5aabdb 100644 --- a/src/librand/distributions/exponential.rs +++ b/src/librand/distributions/exponential.rs @@ -17,9 +17,9 @@ use distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample}; /// A wrapper around an `f64` to generate Exp(1) random numbers. /// -/// See `Exp` for the general exponential distribution.Note that this - // has to be unwrapped before use as an `f64` (using either -/// `*` or `mem::transmute` is safe). +/// See `Exp` for the general exponential distribution. Note that this has to +/// be unwrapped before use as an `f64` (using either `*` or `mem::transmute` +/// is safe). /// /// Implemented via the ZIGNOR variant[1] of the Ziggurat method. The /// exact description in the paper was adjusted to use tables for the diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index b901e31a53a00..d1fb0c2e8d79e 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -25,7 +25,6 @@ use syntax::diagnostic::{Emitter, Handler, Level}; use std::ffi::{CStr, CString}; use std::fs; -use std::mem; use std::path::Path; use std::ptr; use std::str; @@ -375,8 +374,7 @@ unsafe extern "C" fn report_inline_asm<'a, 'b>(cgcx: &'a CodegenContext<'a>, unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef, user: *const c_void, cookie: c_uint) { - let HandlerFreeVars { cgcx, .. } - = *mem::transmute::<_, *const HandlerFreeVars>(user); + let HandlerFreeVars { cgcx, .. } = *(user as *const HandlerFreeVars); let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s)) .expect("non-UTF8 SMDiagnostic"); @@ -385,8 +383,7 @@ unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef, } unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) { - let HandlerFreeVars { llcx, cgcx } - = *mem::transmute::<_, *const HandlerFreeVars>(user); + let HandlerFreeVars { llcx, cgcx } = *(user as *const HandlerFreeVars); match llvm::diagnostic::Diagnostic::unpack(info) { llvm::diagnostic::InlineAsm(inline) => { diff --git a/src/librustc_trans/trans/type_.rs b/src/librustc_trans/trans/type_.rs index 699115a070986..c635d1ba233fd 100644 --- a/src/librustc_trans/trans/type_.rs +++ b/src/librustc_trans/trans/type_.rs @@ -56,6 +56,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())) } @@ -149,19 +153,19 @@ impl Type { } pub fn 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, False)) } 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)) } pub fn struct_(ccx: &CrateContext, els: &[Type], packed: bool) -> Type { - let els : &[TypeRef] = unsafe { mem::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)) @@ -209,9 +213,9 @@ impl Type { } pub fn set_struct_body(&mut self, els: &[Type], packed: bool) { + let slice: &[TypeRef] = Type::to_ref_slice(els); unsafe { - let vec : &[TypeRef] = mem::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/librustc_unicode/lib.rs b/src/librustc_unicode/lib.rs index 3a69430d07822..6cd8b72cb5ce1 100644 --- a/src/librustc_unicode/lib.rs +++ b/src/librustc_unicode/lib.rs @@ -33,6 +33,7 @@ test(no_crate_inject))] #![no_std] +#![feature(char_from_unchecked)] #![feature(core_char_ext)] #![feature(core_slice_ext)] #![feature(core_str_ext)] diff --git a/src/librustc_unicode/normalize.rs b/src/librustc_unicode/normalize.rs index 0c2ad36c637eb..d5219ab28fed6 100644 --- a/src/librustc_unicode/normalize.rs +++ b/src/librustc_unicode/normalize.rs @@ -126,20 +126,18 @@ const S_COUNT: u32 = (L_COUNT * N_COUNT); // Decompose a precomposed Hangul syllable #[inline(always)] fn decompose_hangul(s: char, f: &mut F) where F: FnMut(char) { - use core::mem::transmute; - + use core::char::from_u32_unchecked; let si = s as u32 - S_BASE; - let li = si / N_COUNT; unsafe { - (*f)(transmute(L_BASE + li)); + (*f)(from_u32_unchecked(L_BASE + li)); let vi = (si % N_COUNT) / T_COUNT; - (*f)(transmute(V_BASE + vi)); + (*f)(from_u32_unchecked(V_BASE + vi)); let ti = si % T_COUNT; if ti > 0 { - (*f)(transmute(T_BASE + ti)); + (*f)(from_u32_unchecked(T_BASE + ti)); } } } @@ -147,18 +145,18 @@ fn decompose_hangul(s: char, f: &mut F) where F: FnMut(char) { // Compose a pair of Hangul Jamo #[inline(always)] fn compose_hangul(a: char, b: char) -> Option { - use core::mem::transmute; + use core::char::from_u32_unchecked; let l = a as u32; let v = b as u32; // Compose an LPart and a VPart if L_BASE <= l && l < (L_BASE + L_COUNT) && V_BASE <= v && v < (V_BASE + V_COUNT) { let r = S_BASE + (l - L_BASE) * N_COUNT + (v - V_BASE) * T_COUNT; - return unsafe { Some(transmute(r)) }; + return unsafe { Some(from_u32_unchecked(r)) }; } // Compose an LVPart and a TPart if S_BASE <= l && l <= (S_BASE+S_COUNT-T_COUNT) && T_BASE <= v && v < (T_BASE+T_COUNT) { let r = l + (v - T_BASE); - return unsafe { Some(transmute(r)) }; + return unsafe { Some(from_u32_unchecked(r)) }; } None } diff --git a/src/librustc_unicode/u_str.rs b/src/librustc_unicode/u_str.rs index 95214fe2db389..37443cfa70ce1 100644 --- a/src/librustc_unicode/u_str.rs +++ b/src/librustc_unicode/u_str.rs @@ -20,7 +20,6 @@ use core::prelude::v1::*; use core::char; use core::cmp; use core::iter::Filter; -use core::mem; use core::slice; use core::str::Split; @@ -454,7 +453,7 @@ impl<'a> Iterator for Utf16Items<'a> { if u < 0xD800 || 0xDFFF < u { // not a surrogate - Some(Utf16Item::ScalarValue(unsafe {mem::transmute(u as u32)})) + Some(Utf16Item::ScalarValue(unsafe { char::from_u32_unchecked(u as u32) })) } else if u >= 0xDC00 { // a trailing surrogate Some(Utf16Item::LoneSurrogate(u)) @@ -476,7 +475,7 @@ impl<'a> Iterator for Utf16Items<'a> { // all ok, so lets decode it. let c = (((u - 0xD800) as u32) << 10 | (u2 - 0xDC00) as u32) + 0x1_0000; - Some(Utf16Item::ScalarValue(unsafe {mem::transmute(c)})) + Some(Utf16Item::ScalarValue(unsafe { char::from_u32_unchecked(c) })) } } diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index cd9dadd1be9e6..ded572e82ff9a 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -14,8 +14,8 @@ use prelude::v1::*; -use ops::Range; use mem; +use ops::Range; /// Extension methods for ASCII-subset only operations on owned strings #[unstable(feature = "owned_ascii_ext", diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 4d08f08bb6eb9..f0f481d3721ae 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 6eb0719d9f6ff..3e503074ab4d5 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 { mem::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 47b8230e43029..83d76481d4956 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/path.rs b/src/libstd/path.rs index 4a4db61c3b96f..c3a887cbcb861 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 665f423c3f1f6..8ac2722f65a23 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 1d31ac165f637..c46e61cf41440 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 ae8bfb07aaf1e..4128431ee64c0 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