Skip to content

Commit 3413feb

Browse files
author
Thomas Bahn
committed
Replace transmutes by pointer casts
1 parent f726735 commit 3413feb

File tree

3 files changed

+66
-29
lines changed

3 files changed

+66
-29
lines changed

src/ascii_char.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#[cfg(feature = "quickcheck")]
22
use quickcheck::{Arbitrary, Gen};
33

4-
use core::mem::transmute;
4+
use core::mem;
55
use core::cmp::Ordering;
66
use core::{fmt, char};
77
#[cfg(feature = "std")]
@@ -671,7 +671,7 @@ impl ToAsciiChar for u8 {
671671
}
672672
#[inline]
673673
unsafe fn to_ascii_char_unchecked(self) -> AsciiChar {
674-
transmute(self)
674+
mem::transmute(self)
675675
}
676676
}
677677

src/ascii_str.rs

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,15 @@ impl AsciiStr {
3030
/// Converts `&self` to a `&str` slice.
3131
#[inline]
3232
pub fn as_str(&self) -> &str {
33-
unsafe { mem::transmute(&self.slice) }
33+
let ptr = self as *const AsciiStr as *const str;
34+
unsafe { &*ptr }
3435
}
3536

3637
/// Converts `&self` into a byte slice.
3738
#[inline]
3839
pub fn as_bytes(&self) -> &[u8] {
39-
unsafe { mem::transmute(&self.slice) }
40+
let ptr = self as *const AsciiStr as *const [u8];
41+
unsafe { &*ptr }
4042
}
4143

4244
/// Returns the entire string as slice of `AsciiChar`s.
@@ -297,20 +299,23 @@ impl Default for &'static AsciiStr {
297299
impl<'a> From<&'a [AsciiChar]> for &'a AsciiStr {
298300
#[inline]
299301
fn from(slice: &[AsciiChar]) -> &AsciiStr {
300-
unsafe { mem::transmute(slice) }
302+
let ptr = slice as *const [AsciiChar] as *const AsciiStr;
303+
unsafe { &*ptr }
301304
}
302305
}
303306
impl<'a> From<&'a mut [AsciiChar]> for &'a mut AsciiStr {
304307
#[inline]
305308
fn from(slice: &mut [AsciiChar]) -> &mut AsciiStr {
306-
unsafe { mem::transmute(slice) }
309+
let ptr = slice as *mut [AsciiChar] as *mut AsciiStr;
310+
unsafe { &mut *ptr }
307311
}
308312
}
309313
#[cfg(feature = "std")]
310314
impl From<Box<[AsciiChar]>> for Box<AsciiStr> {
311315
#[inline]
312316
fn from(owned: Box<[AsciiChar]>) -> Box<AsciiStr> {
313-
unsafe { mem::transmute(owned) }
317+
let ptr = Box::into_raw(owned) as *mut AsciiStr;
318+
unsafe { Box::from_raw(ptr) }
314319
}
315320
}
316321

@@ -319,20 +324,23 @@ macro_rules! impl_into {
319324
impl<'a> From<&'a AsciiStr> for &'a$wider {
320325
#[inline]
321326
fn from(slice: &AsciiStr) -> &$wider {
322-
unsafe{ mem::transmute(slice) }
327+
let ptr = slice as *const AsciiStr as *const $wider;
328+
unsafe { &*ptr }
323329
}
324330
}
325331
impl<'a> From<&'a mut AsciiStr> for &'a mut $wider {
326332
#[inline]
327333
fn from(slice: &mut AsciiStr) -> &mut $wider {
328-
unsafe{ mem::transmute(slice) }
334+
let ptr = slice as *mut AsciiStr as *mut $wider;
335+
unsafe { &mut *ptr }
329336
}
330337
}
331338
#[cfg(feature = "std")]
332339
impl From<Box<AsciiStr>> for Box<$wider> {
333340
#[inline]
334341
fn from(owned: Box<AsciiStr>) -> Box<$wider> {
335-
unsafe{ mem::transmute(owned) }
342+
let ptr = Box::into_raw(owned) as *mut $wider;
343+
unsafe { Box::from_raw(ptr) }
336344
}
337345
}
338346
}
@@ -356,30 +364,47 @@ impl fmt::Debug for AsciiStr {
356364
}
357365

