Auto merge of #27252 - tbu-:pr_less_transmutes, r=alexcrichton

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 builds upon #27233.
This commit is contained in:
bors 2015-08-10 18:46:21 +00:00
commit 3d69bec881
30 changed files with 133 additions and 108 deletions

View File

@ -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)) } }
}
}

View File

@ -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

View File

@ -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> {
// FIXME(#27620): Bad: This relies on structure layout!
unsafe { mem::transmute(self.as_slices_internal()) }
}

View File

@ -47,7 +47,6 @@
#![feature(oom)]
#![feature(pattern)]
#![feature(ptr_as_ref)]
#![feature(raw)]
#![feature(slice_patterns)]
#![feature(staged_api)]
#![feature(step_by)]

View File

@ -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
///

View File

@ -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) }
}
}

View File

@ -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))
}
}
}

View File

@ -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

View File

@ -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))
}
}
}

View File

@ -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)
}
}

View File

@ -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_
}
}

View File

@ -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,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<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]
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]
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 +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) } }
}
}
}

View File

@ -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);

View File

@ -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 }

View File

@ -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);

View File

@ -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
}
}

View File

@ -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

View File

@ -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) => {

View File

@ -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)
}
}

View File

@ -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)]

View File

@ -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
}

View File

@ -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) }))
}
}

View File

@ -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",

View File

@ -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

View File

@ -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.

View File

@ -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()
}
}

View File

@ -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.

View File

@ -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());

View File

@ -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);

View File

@ -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