Auto merge of #23333 - oli-obk:slice_from_raw_parts, r=alexcrichton

at least that's what the docs say: http://doc.rust-lang.org/std/slice/fn.from_raw_parts.html

A few situations got prettier. In some situations the mutability of the resulting and source pointers differed (and was cast away by transmute), the mutability matches now.
This commit is contained in:
bors 2015-03-14 08:55:31 +00:00
commit 766a4e1acc
11 changed files with 72 additions and 80 deletions

View File

@ -348,14 +348,8 @@ unsafe fn destroy(&mut self) {
#[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()),
)}
}

View File

@ -24,7 +24,7 @@
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;
@ -468,11 +468,11 @@ pub fn push(&mut self, ch: char) {
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);
}
}

View File

@ -64,7 +64,6 @@
use core::ops;
use core::ptr;
use core::ptr::Unique;
use core::raw::Slice as RawSlice;
use core::slice;
use core::usize;
@ -435,10 +434,7 @@ pub fn as_mut_slice(&mut self) -> &mut [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)
}
}
@ -1560,10 +1556,7 @@ fn as_slice(&self) -> &[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)
}
}
}

View File

@ -29,7 +29,7 @@
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;
@ -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

View File

@ -520,10 +520,10 @@ fn index(&self, index: &ops::Range<usize>) -> &[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
)
}
}
}
@ -559,10 +559,10 @@ fn index_mut(&mut self, index: &ops::Range<usize>) -> &mut [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
)
}
}
}
@ -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)
}
}}
}
@ -898,7 +912,7 @@ fn index_mut(&mut self, index: &ops::RangeFrom<usize>) -> &mut [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)
}
}
@ -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)
}
}
@ -1404,7 +1418,7 @@ 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)
}
}
@ -1412,8 +1426,7 @@ pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] {
#[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)
}
}

View File

@ -14,8 +14,7 @@
use ArchiveRef;
use std::ffi::CString;
use std::mem;
use std::raw;
use std::slice;
use std::path::Path;
pub struct ArchiveRO {
@ -62,10 +61,7 @@ pub fn read<'a>(&'a self, file: &str) -> Option<&'a [u8]> {
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))
}
}
}

View File

@ -26,7 +26,6 @@
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
#![feature(int_uint)]
#![feature(libc)]
#![feature(link_args)]
@ -58,7 +57,7 @@
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,
@ -2226,10 +2225,7 @@ pub enum RustString_opaque {}
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);

View File

@ -931,15 +931,15 @@ fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { (*self).read(buf) }
// 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

View File

@ -29,7 +29,6 @@
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;
@ -214,10 +213,10 @@ fn push_code_point_unchecked(&mut self, code_point: CodePoint) {
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);
@ -725,10 +724,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

View File

@ -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;
@ -27,10 +26,10 @@ fn my_write(&mut self, buf: &[u8]) -> IoResult<()> {
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(())

View File

@ -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
}
}
@ -67,18 +68,18 @@ struct Foo_<T> {
}
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);