Skip to content

slice::from_raw_parts is preferred over transmuting a fresh raw::Slice #23333

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 14, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions src/libcollections/btree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,14 +348,8 @@ impl<K, V> Node<K, V> {
#[inline]
pub fn as_slices<'a>(&'a self) -> (&'a [K], &'a [V]) {
unsafe {(
mem::transmute(raw::Slice {
data: *self.keys as *const K,
len: self.len()
}),
mem::transmute(raw::Slice {
data: *self.vals as *const V,
len: self.len()
})
slice::from_raw_parts(*self.keys, self.len()),
slice::from_raw_parts(*self.vals, self.len()),
)}
}

Expand Down
12 changes: 6 additions & 6 deletions src/libcollections/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use core::iter::{IntoIterator, FromIterator};
use core::mem;
use core::ops::{self, Deref, Add, Index};
use core::ptr;
use core::raw::Slice as RawSlice;
use core::slice;
use unicode::str as unicode_str;
use unicode::str::Utf16Item;

Expand Down Expand Up @@ -468,11 +468,11 @@ impl String {
unsafe {
// Attempt to not use an intermediate buffer by just pushing bytes
// directly onto this string.
let slice = RawSlice {
data: self.vec.as_ptr().offset(cur_len as isize),
len: 4,
};
let used = ch.encode_utf8(mem::transmute(slice)).unwrap_or(0);
let slice = slice::from_raw_parts_mut (
self.vec.as_mut_ptr().offset(cur_len as isize),
4
);
let used = ch.encode_utf8(slice).unwrap_or(0);
self.vec.set_len(cur_len + used);
}
}
Expand Down
11 changes: 2 additions & 9 deletions src/libcollections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ use core::ops::{Index, IndexMut, Deref, Add};
use core::ops;
use core::ptr;
use core::ptr::Unique;
use core::raw::Slice as RawSlice;
use core::slice;
use core::usize;

Expand Down Expand Up @@ -435,10 +434,7 @@ impl<T> Vec<T> {
unsafe {
let ptr = *self.ptr;
assume(!ptr.is_null());
mem::transmute(RawSlice {
data: ptr,
len: self.len,
})
slice::from_raw_parts_mut(ptr, self.len)
}
}

Expand Down Expand Up @@ -1560,10 +1556,7 @@ impl<T> AsSlice<T> for Vec<T> {
unsafe {
let p = *self.ptr;
assume(p != 0 as *mut T);
mem::transmute(RawSlice {
data: p,
len: self.len
})
slice::from_raw_parts(p, self.len)
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/libcollections/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use core::num::{Int, UnsignedInt};
use core::num::wrapping::WrappingOps;
use core::ops::{Index, IndexMut};
use core::ptr::{self, Unique};
use core::raw::Slice as RawSlice;
use core::slice;

use core::hash::{Hash, Hasher};
use core::cmp;
Expand Down Expand Up @@ -91,13 +91,13 @@ impl<T> VecDeque<T> {
/// Turn ptr into a slice
#[inline]
unsafe fn buffer_as_slice(&self) -> &[T] {
mem::transmute(RawSlice { data: *self.ptr as *const T, len: self.cap })
slice::from_raw_parts(*self.ptr, self.cap)
}

/// Turn ptr into a mut slice
#[inline]
unsafe fn buffer_as_mut_slice(&mut self) -> &mut [T] {
mem::transmute(RawSlice { data: *self.ptr as *const T, len: self.cap })
slice::from_raw_parts_mut(*self.ptr, self.cap)
}

/// Moves an element out of the buffer
Expand Down
41 changes: 27 additions & 14 deletions src/libcore/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,10 +520,10 @@ impl<T> ops::Index<ops::Range<usize>> for [T] {
assert!(index.start <= index.end);
assert!(index.end <= self.len());
unsafe {
transmute(RawSlice {
data: self.as_ptr().offset(index.start as isize),
len: index.end - index.start
})
from_raw_parts (
self.as_ptr().offset(index.start as isize),
index.end - index.start
)
}
}
}
Expand Down Expand Up @@ -559,10 +559,10 @@ impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
assert!(index.start <= index.end);
assert!(index.end <= self.len());
unsafe {
transmute(RawSlice {
data: self.as_ptr().offset(index.start as isize),
len: index.end - index.start
})
from_raw_parts_mut(
self.as_mut_ptr().offset(index.start as isize),
index.end - index.start
)
}
}
}
Expand Down Expand Up @@ -731,7 +731,21 @@ macro_rules! make_slice {
diff / mem::size_of::<$t>()
};
unsafe {
transmute::<_, $result>(RawSlice { data: $start, len: len })
from_raw_parts($start, len)
}
}}
}