358366
macro_rules! impl_index {
359-
($lhs:ty, $idx:ty, $rhs:ty) => {
360-
impl Index<$idx> for $lhs {
361-
type Output = $rhs;
367+
($idx:ty) => {
368+
impl Index<$idx> for AsciiStr {
369+
type Output = AsciiStr;
362370

363371
#[inline]
364-
fn index(&self, index: $idx) -> &$rhs {
365-
unsafe { mem::transmute(&self.slice[index]) }
372+
fn index(&self, index: $idx) -> &AsciiStr {
373+
let ptr = &self.slice[index] as *const [AsciiChar] as *const AsciiStr;
374+
unsafe { &* ptr }
366375
}
367376
}
368377

369-
impl IndexMut<$idx> for $lhs {
378+
impl IndexMut<$idx> for AsciiStr {
370379
#[inline]
371-
fn index_mut(&mut self, index: $idx) -> &mut $rhs {
372-
unsafe { mem::transmute(&mut self.slice[index]) }
380+
fn index_mut(&mut self, index: $idx) -> &mut AsciiStr {
381+
let ptr = &mut self.slice[index] as *mut [AsciiChar] as *mut AsciiStr;
382+
unsafe { &mut *ptr }
373383
}
374384
}
375385
}
376386
}
377387

378-
impl_index! { AsciiStr, usize, AsciiChar }
379-
impl_index! { AsciiStr, Range<usize>, AsciiStr }
380-
impl_index! { AsciiStr, RangeTo<usize>, AsciiStr }
381-
impl_index! { AsciiStr, RangeFrom<usize>, AsciiStr }
382-
impl_index! { AsciiStr, RangeFull, AsciiStr }
388+
impl_index! { Range<usize> }
389+
impl_index! { RangeTo<usize> }
390+
impl_index! { RangeFrom<usize> }
391+
impl_index! { RangeFull }
392+
393+
impl Index<usize> for AsciiStr {
394+
type Output = AsciiChar;
395+
396+
#[inline]
397+
fn index(&self, index: usize) -> &AsciiChar {
398+
unsafe { mem::transmute(&self.slice[index]) }
399+
}
400+
}
401+
402+
impl IndexMut<usize> for AsciiStr {
403+
#[inline]
404+
fn index_mut(&mut self, index: usize) -> &mut AsciiChar {
405+
unsafe { mem::transmute(&mut self.slice[index]) }
406+
}
407+
}
383408

384409
#[cfg(feature = "std")]
385410
impl AsciiExt for AsciiStr {
@@ -603,7 +628,8 @@ impl AsAsciiStr for [u8] {
603628
}
604629
#[inline]
605630
unsafe fn as_ascii_str_unchecked(&self) -> &AsciiStr {
606-
mem::transmute(self)
631+
let ptr = self as *const [u8] as *const AsciiStr;
632+
&*ptr
607633
}
608634
}
609635
impl AsMutAsciiStr for [u8] {
@@ -615,7 +641,8 @@ impl AsMutAsciiStr for [u8] {
615641
}
616642
#[inline]
617643
unsafe fn as_mut_ascii_str_unchecked(&mut self) -> &mut AsciiStr {
618-
mem::transmute(self)
644+
let ptr = self as *mut [u8] as *mut AsciiStr;
645+
&mut *ptr
619646
}
620647
}
621648

@@ -637,7 +664,8 @@ impl AsMutAsciiStr for str {
637664
}
638665
#[inline]
639666
unsafe fn as_mut_ascii_str_unchecked(&mut self) -> &mut AsciiStr {
640-
mem::transmute(self)
667+
let ptr = self as *mut str as *mut AsciiStr;
668+
&mut *ptr
641669
}
642670
}
643671

src/ascii_string.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,14 @@ impl AsciiString {
9696
where
9797
B: Into<Vec<u8>>,
9898
{
99-
AsciiString { vec: mem::transmute(bytes.into()) }
99+
let mut bytes = bytes.into();
100+
let vec = Vec::from_raw_parts(
101+
bytes.as_mut_ptr() as *mut AsciiChar,
102+
bytes.len(),
103+
bytes.capacity(),
104+
);
105+
mem::forget(bytes);
106+
AsciiString { vec: vec }
100107
}
101108

102109
/// Converts anything that can represent a byte buffer into an `AsciiString`.
@@ -351,14 +358,16 @@ impl Deref for AsciiString {
351358

352359
#[inline]
353360
fn deref(&self) -> &AsciiStr {
354-
unsafe { mem::transmute(&self.vec[..]) }
361+
let ptr = &*self.vec as *const [AsciiChar] as *const AsciiStr;
362+
unsafe { &*ptr }
355363
}
356364
}
357365

358366
impl DerefMut for AsciiString {
359367
#[inline]
360368
fn deref_mut(&mut self) -> &mut AsciiStr {
361-
unsafe { mem::transmute(&mut self.vec[..]) }
369+
let ptr = &mut *self.vec as *mut [AsciiChar] as *mut AsciiStr;
370+
unsafe { &mut *ptr }
362371
}
363372
}
364373

0 commit comments

Comments
 (0)