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`.
This commit is contained in:
parent
febdc3b201
commit
22ec5f4af7
|
@ -193,7 +193,7 @@ impl<T> Arc<T> {
|
|||
weak: atomic::AtomicUsize::new(1),
|
||||
data: data,
|
||||
};
|
||||
Arc { _ptr: unsafe { NonZero::new(mem::transmute(x)) } }
|
||||
Arc { _ptr: unsafe { NonZero::new(Box::into_raw(x)) } }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<T> TypedArenaChunk<T> {
|
|||
fn start(&self) -> *const u8 {
|
||||
let this: *const TypedArenaChunk<T> = self;
|
||||
unsafe {
|
||||
mem::transmute(round_up(this.offset(1) as usize,
|
||||
mem::align_of::<T>()))
|
||||
round_up(this.offset(1) as usize, mem::align_of::<T>()) as *const u8
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -488,7 +487,7 @@ impl<T> TypedArena<T> {
|
|||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -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<K, V> Node<K, V> {
|
|||
|
||||
#[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<K, V> Node<K, V> {
|
|||
None => heap::EMPTY as *const Node<K,V>,
|
||||
Some(ref p) => **p as *const Node<K,V>,
|
||||
};
|
||||
mem::transmute(raw::Slice {
|
||||
data: data,
|
||||
len: self.len() + 1
|
||||
})
|
||||
slice::from_raw_parts(data, self.len() + 1)
|
||||
}
|
||||
};
|
||||
NodeSlice {
|
||||
|
@ -390,6 +390,7 @@ impl<K, V> Node<K, V> {
|
|||
|
||||
#[inline]
|
||||
pub fn as_slices_internal_mut<'b>(&'b mut self) -> MutNodeSlice<'b, K, V> {
|
||||
// TODO: Bad: This relies on structure layout!
|
||||
unsafe { mem::transmute(self.as_slices_internal()) }
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#![feature(oom)]
|
||||
#![feature(pattern)]
|
||||
#![feature(ptr_as_ref)]
|
||||
#![feature(raw)]
|
||||
#![feature(slice_patterns)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(step_by)]
|
||||
|
|
|
@ -109,6 +109,7 @@ 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
|
||||
|
|
|
@ -479,6 +479,19 @@ 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
|
||||
|
@ -504,8 +517,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
|
||||
///
|
||||
|
|
|
@ -977,7 +977,7 @@ impl ops::Index<ops::RangeFull> 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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1714,7 +1714,7 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
|
|||
} else {
|
||||
self.end = self.end.offset(-1);
|
||||
|
||||
Some(ptr::read(mem::transmute(self.end)))
|
||||
Some(ptr::read(self.end))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<T>(x: *mut T, y: *mut T) {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub unsafe fn replace<T>(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<T: ?Sized> 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_
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<T> 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<T> 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<T> ops::Index<usize> 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<T> ops::IndexMut<usize> 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,40 @@ 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<T,U>() {
|
||||
assert!(mem::size_of::<T>() == mem::size_of::<U>());
|
||||
assert!(mem::align_of::<T>() % mem::align_of::<U>() == 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]
|
||||
#[unstable(feature = "slice_transmute", reason = "recent API addition")]
|
||||
pub unsafe fn transmute<T,U>(slice: &[T]) -> &[U] {
|
||||
check_types::<T,U>();
|
||||
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]
|
||||
#[unstable(feature = "slice_transmute", reason = "recent API addition")]
|
||||
pub unsafe fn transmute_mut<T,U>(slice: &mut [T]) -> &mut [U] {
|
||||
check_types::<T,U>();
|
||||
from_raw_parts_mut(slice.as_mut_ptr() as *mut U, slice.len())
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1580,9 +1610,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) } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1264,6 +1264,7 @@ 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<usize>;
|
||||
fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
|
||||
where P::Searcher: ReverseSearcher<'a>;
|
||||
|
@ -1507,7 +1508,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 +1536,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);
|
||||
|
@ -1556,6 +1557,11 @@ 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<usize> {
|
||||
pat.into_searcher(self).next_match().map(|(i, _)| i)
|
||||
}
|
||||
|
|
|
@ -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<str> 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 }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
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)]
|
||||
|
|
|
@ -20,8 +20,11 @@ use util::nodemap::FnvHashMap;
|
|||
use syntax::ast;
|
||||
|
||||
use std::ffi::CString;
|
||||
#[cfg(stage0)]
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
#[cfg(not(stage0))]
|
||||
use std::slice;
|
||||
use std::cell::RefCell;
|
||||
|
||||
use libc::c_uint;
|
||||
|
@ -148,18 +151,35 @@ 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(),
|
||||
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(),
|
||||
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(),
|
||||
|
@ -167,6 +187,14 @@ impl Type {
|
|||
packed as Bool))
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
pub fn struct_(ccx: &CrateContext, els: &[Type], packed: bool) -> Type {
|
||||
let els : &[TypeRef] = unsafe { slice::transmute(els) };
|
||||
ty!(llvm::LLVMStructTypeInContext(ccx.llcx(), els.as_ptr(),
|
||||
els.len() as c_uint,
|
||||
packed as Bool))
|
||||
}
|
||||
|
||||
pub fn named_struct(ccx: &CrateContext, name: &str) -> Type {
|
||||
let name = CString::new(name).unwrap();
|
||||
ty!(llvm::LLVMStructCreateNamed(ccx.llcx(), name.as_ptr()))
|
||||
|
@ -208,6 +236,7 @@ impl Type {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
pub fn set_struct_body(&mut self, els: &[Type], packed: bool) {
|
||||
unsafe {
|
||||
let vec : &[TypeRef] = mem::transmute(els);
|
||||
|
@ -216,6 +245,15 @@ impl Type {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
pub fn set_struct_body(&mut self, els: &[Type], packed: bool) {
|
||||
unsafe {
|
||||
let vec: &[TypeRef] = slice::transmute(els);
|
||||
llvm::LLVMStructSetBody(self.to_ref(), vec.as_ptr(),
|
||||
els.len() as c_uint, packed as Bool)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ptr_to(&self) -> Type {
|
||||
ty!(llvm::LLVMPointerType(self.to_ref(), 0))
|
||||
}
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -126,20 +126,18 @@ const S_COUNT: u32 = (L_COUNT * N_COUNT);
|
|||
// Decompose a precomposed Hangul syllable
|
||||
#[inline(always)]
|
||||
fn decompose_hangul<F>(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<F>(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<char> {
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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) }))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -134,7 +134,7 @@ impl ops::Index<ops::RangeFull> 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<OsStr> for OsString {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl AsRef<OsStr> 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<OsStr> for String {
|
||||
fn as_ref(&self) -> &OsStr {
|
||||
unsafe { mem::transmute(Slice::from_str(self)) }
|
||||
(&**self).as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -942,7 +942,7 @@ pub struct PathBuf {
|
|||
|
||||
impl PathBuf {
|
||||
fn as_mut_vec(&mut self) -> &mut Vec<u8> {
|
||||
unsafe { mem::transmute(self) }
|
||||
unsafe { &mut *(self as *mut PathBuf as *mut Vec<u8>) }
|
||||
}
|
||||
|
||||
/// 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.
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#![feature(associated_consts)]
|
||||
#![feature(bitset)]
|
||||
#![feature(copy_lifetime)]
|
||||
#![feature(drain)]
|
||||
#![feature(filling_drop)]
|
||||
#![feature(libc)]
|
||||
|
|
Loading…
Reference in New Issue