macro_rules! make_mut_slice {
($t: ty => $result: ty: $start: expr, $end: expr) => {{
let diff = $end as usize - $start as usize;
let len = if mem::size_of::<T>() == 0 {
diff
} else {
diff / mem::size_of::<$t>()
};
unsafe {
from_raw_parts_mut($start, len)
}
}}
}
Expand Down Expand Up @@ -898,7 +912,7 @@ impl<'a, T> ops::IndexMut<ops::RangeFrom<usize>> for IterMut<'a, T> {
impl<'a, T> ops::IndexMut<RangeFull> for IterMut<'a, T> {
#[inline]
fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] {
make_slice!(T => &mut [T]: self.ptr, self.end)
make_mut_slice!(T => &mut [T]: self.ptr, self.end)
}
}

Expand All @@ -912,7 +926,7 @@ impl<'a, T> IterMut<'a, T> {
/// restricted lifetimes that do not consume the iterator.
#[unstable(feature = "core")]
pub fn into_slice(self) -> &'a mut [T] {
make_slice!(T => &'a mut [T]: self.ptr, self.end)
make_mut_slice!(T => &'a mut [T]: self.ptr, self.end)
}
}

Expand Down Expand Up @@ -1404,16 +1418,15 @@ impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {}
#[unstable(feature = "core")]
pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] {
unsafe {
transmute(RawSlice { data: s, len: 1 })
from_raw_parts(s, 1)
}
}

/// Converts a pointer to A into a slice of length 1 (without copying).
#[unstable(feature = "core")]
pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
unsafe {
let ptr: *const A = transmute(s);
transmute(RawSlice { data: ptr, len: 1 })
from_raw_parts_mut(s, 1)
}
}

Expand Down
8 changes: 2 additions & 6 deletions src/librustc_llvm/archive_ro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ use libc;
use ArchiveRef;

use std::ffi::CString;
use std::mem;
use std::raw;
use std::slice;
use std::path::Path;

pub struct ArchiveRO {
Expand Down Expand Up @@ -62,10 +61,7 @@ impl ArchiveRO {
if ptr.is_null() {
None
} else {
Some(mem::transmute(raw::Slice {
data: ptr,
len: size as uint,
}))
Some(slice::from_raw_parts(ptr as *const u8, size as uint))
}
}
}
Expand Down
8 changes: 2 additions & 6 deletions src/librustc_llvm/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
#![feature(int_uint)]
#![feature(libc)]
#![feature(link_args)]
Expand Down Expand Up @@ -59,7 +58,7 @@ pub use self::Linkage::*;

