From 4653ad02055e1accae0fce6aad000b01fbe61d20 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Mon, 24 Nov 2014 15:56:34 +1100 Subject: [PATCH] Make syntax::owned_slice a Box<[T]> wrapper. This makes it correct (e.g. avoiding null pointers) and safe. --- src/librustc/middle/typeck/check/mod.rs | 2 +- src/libstd/prelude.rs | 1 + src/libsyntax/owned_slice.rs | 104 ++++-------------------- src/libsyntax/print/pprust.rs | 2 +- 4 files changed, 19 insertions(+), 90 deletions(-) diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 553d80852c2..9c8374da37a 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -5809,7 +5809,7 @@ pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, if !*b { span_err!(ccx.tcx.sess, span, E0091, "type parameter `{}` is unused", - token::get_ident(tps.get(i).ident)); + token::get_ident(tps[i].ident)); } } } diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 65f45c3f97e..fe8648b2202 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -85,6 +85,7 @@ #[doc(no_inline)] pub use slice::{SlicePrelude, AsSlice, CloneSlicePrelude}; #[doc(no_inline)] pub use slice::{VectorVector, PartialEqSlicePrelude, OrdSlicePrelude}; #[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 vec::Vec; diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs index f622e2d6112..747f8c150b4 100644 --- a/src/libsyntax/owned_slice.rs +++ b/src/libsyntax/owned_slice.rs @@ -10,99 +10,39 @@ use std::fmt; use std::default::Default; -use std::hash; -use std::{mem, raw, ptr, slice, vec}; -use std::rt::heap::EMPTY; +use std::vec; use serialize::{Encodable, Decodable, Encoder, Decoder}; -/// A non-growable owned slice. This would preferably become `~[T]` -/// under DST. -#[unsafe_no_drop_flag] // data is set to null on destruction +/// A non-growable owned slice. This is a separate type to allow the +/// representation to change. +#[deriving(Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct OwnedSlice { - /// null iff len == 0 - data: *mut T, - len: uint, + data: Box<[T]> } impl fmt::Show for OwnedSlice { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - try!("OwnedSlice {{".fmt(fmt)); - for i in self.iter() { - try!(i.fmt(fmt)); - } - try!("}}".fmt(fmt)); - Ok(()) - } -} - -#[unsafe_destructor] -impl Drop for OwnedSlice { - 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(); + self.data.fmt(fmt) } } impl OwnedSlice { pub fn empty() -> OwnedSlice { - OwnedSlice { data: ptr::null_mut(), len: 0 } + OwnedSlice { data: box [] } } #[inline(never)] - pub fn from_vec(mut v: Vec) -> OwnedSlice { - let len = v.len(); - - 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 } - } + pub fn from_vec(v: Vec) -> OwnedSlice { + OwnedSlice { data: v.into_boxed_slice() } } #[inline(never)] pub fn into_vec(self) -> Vec { - // null is ok, because len == 0 in that case, as required by Vec. - unsafe { - let ret = Vec::from_raw_parts(self.data, self.len, self.len); - // the vector owns the allocation now - mem::forget(self); - ret - } + self.data.into_vec() } pub fn as_slice<'a>(&'a self) -> &'a [T] { - let ptr = if self.data.is_null() { - // 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() + &*self.data } pub fn move_iter(self) -> vec::MoveItems { @@ -112,10 +52,12 @@ impl OwnedSlice { pub fn map(&self, f: |&T| -> U) -> OwnedSlice { self.iter().map(f).collect() } +} - pub fn len(&self) -> uint { self.len } - - pub fn is_empty(&self) -> bool { self.len == 0 } +impl Deref<[T]> for OwnedSlice { + fn deref(&self) -> &[T] { + self.as_slice() + } } impl Default for OwnedSlice { @@ -130,20 +72,6 @@ impl Clone for OwnedSlice { } } -impl> hash::Hash for OwnedSlice { - fn hash(&self, state: &mut S) { - self.as_slice().hash(state) - } -} - -impl PartialEq for OwnedSlice { - fn eq(&self, other: &OwnedSlice) -> bool { - self.as_slice() == other.as_slice() - } -} - -impl Eq for OwnedSlice {} - impl FromIterator for OwnedSlice { fn from_iter>(mut iter: I) -> OwnedSlice { OwnedSlice::from_vec(iter.collect()) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 8e7804aaa71..0a6f5dabcce 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2458,7 +2458,7 @@ impl<'a> State<'a> { s.print_lifetime_def(lifetime) } else { let idx = idx - generics.lifetimes.len(); - let param = generics.ty_params.get(idx); + let param = &generics.ty_params[idx]; s.print_ty_param(param) } }));