Make syntax::owned_slice a Box<[T]> wrapper.
This makes it correct (e.g. avoiding null pointers) and safe.
This commit is contained in:
@@ -5809,7 +5809,7 @@ pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
|||||||
if !*b {
|
if !*b {
|
||||||
span_err!(ccx.tcx.sess, span, E0091,
|
span_err!(ccx.tcx.sess, span, E0091,
|
||||||
"type parameter `{}` is unused",
|
"type parameter `{}` is unused",
|
||||||
token::get_ident(tps.get(i).ident));
|
token::get_ident(tps[i].ident));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,6 +85,7 @@
|
|||||||
#[doc(no_inline)] pub use slice::{SlicePrelude, AsSlice, CloneSlicePrelude};
|
#[doc(no_inline)] pub use slice::{SlicePrelude, AsSlice, CloneSlicePrelude};
|
||||||
#[doc(no_inline)] pub use slice::{VectorVector, PartialEqSlicePrelude, OrdSlicePrelude};
|
#[doc(no_inline)] pub use slice::{VectorVector, PartialEqSlicePrelude, OrdSlicePrelude};
|
||||||
#[doc(no_inline)] pub use slice::{CloneSliceAllocPrelude, OrdSliceAllocPrelude, SliceAllocPrelude};
|
#[doc(no_inline)] pub use slice::{CloneSliceAllocPrelude, OrdSliceAllocPrelude, SliceAllocPrelude};
|
||||||
|
#[doc(no_inline)] pub use slice::{BoxedSlicePrelude};
|
||||||
#[doc(no_inline)] pub use string::{IntoString, String, ToString};
|
#[doc(no_inline)] pub use string::{IntoString, String, ToString};
|
||||||
#[doc(no_inline)] pub use vec::Vec;
|
#[doc(no_inline)] pub use vec::Vec;
|
||||||
|
|
||||||
|
|||||||
@@ -10,99 +10,39 @@
|
|||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::hash;
|
use std::vec;
|
||||||
use std::{mem, raw, ptr, slice, vec};
|
|
||||||
use std::rt::heap::EMPTY;
|
|
||||||
use serialize::{Encodable, Decodable, Encoder, Decoder};
|
use serialize::{Encodable, Decodable, Encoder, Decoder};
|
||||||
|
|
||||||
/// A non-growable owned slice. This would preferably become `~[T]`
|
/// A non-growable owned slice. This is a separate type to allow the
|
||||||
/// under DST.
|
/// representation to change.
|
||||||
#[unsafe_no_drop_flag] // data is set to null on destruction
|
#[deriving(Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct OwnedSlice<T> {
|
pub struct OwnedSlice<T> {
|
||||||
/// null iff len == 0
|
data: Box<[T]>
|
||||||
data: *mut T,
|
|
||||||
len: uint,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:fmt::Show> fmt::Show for OwnedSlice<T> {
|
impl<T:fmt::Show> fmt::Show for OwnedSlice<T> {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
try!("OwnedSlice {{".fmt(fmt));
|
self.data.fmt(fmt)
|
||||||
for i in self.iter() {
|
|
||||||
try!(i.fmt(fmt));
|
|
||||||
}
|
|
||||||
try!("}}".fmt(fmt));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[unsafe_destructor]
|
|
||||||
impl<T> Drop for OwnedSlice<T> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if self.data.is_null() { return }
|
|
||||||
|
|
||||||
// extract the vector
|
|
||||||
let v = mem::replace(self, OwnedSlice::empty());
|
|
||||||
// free via the Vec destructor
|
|
||||||
v.into_vec();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> OwnedSlice<T> {
|
impl<T> OwnedSlice<T> {
|
||||||
pub fn empty() -> OwnedSlice<T> {
|
pub fn empty() -> OwnedSlice<T> {
|
||||||
OwnedSlice { data: ptr::null_mut(), len: 0 }
|
OwnedSlice { data: box [] }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
pub fn from_vec(mut v: Vec<T>) -> OwnedSlice<T> {
|
pub fn from_vec(v: Vec<T>) -> OwnedSlice<T> {
|
||||||
let len = v.len();
|
OwnedSlice { data: v.into_boxed_slice() }
|
||||||
|
|
||||||
if len == 0 {
|
|
||||||
OwnedSlice::empty()
|
|
||||||
} else {
|
|
||||||
// drop excess capacity to avoid breaking sized deallocation
|
|
||||||
v.shrink_to_fit();
|
|
||||||
|
|
||||||
let p = v.as_mut_ptr();
|
|
||||||
// we own the allocation now
|
|
||||||
unsafe { mem::forget(v) }
|
|
||||||
|
|
||||||
OwnedSlice { data: p, len: len }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
pub fn into_vec(self) -> Vec<T> {
|
pub fn into_vec(self) -> Vec<T> {
|
||||||
// null is ok, because len == 0 in that case, as required by Vec.
|
self.data.into_vec()
|
||||||
unsafe {
|
|
||||||
let ret = Vec::from_raw_parts(self.data, self.len, self.len);
|
|
||||||
// the vector owns the allocation now
|
|
||||||
mem::forget(self);
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_slice<'a>(&'a self) -> &'a [T] {
|
pub fn as_slice<'a>(&'a self) -> &'a [T] {
|
||||||
let ptr = if self.data.is_null() {
|
&*self.data
|
||||||
// length zero, i.e. this will never be read as a T.
|
|
||||||
EMPTY as *const T
|
|
||||||
} else {
|
|
||||||
self.data as *const T
|
|
||||||
};
|
|
||||||
|
|
||||||
let slice: &[T] = unsafe {mem::transmute(raw::Slice {
|
|
||||||
data: ptr,
|
|
||||||
len: self.len
|
|
||||||
})};
|
|
||||||
|
|
||||||
slice
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get<'a>(&'a self, i: uint) -> &'a T {
|
|
||||||
self.as_slice().get(i).expect("OwnedSlice: index out of bounds")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter<'r>(&'r self) -> slice::Items<'r, T> {
|
|
||||||
self.as_slice().iter()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_iter(self) -> vec::MoveItems<T> {
|
pub fn move_iter(self) -> vec::MoveItems<T> {
|
||||||
@@ -112,10 +52,12 @@ impl<T> OwnedSlice<T> {
|
|||||||
pub fn map<U>(&self, f: |&T| -> U) -> OwnedSlice<U> {
|
pub fn map<U>(&self, f: |&T| -> U) -> OwnedSlice<U> {
|
||||||
self.iter().map(f).collect()
|
self.iter().map(f).collect()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> uint { self.len }
|
impl<T> Deref<[T]> for OwnedSlice<T> {
|
||||||
|
fn deref(&self) -> &[T] {
|
||||||
pub fn is_empty(&self) -> bool { self.len == 0 }
|
self.as_slice()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Default for OwnedSlice<T> {
|
impl<T> Default for OwnedSlice<T> {
|
||||||
@@ -130,20 +72,6 @@ impl<T: Clone> Clone for OwnedSlice<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: hash::Writer, T: hash::Hash<S>> hash::Hash<S> for OwnedSlice<T> {
|
|
||||||
fn hash(&self, state: &mut S) {
|
|
||||||
self.as_slice().hash(state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: PartialEq> PartialEq for OwnedSlice<T> {
|
|
||||||
fn eq(&self, other: &OwnedSlice<T>) -> bool {
|
|
||||||
self.as_slice() == other.as_slice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Eq> Eq for OwnedSlice<T> {}
|
|
||||||
|
|
||||||
impl<T> FromIterator<T> for OwnedSlice<T> {
|
impl<T> FromIterator<T> for OwnedSlice<T> {
|
||||||
fn from_iter<I: Iterator<T>>(mut iter: I) -> OwnedSlice<T> {
|
fn from_iter<I: Iterator<T>>(mut iter: I) -> OwnedSlice<T> {
|
||||||
OwnedSlice::from_vec(iter.collect())
|
OwnedSlice::from_vec(iter.collect())
|
||||||
|
|||||||
@@ -2458,7 +2458,7 @@ impl<'a> State<'a> {
|
|||||||
s.print_lifetime_def(lifetime)
|
s.print_lifetime_def(lifetime)
|
||||||
} else {
|
} else {
|
||||||
let idx = idx - generics.lifetimes.len();
|
let idx = idx - generics.lifetimes.len();
|
||||||
let param = generics.ty_params.get(idx);
|
let param = &generics.ty_params[idx];
|
||||||
s.print_ty_param(param)
|
s.print_ty_param(param)
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|||||||
Reference in New Issue
Block a user