use std::ffi::CString;
use std::cell::RefCell;
use std::{raw, mem};
use std::{slice, mem};
use libc::{c_uint, c_ushort, uint64_t, c_int, size_t, c_char};
use libc::{c_longlong, c_ulonglong, c_void};
use debuginfo::{DIBuilderRef, DIDescriptor,
Expand Down Expand Up @@ -2227,10 +2226,7 @@ type RustStringRepr = *mut RefCell<Vec<u8>>;
pub unsafe extern "C" fn rust_llvm_string_write_impl(sr: RustStringRef,
ptr: *const c_char,
size: size_t) {
let slice: &[u8] = mem::transmute(raw::Slice {
data: ptr as *const u8,
len: size as uint,
});
let slice = slice::from_raw_parts(ptr as *const u8, size as uint);

let sr: RustStringRepr = mem::transmute(sr);
(*sr).borrow_mut().push_all(slice);
Expand Down
10 changes: 5 additions & 5 deletions src/libstd/old_io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -928,15 +928,15 @@ impl<'a> Reader for &'a mut (Reader+'a) {
// Private function here because we aren't sure if we want to expose this as
// API yet. If so, it should be a method on Vec.
unsafe fn slice_vec_capacity<'a, T>(v: &'a mut Vec<T>, start: uint, end: uint) -> &'a mut [T] {
use raw::Slice;
use slice;
use ptr::PtrExt;

assert!(start <= end);
assert!(end <= v.capacity());
transmute(Slice {
data: v.as_ptr().offset(start as int),
len: end - start
})
slice::from_raw_parts_mut(
v.as_mut_ptr().offset(start as int),
end - start
)
}

/// A `RefReader` is a struct implementing `Reader` which contains a reference
Expand Down
18 changes: 9 additions & 9 deletions src/libstd/sys/common/wtf8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ use core::prelude::*;

use core::char::{encode_utf8_raw, encode_utf16_raw};
use core::str::{char_range_at_raw, next_code_point};
use core::raw::Slice as RawSlice;

use ascii::*;
use borrow::Cow;
Expand Down Expand Up @@ -210,10 +209,10 @@ impl Wtf8Buf {
unsafe {
// Attempt to not use an intermediate buffer by just pushing bytes
// directly onto this string.
let slice = RawSlice {
data: self.bytes.as_ptr().offset(cur_len as int),
len: 4,
};
let slice = slice::from_raw_parts_mut(
self.bytes.as_mut_ptr().offset(cur_len as int),
4
);
let used = encode_utf8_raw(code_point.value, mem::transmute(slice))
.unwrap_or(0);
self.bytes.set_len(cur_len + used);
Expand Down Expand Up @@ -721,10 +720,11 @@ pub fn is_code_point_boundary(slice: &Wtf8, index: uint) -> bool {
/// Copied from core::str::raw::slice_unchecked
#[inline]
pub unsafe fn slice_unchecked(s: &Wtf8, begin: uint, end: uint) -> &Wtf8 {
mem::transmute(RawSlice {
data: s.bytes.as_ptr().offset(begin as int),
len: end - begin,
})
// memory layout of an &[u8] and &Wtf8 are the same
mem::transmute(slice::from_raw_parts(
s.bytes.as_ptr().offset(begin as int),
end - begin
))
}

/// Copied from core::str::raw::slice_error_fail
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
// type is `&mut [u8]`, passes in a pointer to the lvalue and not a
// temporary. Issue #19147.

use std::raw;
use std::mem;
use std::slice;
use std::old_io::IoResult;
Expand All @@ -27,10 +26,10 @@ impl<'a> MyWriter for &'a mut [u8] {

let write_len = buf.len();
unsafe {
*self = mem::transmute(raw::Slice {
data: self.as_ptr().offset(write_len as int),
len: self.len() - write_len,
});
*self = slice::from_raw_parts_mut(
self.as_mut_ptr().offset(write_len as isize),
self.len() - write_len
);
}

Ok(())
Expand Down
19 changes: 10 additions & 9 deletions src/test/run-pass/unsized3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,32 @@

use std::mem;
use std::raw;
use std::slice;

struct Foo<T> {
f: [T],
}

struct Bar {
f1: uint,
f2: [uint],
f1: usize,
f2: [usize],
}

struct Baz {
f1: uint,
f1: usize,
f2: str,
}

trait Tr {
fn foo(&self) -> uint;
fn foo(&self) -> usize;
}

struct St {
f: uint
f: usize
}

impl Tr for St {
fn foo(&self) -> uint {
fn foo(&self) -> usize {
self.f
}
}
Expand Down Expand Up @@ -67,18 +68,18 @@ pub fn main() {
}

let data: Box<Foo_<i32>> = box Foo_{f: [1, 2, 3] };
let x: &Foo<i32> = mem::transmute(raw::Slice { len: 3, data: &*data });
let x: &Foo<i32> = mem::transmute(slice::from_raw_parts(&*data, 3));
assert!(x.f.len() == 3);
assert!(x.f[0] == 1);

struct Baz_ {
f1: uint,
f1: usize,
f2: [u8; 5],
}

let data: Box<_> = box Baz_ {
f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] };
let x: &Baz = mem::transmute( raw::Slice { len: 5, data: &*data } );
let x: &Baz = mem::transmute(slice::from_raw_parts(&*data, 5));
assert!(x.f1 == 42);
let chs: Vec<char> = x.f2.chars().collect();
assert!(chs.len() == 5);
Expand Down