about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-05-08 21:01:42 -0700
committerbors <bors@rust-lang.org>2014-05-08 21:01:42 -0700
commita990920c6fff9b762c3d0968ff0a5fdcce6d2b39 (patch)
tree8b4cb2edb2e48660ca6e6c0f6a660951f00c1e02 /src/libstd
parentc0a25e4fdc1fcdde8378b4177a6f06c58001a3be (diff)
parentdc30c483810ca0ee3641f4bab8e6f2a44a883fee (diff)
downloadrust-a990920c6fff9b762c3d0968ff0a5fdcce6d2b39.tar.gz
rust-a990920c6fff9b762c3d0968ff0a5fdcce6d2b39.zip
auto merge of #13963 : kballard/rust/remove_owned_vec_from_iterator, r=pcwalton
With `~[T]` no longer growable, the `FromIterator` impl for `~[T]` doesn't make
much sense. Not only that, but nearly everywhere it is used is to convert from
a `Vec<T>` into a `~[T]`, for the sake of maintaining existing APIs. This turns
out to be a performance loss, as it means every API that returns `~[T]`, even a
supposedly non-copying one, is in fact doing extra allocations and memcpy's.
Even `&[T].to_owned()` is going through `Vec<T>` first.

Remove the `FromIterator` impl for `~[T]`, and adjust all the APIs that relied
on it to start using `Vec<T>` instead. This includes rewriting
`&[T].to_owned()` to be more efficient, among other performance wins.

Also add a new mechanism to go from `Vec<T>` -> `~[T]`, just in case anyone
truly needs that, using the new trait `FromVec`.

[breaking-change]
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/ascii.rs87
-rw-r--r--src/libstd/io/mod.rs2
-rw-r--r--src/libstd/io/net/addrinfo.rs6
-rw-r--r--src/libstd/io/process.rs4
-rw-r--r--src/libstd/lib.rs3
-rw-r--r--src/libstd/num/i16.rs3
-rw-r--r--src/libstd/num/i32.rs3
-rw-r--r--src/libstd/num/i64.rs3
-rw-r--r--src/libstd/num/i8.rs3
-rw-r--r--src/libstd/num/int.rs3
-rw-r--r--src/libstd/num/int_macros.rs5
-rw-r--r--src/libstd/num/strconv.rs21
-rw-r--r--src/libstd/num/u16.rs3
-rw-r--r--src/libstd/num/u32.rs3
-rw-r--r--src/libstd/num/u64.rs3
-rw-r--r--src/libstd/num/u8.rs3
-rw-r--r--src/libstd/num/uint.rs3
-rw-r--r--src/libstd/num/uint_macros.rs5
-rw-r--r--src/libstd/os.rs48
-rw-r--r--src/libstd/rt/args.rs43
-rw-r--r--src/libstd/rt/rtio.rs4
-rw-r--r--src/libstd/slice.rs287
-rw-r--r--src/libstd/str.rs189
-rw-r--r--src/libstd/strbuf.rs7
-rw-r--r--src/libstd/sync/arc.rs6
-rw-r--r--src/libstd/sync/deque.rs4
-rw-r--r--src/libstd/unstable/dynamic_lib.rs9
-rw-r--r--src/libstd/vec.rs168
28 files changed, 510 insertions, 418 deletions
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index 5b4400593b4..f45ec8a6742 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -13,7 +13,7 @@
 use to_str::{IntoStr};
 use str;
 use str::Str;
-use str::StrSlice;
+use str::{StrAllocating, StrSlice};
 use str::OwnedStr;
 use container::Container;
 use cast;
@@ -217,14 +217,14 @@ pub trait OwnedAsciiCast {
 
     /// Take ownership and cast to an ascii vector. Fail on non-ASCII input.
     #[inline]
-    fn into_ascii(self) -> ~[Ascii] {
+    fn into_ascii(self) -> Vec<Ascii> {
         assert!(self.is_ascii());
         unsafe {self.into_ascii_nocheck()}
     }
 
     /// Take ownership and cast to an ascii vector. Return None on non-ASCII input.
     #[inline]
-    fn into_ascii_opt(self) -> Option<~[Ascii]> {
+    fn into_ascii_opt(self) -> Option<Vec<Ascii>> {
         if self.is_ascii() {
             Some(unsafe { self.into_ascii_nocheck() })
         } else {
@@ -234,7 +234,7 @@ pub trait OwnedAsciiCast {
 
     /// Take ownership and cast to an ascii vector.
     /// Does not perform validation checks.
-    unsafe fn into_ascii_nocheck(self) -> ~[Ascii];
+    unsafe fn into_ascii_nocheck(self) -> Vec<Ascii>;
 }
 
 impl OwnedAsciiCast for ~[u8] {
@@ -244,8 +244,8 @@ impl OwnedAsciiCast for ~[u8] {
     }
 
     #[inline]
-    unsafe fn into_ascii_nocheck(self) -> ~[Ascii] {
-        cast::transmute(self)
+    unsafe fn into_ascii_nocheck(self) -> Vec<Ascii> {
+        cast::transmute(Vec::from_slice(self.as_slice()))
     }
 }
 
@@ -256,7 +256,20 @@ impl OwnedAsciiCast for ~str {
     }
 
     #[inline]
-    unsafe fn into_ascii_nocheck(self) -> ~[Ascii] {
+    unsafe fn into_ascii_nocheck(self) -> Vec<Ascii> {
+        let v: ~[u8] = cast::transmute(self);
+        v.into_ascii_nocheck()
+    }
+}
+
+impl OwnedAsciiCast for Vec<u8> {
+    #[inline]
+    fn is_ascii(&self) -> bool {
+        self.as_slice().is_ascii()
+    }
+
+    #[inline]
+    unsafe fn into_ascii_nocheck(self) -> Vec<Ascii> {
         cast::transmute(self)
     }
 }
@@ -268,10 +281,10 @@ pub trait AsciiStr {
     fn as_str_ascii<'a>(&'a self) -> &'a str;
 
     /// Convert to vector representing a lower cased ascii string.
-    fn to_lower(&self) -> ~[Ascii];
+    fn to_lower(&self) -> Vec<Ascii>;
 
     /// Convert to vector representing a upper cased ascii string.
-    fn to_upper(&self) -> ~[Ascii];
+    fn to_upper(&self) -> Vec<Ascii>;
 
     /// Compares two Ascii strings ignoring case.
     fn eq_ignore_case(self, other: &[Ascii]) -> bool;
@@ -284,12 +297,12 @@ impl<'a> AsciiStr for &'a [Ascii] {
     }
 
     #[inline]
-    fn to_lower(&self) -> ~[Ascii] {
+    fn to_lower(&self) -> Vec<Ascii> {
         self.iter().map(|a| a.to_lower()).collect()
     }
 
     #[inline]
-    fn to_upper(&self) -> ~[Ascii] {
+    fn to_upper(&self) -> Vec<Ascii> {
         self.iter().map(|a| a.to_upper()).collect()
     }
 
@@ -309,19 +322,21 @@ impl IntoStr for ~[Ascii] {
 impl IntoStr for Vec<Ascii> {
     #[inline]
     fn into_str(self) -> ~str {
-        let v: ~[Ascii] = self.move_iter().collect();
-        unsafe { cast::transmute(v) }
+        unsafe {
+            let s: &str = cast::transmute(self.as_slice());
+            s.to_owned()
+        }
     }
 }
 
-/// Trait to convert to an owned byte array by consuming self
+/// Trait to convert to an owned byte vector by consuming self
 pub trait IntoBytes {
-    /// Converts to an owned byte array by consuming self
-    fn into_bytes(self) -> ~[u8];
+    /// Converts to an owned byte vector by consuming self
+    fn into_bytes(self) -> Vec<u8>;
 }
 
-impl IntoBytes for ~[Ascii] {
-    fn into_bytes(self) -> ~[u8] {
+impl IntoBytes for Vec<Ascii> {
+    fn into_bytes(self) -> Vec<u8> {
         unsafe { cast::transmute(self) }
     }
 }
@@ -404,9 +419,11 @@ unsafe fn str_map_bytes(string: ~str, map: &'static [u8]) -> ~str {
 
 #[inline]
 unsafe fn str_copy_map_bytes(string: &str, map: &'static [u8]) -> ~str {
-    let bytes = string.bytes().map(|b| map[b as uint]).collect::<~[_]>();
-
-    str::raw::from_utf8_owned(bytes)
+    let mut s = string.to_owned();
+    for b in str::raw::as_owned_vec(&mut s).mut_iter() {
+        *b = map[*b as uint];
+    }
+    s
 }
 
 static ASCII_LOWER_MAP: &'static [u8] = &[
@@ -492,7 +509,6 @@ mod tests {
     macro_rules! v2ascii (
         ( [$($e:expr),*]) => (&[$(Ascii{chr:$e}),*]);
         (&[$($e:expr),*]) => (&[$(Ascii{chr:$e}),*]);
-        (~[$($e:expr),*]) => (box [$(Ascii{chr:$e}),*]);
     )
 
     macro_rules! vec2ascii (
@@ -556,20 +572,17 @@ mod tests {
 
     #[test]
     fn test_ascii_vec_ng() {
-        assert_eq!(Vec::from_slice("abCDef&?#".to_ascii().to_lower()).into_str(),
-                   "abcdef&?#".to_owned());
-        assert_eq!(Vec::from_slice("abCDef&?#".to_ascii().to_upper()).into_str(),
-                   "ABCDEF&?#".to_owned());
-        assert_eq!(Vec::from_slice("".to_ascii().to_lower()).into_str(), "".to_owned());
-        assert_eq!(Vec::from_slice("YMCA".to_ascii().to_lower()).into_str(), "ymca".to_owned());
-        assert_eq!(Vec::from_slice("abcDEFxyz:.;".to_ascii().to_upper()).into_str(),
-                   "ABCDEFXYZ:.;".to_owned());
+        assert_eq!("abCDef&?#".to_ascii().to_lower().into_str(), "abcdef&?#".to_owned());
+        assert_eq!("abCDef&?#".to_ascii().to_upper().into_str(), "ABCDEF&?#".to_owned());
+        assert_eq!("".to_ascii().to_lower().into_str(), "".to_owned());
+        assert_eq!("YMCA".to_ascii().to_lower().into_str(), "ymca".to_owned());
+        assert_eq!("abcDEFxyz:.;".to_ascii().to_upper().into_str(), "ABCDEFXYZ:.;".to_owned());
     }
 
     #[test]
     fn test_owned_ascii_vec() {
-        assert_eq!(("( ;".to_owned()).into_ascii(), v2ascii!(~[40, 32, 59]));
-        assert_eq!((box [40u8, 32u8, 59u8]).into_ascii(), v2ascii!(~[40, 32, 59]));
+        assert_eq!(("( ;".to_owned()).into_ascii(), vec2ascii![40, 32, 59]);
+        assert_eq!((box [40u8, 32u8, 59u8]).into_ascii(), vec2ascii![40, 32, 59]);
     }
 
     #[test]
@@ -580,13 +593,13 @@ mod tests {
 
     #[test]
     fn test_ascii_into_str() {
-        assert_eq!(v2ascii!(~[40, 32, 59]).into_str(), "( ;".to_owned());
+        assert_eq!(vec2ascii![40, 32, 59].into_str(), "( ;".to_owned());
         assert_eq!(vec2ascii!(40, 32, 59).into_str(), "( ;".to_owned());
     }
 
     #[test]
     fn test_ascii_to_bytes() {
-        assert_eq!(v2ascii!(~[40, 32, 59]).into_bytes(), box [40u8, 32u8, 59u8]);
+        assert_eq!(vec2ascii![40, 32, 59].into_bytes(), vec![40u8, 32u8, 59u8]);
     }
 
     #[test] #[should_fail]
@@ -625,10 +638,10 @@ mod tests {
         assert_eq!(v.to_ascii_opt(), Some(v2));
         assert_eq!("zoä华".to_ascii_opt(), None);
 
-        assert_eq!((box [40u8, 32u8, 59u8]).into_ascii_opt(), Some(v2ascii!(~[40, 32, 59])));
-        assert_eq!((box [127u8, 128u8, 255u8]).into_ascii_opt(), None);
+        assert_eq!((vec![40u8, 32u8, 59u8]).into_ascii_opt(), Some(vec2ascii![40, 32, 59]));
+        assert_eq!((vec![127u8, 128u8, 255u8]).into_ascii_opt(), None);
 
-        assert_eq!(("( ;".to_owned()).into_ascii_opt(), Some(v2ascii!(~[40, 32, 59])));
+        assert_eq!(("( ;".to_owned()).into_ascii_opt(), Some(vec2ascii![40, 32, 59]));
         assert_eq!(("zoä华".to_owned()).into_ascii_opt(), None);
     }
 
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index a89af05c50a..4a53a064610 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -76,7 +76,7 @@ Some examples of obvious things you might want to do
 
     let path = Path::new("message.txt");
     let mut file = BufferedReader::new(File::open(&path));
-    let lines: ~[~str] = file.lines().map(|x| x.unwrap()).collect();
+    let lines: Vec<~str> = file.lines().map(|x| x.unwrap()).collect();
     ```
 
 * Make a simple TCP client connection and request
diff --git a/src/libstd/io/net/addrinfo.rs b/src/libstd/io/net/addrinfo.rs
index 4006665e886..879c66e0769 100644
--- a/src/libstd/io/net/addrinfo.rs
+++ b/src/libstd/io/net/addrinfo.rs
@@ -24,7 +24,7 @@ use io::IoResult;
 use io::net::ip::{SocketAddr, IpAddr};
 use option::{Option, Some, None};
 use rt::rtio::{IoFactory, LocalIo};
-use slice::OwnedVector;
+use vec::Vec;
 
 /// Hints to the types of sockets that are desired when looking up hosts
 pub enum SocketType {
@@ -73,7 +73,7 @@ pub struct Info {
 
 /// Easy name resolution. Given a hostname, returns the list of IP addresses for
 /// that hostname.
-pub fn get_host_addresses(host: &str) -> IoResult<~[IpAddr]> {
+pub fn get_host_addresses(host: &str) -> IoResult<Vec<IpAddr>> {
     lookup(Some(host), None, None).map(|a| a.move_iter().map(|i| i.address.ip).collect())
 }
 
@@ -90,7 +90,7 @@ pub fn get_host_addresses(host: &str) -> IoResult<~[IpAddr]> {
 /// FIXME: this is not public because the `Hint` structure is not ready for public
 ///      consumption just yet.
 fn lookup(hostname: Option<&str>, servname: Option<&str>, hint: Option<Hint>)
-          -> IoResult<~[Info]> {
+          -> IoResult<Vec<Info>> {
     LocalIo::maybe_raise(|io| io.get_host_addresses(hostname, servname, hint))
 }
 
diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs
index 74f6944f102..3babef6126e 100644
--- a/src/libstd/io/process.rs
+++ b/src/libstd/io/process.rs
@@ -69,7 +69,7 @@ pub struct Process {
 
     /// Extra I/O handles as configured by the original `ProcessConfig` when
     /// this process was created. This is by default empty.
-    pub extra_io: ~[Option<io::PipeStream>],
+    pub extra_io: Vec<Option<io::PipeStream>>,
 }
 
 /// This configuration describes how a new process should be spawned. A blank
@@ -418,7 +418,7 @@ impl Drop for Process {
         drop(self.stdin.take());
         drop(self.stdout.take());
         drop(self.stderr.take());
-        drop(mem::replace(&mut self.extra_io, box []));
+        drop(mem::replace(&mut self.extra_io, Vec::new()));
 
         self.wait();
     }
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 72d41ae1dd2..8a783b6f378 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -278,4 +278,7 @@ mod std {
     pub use ty;
     pub use unstable;
     pub use vec;
+
+    // The test runner requires std::slice::Vector, so re-export std::slice just for it.
+    #[cfg(test)] pub use slice;
 }
diff --git a/src/libstd/num/i16.rs b/src/libstd/num/i16.rs
index 4bd2ba07634..d8f1c108b74 100644
--- a/src/libstd/num/i16.rs
+++ b/src/libstd/num/i16.rs
@@ -11,11 +11,10 @@
 //! Operations and constants for signed 16-bits integers (`i16` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::i16::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/i32.rs b/src/libstd/num/i32.rs
index 3c3acfae3c0..9cc8981fc13 100644
--- a/src/libstd/num/i32.rs
+++ b/src/libstd/num/i32.rs
@@ -11,11 +11,10 @@
 //! Operations and constants for signed 32-bits integers (`i32` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::i32::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/i64.rs b/src/libstd/num/i64.rs
index ad0fe1c08ef..4f7fe32cc70 100644
--- a/src/libstd/num/i64.rs
+++ b/src/libstd/num/i64.rs
@@ -11,11 +11,10 @@
 //! Operations and constants for signed 64-bits integers (`i64` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::i64::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/i8.rs b/src/libstd/num/i8.rs
index bd40a2c53b6..bea315d8683 100644
--- a/src/libstd/num/i8.rs
+++ b/src/libstd/num/i8.rs
@@ -11,11 +11,10 @@
 //! Operations and constants for signed 8-bits integers (`i8` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::i8::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs
index d9552ee3340..d6a7fd1660b 100644
--- a/src/libstd/num/int.rs
+++ b/src/libstd/num/int.rs
@@ -11,11 +11,10 @@
 //! Operations and constants for architecture-sized signed integers (`int` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::int::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs
index 8a7bea46585..fcdb63f5ad5 100644
--- a/src/libstd/num/int_macros.rs
+++ b/src/libstd/num/int_macros.rs
@@ -77,13 +77,16 @@ impl ToStrRadix for $T {
     /// Convert to a string in a given base.
     #[inline]
     fn to_str_radix(&self, radix: uint) -> ~str {
+        use slice::Vector;
+        use str::StrAllocating;
+
         let mut buf = ::vec::Vec::new();
         strconv::int_to_str_bytes_common(*self, radix, strconv::SignNeg, |i| {
             buf.push(i);
         });
         // We know we generated valid utf-8, so we don't need to go through that
         // check.
-        unsafe { str::raw::from_utf8_owned(buf.move_iter().collect()) }
+        unsafe { str::raw::from_utf8(buf.as_slice()).to_owned() }
     }
 }
 
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index 8861597bb4c..4769b17fb2b 100644
--- a/src/libstd/num/strconv.rs
+++ b/src/libstd/num/strconv.rs
@@ -19,11 +19,10 @@ use num::{Float, FPNaN, FPInfinite, ToPrimitive};
 use num;
 use ops::{Add, Sub, Mul, Div, Rem, Neg};
 use option::{None, Option, Some};
-use slice::OwnedVector;
 use slice::{CloneableVector, ImmutableVector, MutableVector};
 use std::cmp::{Ord, Eq};
-use str::{StrSlice};
-use str;
+use str::{StrAllocating, StrSlice};
+use strbuf::StrBuf;
 use vec::Vec;
 
 /// A flag that specifies whether to use exponential (scientific) notation.
@@ -262,7 +261,7 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+
                                   Div<T,T>+Neg<T>+Rem<T,T>+Mul<T,T>>(
         num: T, radix: uint, negative_zero: bool,
         sign: SignFormat, digits: SignificantDigits, exp_format: ExponentFormat, exp_upper: bool
-        ) -> (~[u8], bool) {
+        ) -> (Vec<u8>, bool) {
     assert!(2 <= radix && radix <= 36);
     match exp_format {
         ExpDec if radix >= DIGIT_E_RADIX       // decimal exponent 'e'
@@ -278,17 +277,17 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+
     let _1: T = One::one();
 
     match num.classify() {
-        FPNaN => { return ("NaN".as_bytes().to_owned(), true); }
+        FPNaN => { return (Vec::from_slice("NaN".as_bytes()), true); }
         FPInfinite if num > _0 => {
             return match sign {
-                SignAll => ("+inf".as_bytes().to_owned(), true),
-                _       => ("inf".as_bytes().to_owned(), true)
+                SignAll => (Vec::from_slice("+inf".as_bytes()), true),
+                _       => (Vec::from_slice("inf".as_bytes()), true)
             };
         }
         FPInfinite if num < _0 => {
             return match sign {
-                SignNone => ("inf".as_bytes().to_owned(), true),
-                _        => ("-inf".as_bytes().to_owned(), true),
+                SignNone => (Vec::from_slice("inf".as_bytes()), true),
+                _        => (Vec::from_slice("-inf".as_bytes()), true),
             };
         }
         _ => {}
@@ -483,7 +482,7 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+
         }
     }
 
-    (buf.move_iter().collect(), false)
+    (buf, false)
 }
 
 /**
@@ -498,7 +497,7 @@ pub fn float_to_str_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Float+
         ) -> (~str, bool) {
     let (bytes, special) = float_to_str_bytes_common(num, radix,
                                negative_zero, sign, digits, exp_format, exp_capital);
-    (str::from_utf8_owned(bytes).unwrap(), special)
+    (StrBuf::from_utf8(bytes).unwrap().into_owned(), special)
 }
 
 // Some constants for from_str_bytes_common's input validation,
diff --git a/src/libstd/num/u16.rs b/src/libstd/num/u16.rs
index dd6a838df9b..5c93ca6c36b 100644
--- a/src/libstd/num/u16.rs
+++ b/src/libstd/num/u16.rs
@@ -11,11 +11,10 @@
 //! Operations and constants for unsigned 16-bits integers (`u16` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::u16::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/u32.rs b/src/libstd/num/u32.rs
index bb05938969d..436eae7cd14 100644
--- a/src/libstd/num/u32.rs
+++ b/src/libstd/num/u32.rs
@@ -11,11 +11,10 @@
 //! Operations and constants for unsigned 32-bits integers (`u32` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::u32::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/u64.rs b/src/libstd/num/u64.rs
index f38806e1527..c654d6fbe31 100644
--- a/src/libstd/num/u64.rs
+++ b/src/libstd/num/u64.rs
@@ -11,11 +11,10 @@
 //! Operations and constants for unsigned 64-bits integer (`u64` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::u64::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/u8.rs b/src/libstd/num/u8.rs
index 87fed563a15..7051b9191be 100644
--- a/src/libstd/num/u8.rs
+++ b/src/libstd/num/u8.rs
@@ -11,11 +11,10 @@
 //! Operations and constants for unsigned 8-bits integers (`u8` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::u8::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs
index 61ab97e86b8..d1c3e96b2c9 100644
--- a/src/libstd/num/uint.rs
+++ b/src/libstd/num/uint.rs
@@ -11,11 +11,10 @@
 //! Operations and constants for architecture-sized unsigned integers (`uint` type)
 
 use from_str::FromStr;
-use iter::Iterator;
 use num::{ToStrRadix, FromStrRadix};
 use num::strconv;
 use option::Option;
-use slice::{ImmutableVector, OwnedVector};
+use slice::ImmutableVector;
 use str;
 
 pub use core::uint::{BITS, BYTES, MIN, MAX};
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index 3e64c171613..0795238a49c 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -78,13 +78,16 @@ impl ToStrRadix for $T {
     /// Convert to a string in a given base.
     #[inline]
     fn to_str_radix(&self, radix: uint) -> ~str {
+        use slice::Vector;
+        use str::StrAllocating;
+
         let mut buf = ::vec::Vec::new();
         strconv::int_to_str_bytes_common(*self, radix, strconv::SignNone, |i| {
             buf.push(i);
         });
         // We know we generated valid utf-8, so we don't need to go through that
         // check.
-        unsafe { str::raw::from_utf8_owned(buf.move_iter().collect()) }
+        unsafe { str::raw::from_utf8(buf.as_slice()).to_owned() }
     }
 }
 
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 809757aaf4d..66143b40d52 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -169,7 +169,7 @@ fn with_env_lock<T>(f: || -> T) -> T {
 ///
 /// Invalid UTF-8 bytes are replaced with \uFFFD. See `str::from_utf8_lossy()`
 /// for details.
-pub fn env() -> ~[(~str,~str)] {
+pub fn env() -> Vec<(~str,~str)> {
     env_as_bytes().move_iter().map(|(k,v)| {
         let k = str::from_utf8_lossy(k).into_owned();
         let v = str::from_utf8_lossy(v).into_owned();
@@ -179,7 +179,7 @@ pub fn env() -> ~[(~str,~str)] {
 
 /// Returns a vector of (variable, value) byte-vector pairs for all the
 /// environment variables of the current process.
-pub fn env_as_bytes() -> ~[(~[u8],~[u8])] {
+pub fn env_as_bytes() -> Vec<(~[u8],~[u8])> {
     unsafe {
         #[cfg(windows)]
         unsafe fn get_env_pairs() -> Vec<~[u8]> {
@@ -224,16 +224,16 @@ pub fn env_as_bytes() -> ~[(~[u8],~[u8])] {
         fn env_convert(input: Vec<~[u8]>) -> Vec<(~[u8], ~[u8])> {
             let mut pairs = Vec::new();
             for p in input.iter() {
-                let vs: ~[&[u8]] = p.splitn(1, |b| *b == '=' as u8).collect();
-                let key = vs[0].to_owned();
-                let val = if vs.len() < 2 { box [] } else { vs[1].to_owned() };
+                let mut it = p.splitn(1, |b| *b == '=' as u8);
+                let key = it.next().unwrap().to_owned();
+                let val = it.next().unwrap_or(&[]).to_owned();
                 pairs.push((key, val));
             }
             pairs
         }
         with_env_lock(|| {
             let unparsed_environ = get_env_pairs();
-            env_convert(unparsed_environ).move_iter().collect()
+            env_convert(unparsed_environ)
         })
     }
 }
@@ -416,7 +416,7 @@ pub fn dll_filename(base: &str) -> ~str {
 pub fn self_exe_name() -> Option<Path> {
 
     #[cfg(target_os = "freebsd")]
-    fn load_self() -> Option<~[u8]> {
+    fn load_self() -> Option<Vec<u8>> {
         unsafe {
             use libc::funcs::bsd44::*;
             use libc::consts::os::extra::*;
@@ -436,23 +436,23 @@ pub fn self_exe_name() -> Option<Path> {
             if err != 0 { return None; }
             if sz == 0 { return None; }
             v.set_len(sz as uint - 1); // chop off trailing NUL
-            Some(v.move_iter().collect())
+            Some(v)
         }
     }
 
     #[cfg(target_os = "linux")]
     #[cfg(target_os = "android")]
-    fn load_self() -> Option<~[u8]> {
+    fn load_self() -> Option<Vec<u8>> {
         use std::io;
 
         match io::fs::readlink(&Path::new("/proc/self/exe")) {
-            Ok(path) => Some(path.as_vec().to_owned()),
+            Ok(path) => Some(path.into_vec()),
             Err(..) => None
         }
     }
 
     #[cfg(target_os = "macos")]
-    fn load_self() -> Option<~[u8]> {
+    fn load_self() -> Option<Vec<u8>> {
         unsafe {
             use libc::funcs::extra::_NSGetExecutablePath;
             let mut sz: u32 = 0;
@@ -462,19 +462,19 @@ pub fn self_exe_name() -> Option<Path> {
             let err = _NSGetExecutablePath(v.as_mut_ptr() as *mut i8, &mut sz);
             if err != 0 { return None; }
             v.set_len(sz as uint - 1); // chop off trailing NUL
-            Some(v.move_iter().collect())
+            Some(v)
         }
     }
 
     #[cfg(windows)]
-    fn load_self() -> Option<~[u8]> {
+    fn load_self() -> Option<Vec<u8>> {
         use str::OwnedStr;
 
         unsafe {
             use os::win32::fill_utf16_buf_and_decode;
             fill_utf16_buf_and_decode(|buf, sz| {
                 libc::GetModuleFileNameW(0u as libc::DWORD, buf, sz)
-            }).map(|s| s.into_bytes())
+            }).map(|s| s.into_strbuf().into_bytes())
         }
     }
 
@@ -789,12 +789,12 @@ pub fn get_exit_status() -> int {
 }
 
 #[cfg(target_os = "macos")]
-unsafe fn load_argc_and_argv(argc: int, argv: **c_char) -> ~[~[u8]] {
+unsafe fn load_argc_and_argv(argc: int, argv: **c_char) -> Vec<~[u8]> {
     use c_str::CString;
 
     Vec::from_fn(argc as uint, |i| {
         CString::new(*argv.offset(i as int), false).as_bytes_no_nul().to_owned()
-    }).move_iter().collect()
+    })
 }
 
 /**
@@ -803,7 +803,7 @@ unsafe fn load_argc_and_argv(argc: int, argv: **c_char) -> ~[~[u8]] {
  * Returns a list of the command line arguments.
  */
 #[cfg(target_os = "macos")]
-fn real_args_as_bytes() -> ~[~[u8]] {
+fn real_args_as_bytes() -> Vec<~[u8]> {
     unsafe {
         let (argc, argv) = (*_NSGetArgc() as int,
                             *_NSGetArgv() as **c_char);
@@ -814,7 +814,7 @@ fn real_args_as_bytes() -> ~[~[u8]] {
 #[cfg(target_os = "linux")]
 #[cfg(target_os = "android")]
 #[cfg(target_os = "freebsd")]
-fn real_args_as_bytes() -> ~[~[u8]] {
+fn real_args_as_bytes() -> Vec<~[u8]> {
     use rt;
 
     match rt::args::clone() {
@@ -824,12 +824,12 @@ fn real_args_as_bytes() -> ~[~[u8]] {
 }
 
 #[cfg(not(windows))]
-fn real_args() -> ~[~str] {
+fn real_args() -> Vec<~str> {
     real_args_as_bytes().move_iter().map(|v| str::from_utf8_lossy(v).into_owned()).collect()
 }
 
 #[cfg(windows)]
-fn real_args() -> ~[~str] {
+fn real_args() -> Vec<~str> {
     use slice;
     use option::Expect;
 
@@ -855,11 +855,11 @@ fn real_args() -> ~[~str] {
         LocalFree(szArgList as *c_void);
     }
 
-    return args.move_iter().collect();
+    return args
 }
 
 #[cfg(windows)]
-fn real_args_as_bytes() -> ~[~[u8]] {
+fn real_args_as_bytes() -> Vec<~[u8]> {
     real_args().move_iter().map(|s| s.into_bytes()).collect()
 }
 
@@ -883,13 +883,13 @@ extern "system" {
 ///
 /// The arguments are interpreted as utf-8, with invalid bytes replaced with \uFFFD.
 /// See `str::from_utf8_lossy` for details.
-pub fn args() -> ~[~str] {
+pub fn args() -> Vec<~str> {
     real_args()
 }
 
 /// Returns the arguments which this program was started with (normally passed
 /// via the command line) as byte vectors.
-pub fn args_as_bytes() -> ~[~[u8]] {
+pub fn args_as_bytes() -> Vec<~[u8]> {
     real_args_as_bytes()
 }
 
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs
index ac1692e6bb3..df0f1d8d449 100644
--- a/src/libstd/rt/args.rs
+++ b/src/libstd/rt/args.rs
@@ -21,6 +21,7 @@
 //! FIXME #7756: This has a lot of C glue for lack of globals.
 
 use option::Option;
+use vec::Vec;
 #[cfg(test)] use option::{Some, None};
 #[cfg(test)] use realstd;
 #[cfg(test)] use realargs = realstd::rt::args;
@@ -36,10 +37,10 @@ pub unsafe fn init(argc: int, argv: **u8) { realargs::init(argc, argv) }
 #[cfg(test)]      pub unsafe fn cleanup() { realargs::cleanup() }
 
 /// Take the global arguments from global storage.
-#[cfg(not(test))] pub fn take() -> Option<~[~[u8]]> { imp::take() }
-#[cfg(test)]      pub fn take() -> Option<~[~[u8]]> {
+#[cfg(not(test))] pub fn take() -> Option<Vec<~[u8]>> { imp::take() }
+#[cfg(test)]      pub fn take() -> Option<Vec<~[u8]>> {
     match realargs::take() {
-        realstd::option::Some(a) => Some(a),
+        realstd::option::Some(v) => Some(unsafe{ ::cast::transmute(v) }),
         realstd::option::None => None,
     }
 }
@@ -47,14 +48,14 @@ pub unsafe fn init(argc: int, argv: **u8) { realargs::init(argc, argv) }
 /// Give the global arguments to global storage.
 ///
 /// It is an error if the arguments already exist.
-#[cfg(not(test))] pub fn put(args: ~[~[u8]]) { imp::put(args) }
-#[cfg(test)]      pub fn put(args: ~[~[u8]]) { realargs::put(args) }
+#[cfg(not(test))] pub fn put(args: Vec<~[u8]>) { imp::put(args) }
+#[cfg(test)]      pub fn put(args: Vec<~[u8]>) { realargs::put(unsafe { ::cast::transmute(args) }) }
 
 /// Make a clone of the global arguments.
-#[cfg(not(test))] pub fn clone() -> Option<~[~[u8]]> { imp::clone() }
-#[cfg(test)]      pub fn clone() -> Option<~[~[u8]]> {
+#[cfg(not(test))] pub fn clone() -> Option<Vec<~[u8]>> { imp::clone() }
+#[cfg(test)]      pub fn clone() -> Option<Vec<~[u8]>> {
     match realargs::clone() {
-        realstd::option::Some(a) => Some(a),
+        realstd::option::Some(v) => Some(unsafe { ::cast::transmute(v) }),
         realstd::option::None => None,
     }
 }
@@ -70,6 +71,7 @@ mod imp {
     use owned::Box;
     use unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
     use mem;
+    use vec::Vec;
     #[cfg(not(test))] use ptr::RawPtr;
 
     static mut global_args_ptr: uint = 0;
@@ -87,15 +89,15 @@ mod imp {
         lock.destroy();
     }
 
-    pub fn take() -> Option<~[~[u8]]> {
+    pub fn take() -> Option<Vec<~[u8]>> {
         with_lock(|| unsafe {
             let ptr = get_global_ptr();
             let val = mem::replace(&mut *ptr, None);
-            val.as_ref().map(|s: &Box<~[~[u8]]>| (**s).clone())
+            val.as_ref().map(|s: &Box<Vec<~[u8]>>| (**s).clone())
         })
     }
 
-    pub fn put(args: ~[~[u8]]) {
+    pub fn put(args: Vec<~[u8]>) {
         with_lock(|| unsafe {
             let ptr = get_global_ptr();
             rtassert!((*ptr).is_none());
@@ -103,10 +105,10 @@ mod imp {
         })
     }
 
-    pub fn clone() -> Option<~[~[u8]]> {
+    pub fn clone() -> Option<Vec<~[u8]>> {
         with_lock(|| unsafe {
             let ptr = get_global_ptr();
-            (*ptr).as_ref().map(|s: &Box<~[~[u8]]>| (**s).clone())
+            (*ptr).as_ref().map(|s: &Box<Vec<~[u8]>>| (**s).clone())
         })
     }
 
@@ -117,13 +119,13 @@ mod imp {
         }
     }
 
-    fn get_global_ptr() -> *mut Option<Box<~[~[u8]]>> {
+    fn get_global_ptr() -> *mut Option<Box<Vec<~[u8]>>> {
         unsafe { cast::transmute(&global_args_ptr) }
     }
 
     // Copied from `os`.
     #[cfg(not(test))]
-    unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~[u8]] {
+    unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> Vec<~[u8]> {
         use c_str::CString;
         use ptr::RawPtr;
         use libc;
@@ -133,7 +135,7 @@ mod imp {
         Vec::from_fn(argc as uint, |i| {
             let cs = CString::new(*(argv as **libc::c_char).offset(i as int), false);
             cs.as_bytes_no_nul().to_owned()
-        }).move_iter().collect()
+        })
     }
 
     #[cfg(test)]
@@ -147,7 +149,7 @@ mod imp {
             // Preserve the actual global state.
             let saved_value = take();
 
-            let expected = box [bytes!("happy").to_owned(), bytes!("today?").to_owned()];
+            let expected = vec![bytes!("happy").to_owned(), bytes!("today?").to_owned()];
 
             put(expected.clone());
             assert!(clone() == Some(expected.clone()));
@@ -170,6 +172,7 @@ mod imp {
 #[cfg(target_os = "win32", not(test))]
 mod imp {
     use option::Option;
+    use vec::Vec;
 
     pub unsafe fn init(_argc: int, _argv: **u8) {
     }
@@ -177,15 +180,15 @@ mod imp {
     pub fn cleanup() {
     }
 
-    pub fn take() -> Option<~[~[u8]]> {
+    pub fn take() -> Option<Vec<~[u8]>> {
         fail!()
     }
 
-    pub fn put(_args: ~[~[u8]]) {
+    pub fn put(_args: Vec<~[u8]>) {
         fail!()
     }
 
-    pub fn clone() -> Option<~[~[u8]]> {
+    pub fn clone() -> Option<Vec<~[u8]>> {
         fail!()
     }
 }
diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs
index 16882624ab7..ccde8d9c96a 100644
--- a/src/libstd/rt/rtio.rs
+++ b/src/libstd/rt/rtio.rs
@@ -161,7 +161,7 @@ pub trait IoFactory {
     fn unix_connect(&mut self, path: &CString,
                     timeout: Option<u64>) -> IoResult<Box<RtioPipe:Send>>;
     fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
-                          hint: Option<ai::Hint>) -> IoResult<~[ai::Info]>;
+                          hint: Option<ai::Hint>) -> IoResult<Vec<ai::Info>>;
 
     // filesystem operations
     fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior)
@@ -191,7 +191,7 @@ pub trait IoFactory {
     fn timer_init(&mut self) -> IoResult<Box<RtioTimer:Send>>;
     fn spawn(&mut self, config: ProcessConfig)
             -> IoResult<(Box<RtioProcess:Send>,
-                         ~[Option<Box<RtioPipe:Send>>])>;
+                         Vec<Option<Box<RtioPipe:Send>>>)>;
     fn kill(&mut self, pid: libc::pid_t, signal: int) -> IoResult<()>;
     fn pipe_open(&mut self, fd: c_int) -> IoResult<Box<RtioPipe:Send>>;
     fn tty_open(&mut self, fd: c_int, readable: bool)
diff --git a/src/libstd/slice.rs b/src/libstd/slice.rs
index c7cefbb28ee..21084407b8d 100644
--- a/src/libstd/slice.rs
+++ b/src/libstd/slice.rs
@@ -127,23 +127,23 @@ pub trait VectorVector<T> {
     // FIXME #5898: calling these .concat and .connect conflicts with
     // StrVector::con{cat,nect}, since they have generic contents.
     /// Flattens a vector of vectors of T into a single vector of T.
-    fn concat_vec(&self) -> ~[T];
+    fn concat_vec(&self) -> Vec<T>;
 
     /// Concatenate a vector of vectors, placing a given separator between each.
-    fn connect_vec(&self, sep: &T) -> ~[T];
+    fn connect_vec(&self, sep: &T) -> Vec<T>;
 }
 
 impl<'a, T: Clone, V: Vector<T>> VectorVector<T> for &'a [V] {
-    fn concat_vec(&self) -> ~[T] {
+    fn concat_vec(&self) -> Vec<T> {
         let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
         let mut result = Vec::with_capacity(size);
         for v in self.iter() {
             result.push_all(v.as_slice())
         }
-        result.move_iter().collect()
+        result
     }
 
-    fn connect_vec(&self, sep: &T) -> ~[T] {
+    fn connect_vec(&self, sep: &T) -> Vec<T> {
         let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
         let mut result = Vec::with_capacity(size + self.len());
         let mut first = true;
@@ -151,29 +151,10 @@ impl<'a, T: Clone, V: Vector<T>> VectorVector<T> for &'a [V] {
             if first { first = false } else { result.push(sep.clone()) }
             result.push_all(v.as_slice())
         }
-        result.move_iter().collect()
+        result
     }
 }
 
-/**
- * Convert an iterator of pairs into a pair of vectors.
- *
- * Returns a tuple containing two vectors where the i-th element of the first
- * vector contains the first element of the i-th tuple of the input iterator,
- * and the i-th element of the second vector contains the second element
- * of the i-th tuple of the input iterator.
- */
-pub fn unzip<T, U, V: Iterator<(T, U)>>(mut iter: V) -> (~[T], ~[U]) {
-    let (lo, _) = iter.size_hint();
-    let mut ts = Vec::with_capacity(lo);
-    let mut us = Vec::with_capacity(lo);
-    for (t, u) in iter {
-        ts.push(t);
-        us.push(u);
-    }
-    (ts.move_iter().collect(), us.move_iter().collect())
-}
-
 /// An Iterator that yields the element swaps needed to produce
 /// a sequence of all possible permutations for an indexed sequence of
 /// elements. Each permutation is only a single swap apart.
@@ -185,7 +166,7 @@ pub fn unzip<T, U, V: Iterator<(T, U)>>(mut iter: V) -> (~[T], ~[U]) {
 /// The last generated swap is always (0, 1), and it returns the
 /// sequence to its initial order.
 pub struct ElementSwaps {
-    sdir: ~[SizeDirection],
+    sdir: Vec<SizeDirection>,
     /// If true, emit the last swap that returns the sequence to initial state
     emit_reset: bool,
     swaps_made : uint,
@@ -199,9 +180,7 @@ impl ElementSwaps {
         // element (equal to the original index).
         ElementSwaps{
             emit_reset: true,
-            sdir: range(0, length)
-                    .map(|i| SizeDirection{ size: i, dir: Neg })
-                    .collect::<~[_]>(),
+            sdir: range(0, length).map(|i| SizeDirection{ size: i, dir: Neg }).collect(),
             swaps_made: 0
         }
     }
@@ -228,12 +207,12 @@ impl Iterator<(uint, uint)> for ElementSwaps {
         let max = self.sdir.iter().map(|&x| x).enumerate()
                            .filter(|&(i, sd)|
                                 new_pos(i, sd.dir) < self.sdir.len() &&
-                                self.sdir[new_pos(i, sd.dir)].size < sd.size)
+                                self.sdir.get(new_pos(i, sd.dir)).size < sd.size)
                            .max_by(|&(_, sd)| sd.size);
         match max {
             Some((i, sd)) => {
                 let j = new_pos(i, sd.dir);
-                self.sdir.swap(i, j);
+                self.sdir.as_mut_slice().swap(i, j);
 
                 // Swap the direction of each larger SizeDirection
                 for x in self.sdir.mut_iter() {
@@ -314,16 +293,29 @@ impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
     /// Returns a copy of `v`.
     #[inline]
     fn to_owned(&self) -> ~[T] {
+        use RawVec = core::raw::Vec;
+        use rt::global_heap::{malloc_raw, exchange_free};
+        use num::{CheckedAdd, CheckedMul};
+        use option::Expect;
+
         let len = self.len();
-        let mut result = Vec::with_capacity(len);
-        // Unsafe code so this can be optimised to a memcpy (or something
-        // similarly fast) when T is Copy. LLVM is easily confused, so any
-        // extra operations during the loop can prevent this optimisation
+        let data_size = len.checked_mul(&mem::size_of::<T>());
+        let data_size = data_size.expect("overflow in to_owned()");
+        let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
+        let size = size.expect("overflow in to_owned()");
+
         unsafe {
+            let ret = malloc_raw(size) as *mut RawVec<()>;
+
+            (*ret).fill = len * mem::nonzero_size_of::<T>();
+            (*ret).alloc = len * mem::nonzero_size_of::<T>();
+
+            // Be careful with the following loop. We want it to be optimized
+            // to a memcpy (or something similarly fast) when T is Copy. LLVM
+            // is easily confused, so any extra operations during the loop can
+            // prevent this optimization.
             let mut i = 0;
-            let p = result.as_mut_ptr();
-            // Use try_finally here otherwise the write to length
-            // inside the loop stops LLVM from optimising this.
+            let p = &mut (*ret).data as *mut _ as *mut T;
             try_finally(
                 &mut i, (),
                 |i, ()| while *i < len {
@@ -332,9 +324,15 @@ impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
                         self.unsafe_ref(*i).clone());
                     *i += 1;
                 },
-                |i| result.set_len(*i));
+                |i| if *i < len {
+                    // we must be failing, clean up after ourselves
+                    for j in range(0, *i as int) {
+                        ptr::read(&*p.offset(j));
+                    }
+                    exchange_free(ret as *u8);
+                });
+            cast::transmute(ret)
         }
-        result.move_iter().collect()
     }
 
     #[inline(always)]
@@ -354,7 +352,7 @@ impl<T: Clone> CloneableVector<T> for ~[T] {
 pub trait ImmutableCloneableVector<T> {
     /// Partitions the vector into two vectors `(A,B)`, where all
     /// elements of `A` satisfy `f` and all elements of `B` do not.
-    fn partitioned(&self, f: |&T| -> bool) -> (~[T], ~[T]);
+    fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>);
 
     /// Create an iterator that yields every possible permutation of the
     /// vector in succession.
@@ -363,7 +361,7 @@ pub trait ImmutableCloneableVector<T> {
 
 impl<'a,T:Clone> ImmutableCloneableVector<T> for &'a [T] {
     #[inline]
-    fn partitioned(&self, f: |&T| -> bool) -> (~[T], ~[T]) {
+    fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
         let mut lefts  = Vec::new();
         let mut rights = Vec::new();
 
@@ -375,7 +373,7 @@ impl<'a,T:Clone> ImmutableCloneableVector<T> for &'a [T] {
             }
         }
 
-        (lefts.move_iter().collect(), rights.move_iter().collect())
+        (lefts, rights)
     }
 
     fn permutations(self) -> Permutations<T> {
@@ -412,7 +410,7 @@ pub trait OwnedVector<T> {
      * Partitions the vector into two vectors `(A,B)`, where all
      * elements of `A` satisfy `f` and all elements of `B` do not.
      */
-    fn partition(self, f: |&T| -> bool) -> (~[T], ~[T]);
+    fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>);
 }
 
 impl<T> OwnedVector<T> for ~[T] {
@@ -432,7 +430,7 @@ impl<T> OwnedVector<T> for ~[T] {
     }
 
     #[inline]
-    fn partition(self, f: |&T| -> bool) -> (~[T], ~[T]) {
+    fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
         let mut lefts  = Vec::new();
         let mut rights = Vec::new();
 
@@ -444,7 +442,7 @@ impl<T> OwnedVector<T> for ~[T] {
             }
         }
 
-        (lefts.move_iter().collect(), rights.move_iter().collect())
+        (lefts, rights)
     }
 }
 
@@ -729,45 +727,10 @@ impl<'a, T: TotalOrd> MutableTotalOrdVector<T> for &'a mut [T] {
     }
 }
 
-/**
-* Constructs a vector from an unsafe pointer to a buffer
-*
-* # Arguments
-*
-* * ptr - An unsafe pointer to a buffer of `T`
-* * elts - The number of elements in the buffer
-*/
-// Wrapper for fn in raw: needs to be called by net_tcp::on_tcp_read_cb
-pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> ~[T] {
-    raw::from_buf_raw(ptr, elts)
-}
-
 /// Unsafe operations
 pub mod raw {
-    use iter::Iterator;
-    use ptr;
-    use slice::{MutableVector, OwnedVector};
-    use vec::Vec;
-
     pub use core::slice::raw::{buf_as_slice, mut_buf_as_slice};
     pub use core::slice::raw::{shift_ptr, pop_ptr};
-
-    /**
-    * Constructs a vector from an unsafe pointer to a buffer
-    *
-    * # Arguments
-    *
-    * * ptr - An unsafe pointer to a buffer of `T`
-    * * elts - The number of elements in the buffer
-    */
-    // Was in raw, but needs to be called by net_tcp::on_tcp_read_cb
-    #[inline]
-    pub unsafe fn from_buf_raw<T>(ptr: *T, elts: uint) -> ~[T] {
-        let mut dst = Vec::with_capacity(elts);
-        dst.set_len(elts);
-        ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
-        dst.move_iter().collect()
-    }
 }
 
 /// An iterator that moves out of a vector.
@@ -828,31 +791,6 @@ mod tests {
     fn is_odd(n: &uint) -> bool { *n % 2u == 1u }
 
     #[test]
-    fn test_unsafe_ptrs() {
-        unsafe {
-            // Test on-stack copy-from-buf.
-            let a = box [1, 2, 3];
-            let mut ptr = a.as_ptr();
-            let b = from_buf(ptr, 3u);
-            assert_eq!(b.len(), 3u);
-            assert_eq!(b[0], 1);
-            assert_eq!(b[1], 2);
-            assert_eq!(b[2], 3);
-
-            // Test on-heap copy-from-buf.
-            let c = box [1, 2, 3, 4, 5];
-            ptr = c.as_ptr();
-            let d = from_buf(ptr, 5u);
-            assert_eq!(d.len(), 5u);
-            assert_eq!(d[0], 1);
-            assert_eq!(d[1], 2);
-            assert_eq!(d[2], 3);
-            assert_eq!(d[3], 4);
-            assert_eq!(d[4], 5);
-        }
-    }
-
-    #[test]
     fn test_from_fn() {
         // Test on-stack from_fn.
         let mut v = Vec::from_fn(3u, square);
@@ -1231,17 +1169,6 @@ mod tests {
     }
 
     #[test]
-    fn test_zip_unzip() {
-        let z1 = vec![(1, 4), (2, 5), (3, 6)];
-
-        let (left, right) = unzip(z1.iter().map(|&x| x));
-
-        assert_eq!((1, 4), (left[0], right[0]));
-        assert_eq!((2, 5), (left[1], right[1]));
-        assert_eq!((3, 6), (left[2], right[2]));
-    }
-
-    #[test]
     fn test_element_swaps() {
         let mut v = [1, 2, 3];
         for (i, (a, b)) in ElementSwaps::new(v.len()).enumerate() {
@@ -1425,7 +1352,7 @@ mod tests {
                         let n = task_rng().gen::<uint>() % 10;
                         counts[n] += 1;
                         (n, counts[n])
-                    }).collect::<~[(uint, int)]>();
+                    }).collect::<Vec<(uint, int)>>();
 
                 // only sort on the first element, so an unstable sort
                 // may mix up the counts.
@@ -1436,46 +1363,45 @@ mod tests {
                 // will need to be ordered with increasing
                 // counts... i.e. exactly asserting that this sort is
                 // stable.
-                assert!(v.windows(2).all(|w| w[0] <= w[1]));
+                assert!(v.as_slice().windows(2).all(|w| w[0] <= w[1]));
             }
         }
     }
 
     #[test]
     fn test_partition() {
-        assert_eq!((box []).partition(|x: &int| *x < 3), (box [], box []));
-        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 4), (box [1, 2, 3], box []));
-        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 2), (box [1], box [2, 3]));
-        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 0), (box [], box [1, 2, 3]));
+        assert_eq!((box []).partition(|x: &int| *x < 3), (vec![], vec![]));
+        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
+        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 2), (vec![1], vec![2, 3]));
+        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
     }
 
     #[test]
     fn test_partitioned() {
-        assert_eq!(([]).partitioned(|x: &int| *x < 3), (box [], box []))
-        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 4), (box [1, 2, 3], box []));
-        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 2), (box [1], box [2, 3]));
-        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 0), (box [], box [1, 2, 3]));
+        assert_eq!(([]).partitioned(|x: &int| *x < 3), (vec![], vec![]));
+        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
+        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 2), (vec![1], vec![2, 3]));
+        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
     }
 
     #[test]
     fn test_concat() {
         let v: [~[int], ..0] = [];
-        assert_eq!(v.concat_vec(), box []);
-        assert_eq!([box [1], box [2,3]].concat_vec(), box [1, 2, 3]);
+        assert_eq!(v.concat_vec(), vec![]);
+        assert_eq!([box [1], box [2,3]].concat_vec(), vec![1, 2, 3]);
 
-        assert_eq!([&[1], &[2,3]].concat_vec(), box [1, 2, 3]);
+        assert_eq!([&[1], &[2,3]].concat_vec(), vec![1, 2, 3]);
     }
 
     #[test]
     fn test_connect() {
         let v: [~[int], ..0] = [];
-        assert_eq!(v.connect_vec(&0), box []);
-        assert_eq!([box [1], box [2, 3]].connect_vec(&0), box [1, 0, 2, 3]);
-        assert_eq!([box [1], box [2], box [3]].connect_vec(&0), box [1, 0, 2, 0, 3]);
+        assert_eq!(v.connect_vec(&0), vec![]);
+        assert_eq!([box [1], box [2, 3]].connect_vec(&0), vec![1, 0, 2, 3]);
+        assert_eq!([box [1], box [2], box [3]].connect_vec(&0), vec![1, 0, 2, 0, 3]);
 
-        assert_eq!(v.connect_vec(&0), box []);
-        assert_eq!([&[1], &[2, 3]].connect_vec(&0), box [1, 0, 2, 3]);
-        assert_eq!([&[1], &[2], &[3]].connect_vec(&0), box [1, 0, 2, 0, 3]);
+        assert_eq!([&[1], &[2, 3]].connect_vec(&0), vec![1, 0, 2, 3]);
+        assert_eq!([&[1], &[2], &[3]].connect_vec(&0), vec![1, 0, 2, 0, 3]);
     }
 
     #[test]
@@ -1773,74 +1699,74 @@ mod tests {
     fn test_splitator() {
         let xs = &[1i,2,3,4,5];
 
-        assert_eq!(xs.split(|x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   box [&[1], &[3], &[5]]);
-        assert_eq!(xs.split(|x| *x == 1).collect::<~[&[int]]>(),
-                   box [&[], &[2,3,4,5]]);
-        assert_eq!(xs.split(|x| *x == 5).collect::<~[&[int]]>(),
-                   box [&[1,2,3,4], &[]]);
-        assert_eq!(xs.split(|x| *x == 10).collect::<~[&[int]]>(),
-                   box [&[1,2,3,4,5]]);
-        assert_eq!(xs.split(|_| true).collect::<~[&[int]]>(),
-                   box [&[], &[], &[], &[], &[], &[]]);
+        assert_eq!(xs.split(|x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1], &[3], &[5]]);
+        assert_eq!(xs.split(|x| *x == 1).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[], &[2,3,4,5]]);
+        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1,2,3,4], &[]]);
+        assert_eq!(xs.split(|x| *x == 10).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1,2,3,4,5]]);
+        assert_eq!(xs.split(|_| true).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[], &[], &[], &[], &[], &[]]);
 
         let xs: &[int] = &[];
-        assert_eq!(xs.split(|x| *x == 5).collect::<~[&[int]]>(), box [&[]]);
+        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[int]>>().as_slice(), &[&[]]);
     }
 
     #[test]
     fn test_splitnator() {
         let xs = &[1i,2,3,4,5];
 
-        assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   box [&[1,2,3,4,5]]);
-        assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   box [&[1], &[3,4,5]]);
-        assert_eq!(xs.splitn(3, |_| true).collect::<~[&[int]]>(),
-                   box [&[], &[], &[], &[4,5]]);
+        assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1,2,3,4,5]]);
+        assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1], &[3,4,5]]);
+        assert_eq!(xs.splitn(3, |_| true).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[], &[], &[], &[4,5]]);
 
         let xs: &[int] = &[];
-        assert_eq!(xs.splitn(1, |x| *x == 5).collect::<~[&[int]]>(), box [&[]]);
+        assert_eq!(xs.splitn(1, |x| *x == 5).collect::<Vec<&[int]>>().as_slice(), &[&[]]);
     }
 
     #[test]
     fn test_rsplitator() {
         let xs = &[1i,2,3,4,5];
 
-        assert_eq!(xs.split(|x| *x % 2 == 0).rev().collect::<~[&[int]]>(),
-                   box [&[5], &[3], &[1]]);
-        assert_eq!(xs.split(|x| *x == 1).rev().collect::<~[&[int]]>(),
-                   box [&[2,3,4,5], &[]]);
-        assert_eq!(xs.split(|x| *x == 5).rev().collect::<~[&[int]]>(),
-                   box [&[], &[1,2,3,4]]);
-        assert_eq!(xs.split(|x| *x == 10).rev().collect::<~[&[int]]>(),
-                   box [&[1,2,3,4,5]]);
+        assert_eq!(xs.split(|x| *x % 2 == 0).rev().collect::<Vec<&[int]>>().as_slice(),
+                   &[&[5], &[3], &[1]]);
+        assert_eq!(xs.split(|x| *x == 1).rev().collect::<Vec<&[int]>>().as_slice(),
+                   &[&[2,3,4,5], &[]]);
+        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[int]>>().as_slice(),
+                   &[&[], &[1,2,3,4]]);
+        assert_eq!(xs.split(|x| *x == 10).rev().collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1,2,3,4,5]]);
 
         let xs: &[int] = &[];
-        assert_eq!(xs.split(|x| *x == 5).rev().collect::<~[&[int]]>(), box [&[]]);
+        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[int]>>().as_slice(), &[&[]]);
     }
 
     #[test]
     fn test_rsplitnator() {
         let xs = &[1,2,3,4,5];
 
-        assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   box [&[1,2,3,4,5]]);
-        assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   box [&[5], &[1,2,3]]);
-        assert_eq!(xs.rsplitn(3, |_| true).collect::<~[&[int]]>(),
-                   box [&[], &[], &[], &[1,2]]);
+        assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1,2,3,4,5]]);
+        assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[5], &[1,2,3]]);
+        assert_eq!(xs.rsplitn(3, |_| true).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[], &[], &[], &[1,2]]);
 
         let xs: &[int] = &[];
-        assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<~[&[int]]>(), box [&[]]);
+        assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<Vec<&[int]>>().as_slice(), &[&[]]);
     }
 
     #[test]
     fn test_windowsator() {
         let v = &[1i,2,3,4];
 
-        assert_eq!(v.windows(2).collect::<~[&[int]]>(), box [&[1,2], &[2,3], &[3,4]]);
-        assert_eq!(v.windows(3).collect::<~[&[int]]>(), box [&[1i,2,3], &[2,3,4]]);
+        assert_eq!(v.windows(2).collect::<Vec<&[int]>>().as_slice(), &[&[1,2], &[2,3], &[3,4]]);
+        assert_eq!(v.windows(3).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2,3], &[2,3,4]]);
         assert!(v.windows(6).next().is_none());
     }
 
@@ -1855,11 +1781,11 @@ mod tests {
     fn test_chunksator() {
         let v = &[1i,2,3,4,5];
 
-        assert_eq!(v.chunks(2).collect::<~[&[int]]>(), box [&[1i,2], &[3,4], &[5]]);
-        assert_eq!(v.chunks(3).collect::<~[&[int]]>(), box [&[1i,2,3], &[4,5]]);
-        assert_eq!(v.chunks(6).collect::<~[&[int]]>(), box [&[1i,2,3,4,5]]);
+        assert_eq!(v.chunks(2).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2], &[3,4], &[5]]);
+        assert_eq!(v.chunks(3).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2,3], &[4,5]]);
+        assert_eq!(v.chunks(6).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2,3,4,5]]);
 
-        assert_eq!(v.chunks(2).rev().collect::<~[&[int]]>(), box [&[5i], &[3,4], &[1,2]]);
+        assert_eq!(v.chunks(2).rev().collect::<Vec<&[int]>>().as_slice(), &[&[5i], &[3,4], &[1,2]]);
         let mut it = v.chunks(2);
         assert_eq!(it.indexable(), 3);
         assert_eq!(it.idx(0).unwrap(), &[1,2]);
@@ -2238,15 +2164,6 @@ mod bench {
     }
 
     #[bench]
-    fn add(b: &mut Bencher) {
-        let xs: &[int] = [5, ..10];
-        let ys: &[int] = [5, ..10];
-        b.iter(|| {
-            xs + ys;
-        });
-    }
-
-    #[bench]
     fn concat(b: &mut Bencher) {
         let xss: Vec<Vec<uint>> = Vec::from_fn(100, |i| range(0, i).collect());
         b.iter(|| {
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 666c0a58b33..fb3dcc97287 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -85,10 +85,9 @@ use fmt;
 use io::Writer;
 use iter::{Iterator, range, AdditiveIterator};
 use option::{None, Option, Some};
-use ptr;
 use from_str::FromStr;
-use slice::{OwnedVector, ImmutableVector, MutableVector};
-use slice::{Vector};
+use slice::{ImmutableVector, MutableVector, CloneableVector};
+use slice::Vector;
 use vec::Vec;
 use default::Default;
 use strbuf::StrBuf;
@@ -668,25 +667,22 @@ impl<'a> fmt::Show for MaybeOwned<'a> {
 /// Unsafe operations
 pub mod raw {
     use cast;
-    use iter::Iterator;
     use libc;
     use ptr::RawPtr;
-    use ptr;
-    use slice::{MutableVector, OwnedVector, Vector};
-    use str::{is_utf8};
-    use vec::Vec;
+    use raw::Slice;
+    use slice::CloneableVector;
+    use str::{is_utf8, StrAllocating};
 
     pub use core::str::raw::{from_utf8, c_str_to_static_slice, slice_bytes};
     pub use core::str::raw::{slice_unchecked};
 
     /// Create a Rust string from a *u8 buffer of the given length
     pub unsafe fn from_buf_len(buf: *u8, len: uint) -> ~str {
-        let mut v = Vec::with_capacity(len);
-        ptr::copy_memory(v.as_mut_ptr(), buf, len);
-        v.set_len(len);
-
-        assert!(is_utf8(v.as_slice()));
-        ::cast::transmute(v.move_iter().collect::<~[u8]>())
+        let v = Slice { data: buf, len: len };
+        let bytes: &[u8] = ::cast::transmute(v);
+        assert!(is_utf8(bytes));
+        let s: &str = ::cast::transmute(bytes);
+        s.to_owned()
     }
 
     #[lang="strdup_uniq"]
@@ -824,27 +820,23 @@ pub trait StrAllocating: Str {
     /// Copy a slice into a new owned str.
     #[inline]
     fn to_owned(&self) -> ~str {
-        let me = self.as_slice();
-        let len = me.len();
-        unsafe {
-            let mut v = Vec::with_capacity(len);
+        use slice::Vector;
 
-            ptr::copy_memory(v.as_mut_ptr(), me.as_ptr(), len);
-            v.set_len(len);
-            ::cast::transmute(v.move_iter().collect::<~[u8]>())
+        unsafe {
+            ::cast::transmute(self.as_slice().as_bytes().to_owned())
         }
     }
 
     /// Converts to a vector of `u16` encoded as UTF-16.
-    fn to_utf16(&self) -> ~[u16] {
+    fn to_utf16(&self) -> Vec<u16> {
         let me = self.as_slice();
-        let mut u = Vec::new();;
+        let mut u = Vec::new();
         for ch in me.chars() {
             let mut buf = [0u16, ..2];
             let n = ch.encode_utf16(buf /* as mut slice! */);
             u.push_all(buf.slice_to(n));
         }
-        u.move_iter().collect()
+        u
     }
 
     /// Given a string, make a new string with repeated copies of it.
@@ -1554,7 +1546,8 @@ mod tests {
         assert_eq!(a.subslice_offset(c), 0);
 
         let string = "a\nb\nc";
-        let lines: ~[&str] = string.lines().collect();
+        let lines: Vec<&str> = string.lines().collect();
+        let lines = lines.as_slice();
         assert_eq!(string.subslice_offset(lines[0]), 0);
         assert_eq!(string.subslice_offset(lines[1]), 2);
         assert_eq!(string.subslice_offset(lines[2]), 4);
@@ -1617,13 +1610,13 @@ mod tests {
     fn test_utf16() {
         let pairs =
             [("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n".to_owned(),
-              box [0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
+              vec![0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
                 0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16,
                 0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16,
                 0xd800_u16, 0xdf30_u16, 0x000a_u16]),
 
              ("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n".to_owned(),
-              box [0xd801_u16, 0xdc12_u16, 0xd801_u16,
+              vec![0xd801_u16, 0xdc12_u16, 0xd801_u16,
                 0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
                 0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
                 0xdc4b_u16, 0x0020_u16, 0xd801_u16, 0xdc0f_u16,
@@ -1631,7 +1624,7 @@ mod tests {
                 0x000a_u16]),
 
              ("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n".to_owned(),
-              box [0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
+              vec![0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
                 0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16,
                 0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16,
                 0x00b7_u16, 0xd800_u16, 0xdf0c_u16, 0xd800_u16,
@@ -1640,7 +1633,7 @@ mod tests {
                 0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),
 
              ("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n".to_owned(),
-              box [0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
+              vec![0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
                 0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16,
                 0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16,
                 0x0020_u16, 0xd801_u16, 0xdc95_u16, 0xd801_u16,
@@ -1653,18 +1646,18 @@ mod tests {
                 0x000a_u16 ]),
              // Issue #12318, even-numbered non-BMP planes
              ("\U00020000".to_owned(),
-              box [0xD840, 0xDC00])];
+              vec![0xD840, 0xDC00])];
 
         for p in pairs.iter() {
             let (s, u) = (*p).clone();
-            assert!(is_utf16(u));
+            assert!(is_utf16(u.as_slice()));
             assert_eq!(s.to_utf16(), u);
 
-            assert_eq!(from_utf16(u).unwrap(), s);
-            assert_eq!(from_utf16_lossy(u), s);
+            assert_eq!(from_utf16(u.as_slice()).unwrap(), s);
+            assert_eq!(from_utf16_lossy(u.as_slice()), s);
 
-            assert_eq!(from_utf16(s.to_utf16()).unwrap(), s);
-            assert_eq!(from_utf16(u).unwrap().to_utf16(), u);
+            assert_eq!(from_utf16(s.to_utf16().as_slice()).unwrap(), s);
+            assert_eq!(from_utf16(u.as_slice()).unwrap().to_utf16(), u);
         }
     }
 
@@ -1921,105 +1914,105 @@ mod tests {
     fn test_split_char_iterator() {
         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
 
-        let split: ~[&str] = data.split(' ').collect();
-        assert_eq!( split, box ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+        let split: Vec<&str> = data.split(' ').collect();
+        assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
-        let mut rsplit: ~[&str] = data.split(' ').rev().collect();
+        let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
         rsplit.reverse();
-        assert_eq!(rsplit, box ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+        assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
-        let split: ~[&str] = data.split(|c: char| c == ' ').collect();
-        assert_eq!( split, box ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+        let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
+        assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
-        let mut rsplit: ~[&str] = data.split(|c: char| c == ' ').rev().collect();
+        let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
         rsplit.reverse();
-        assert_eq!(rsplit, box ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+        assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
 
         // Unicode
-        let split: ~[&str] = data.split('ä').collect();
-        assert_eq!( split, box ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+        let split: Vec<&str> = data.split('ä').collect();
+        assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
 
-        let mut rsplit: ~[&str] = data.split('ä').rev().collect();
+        let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
         rsplit.reverse();
-        assert_eq!(rsplit, box ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+        assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
 
-        let split: ~[&str] = data.split(|c: char| c == 'ä').collect();
-        assert_eq!( split, box ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+        let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
+        assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
 
-        let mut rsplit: ~[&str] = data.split(|c: char| c == 'ä').rev().collect();
+        let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
         rsplit.reverse();
-        assert_eq!(rsplit, box ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+        assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
     }
 
     #[test]
     fn test_splitn_char_iterator() {
         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
 
-        let split: ~[&str] = data.splitn(' ', 3).collect();
-        assert_eq!(split, box ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
+        let split: Vec<&str> = data.splitn(' ', 3).collect();
+        assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
 
-        let split: ~[&str] = data.splitn(|c: char| c == ' ', 3).collect();
-        assert_eq!(split, box ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
+        let split: Vec<&str> = data.splitn(|c: char| c == ' ', 3).collect();
+        assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
 
         // Unicode
-        let split: ~[&str] = data.splitn('ä', 3).collect();
-        assert_eq!(split, box ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
+        let split: Vec<&str> = data.splitn('ä', 3).collect();
+        assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
 
-        let split: ~[&str] = data.splitn(|c: char| c == 'ä', 3).collect();
-        assert_eq!(split, box ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
+        let split: Vec<&str> = data.splitn(|c: char| c == 'ä', 3).collect();
+        assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
     }
 
     #[test]
     fn test_rsplitn_char_iterator() {
         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
 
-        let mut split: ~[&str] = data.rsplitn(' ', 3).collect();
+        let mut split: Vec<&str> = data.rsplitn(' ', 3).collect();
         split.reverse();
-        assert_eq!(split, box ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
+        assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
 
-        let mut split: ~[&str] = data.rsplitn(|c: char| c == ' ', 3).collect();
+        let mut split: Vec<&str> = data.rsplitn(|c: char| c == ' ', 3).collect();
         split.reverse();
-        assert_eq!(split, box ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
+        assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
 
         // Unicode
-        let mut split: ~[&str] = data.rsplitn('ä', 3).collect();
+        let mut split: Vec<&str> = data.rsplitn('ä', 3).collect();
         split.reverse();
-        assert_eq!(split, box ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
+        assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
 
-        let mut split: ~[&str] = data.rsplitn(|c: char| c == 'ä', 3).collect();
+        let mut split: Vec<&str> = data.rsplitn(|c: char| c == 'ä', 3).collect();
         split.reverse();
-        assert_eq!(split, box ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
+        assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
     }
 
     #[test]
     fn test_split_char_iterator_no_trailing() {
         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
 
-        let split: ~[&str] = data.split('\n').collect();
-        assert_eq!(split, box ["", "Märy häd ä little lämb", "Little lämb", ""]);
+        let split: Vec<&str> = data.split('\n').collect();
+        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]);
 
-        let split: ~[&str] = data.split_terminator('\n').collect();
-        assert_eq!(split, box ["", "Märy häd ä little lämb", "Little lämb"]);
+        let split: Vec<&str> = data.split_terminator('\n').collect();
+        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]);
     }
 
     #[test]
     fn test_rev_split_char_iterator_no_trailing() {
         let data = "\nMäry häd ä little lämb\nLittle lämb\n";
 
-        let mut split: ~[&str] = data.split('\n').rev().collect();
+        let mut split: Vec<&str> = data.split('\n').rev().collect();
         split.reverse();
-        assert_eq!(split, box ["", "Märy häd ä little lämb", "Little lämb", ""]);
+        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]);
 
-        let mut split: ~[&str] = data.split_terminator('\n').rev().collect();
+        let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
         split.reverse();
-        assert_eq!(split, box ["", "Märy häd ä little lämb", "Little lämb"]);
+        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]);
     }
 
     #[test]
     fn test_words() {
         let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
-        let words: ~[&str] = data.words().collect();
-        assert_eq!(words, box ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
+        let words: Vec<&str> = data.words().collect();
+        assert_eq!(words, vec!["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
     }
 
     #[test]
@@ -2053,34 +2046,34 @@ mod tests {
     #[test]
     fn test_lines() {
         let data = "\nMäry häd ä little lämb\n\nLittle lämb\n";
-        let lines: ~[&str] = data.lines().collect();
-        assert_eq!(lines, box ["", "Märy häd ä little lämb", "", "Little lämb"]);
+        let lines: Vec<&str> = data.lines().collect();
+        assert_eq!(lines, vec!["", "Märy häd ä little lämb", "", "Little lämb"]);
 
         let data = "\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
-        let lines: ~[&str] = data.lines().collect();
-        assert_eq!(lines, box ["", "Märy häd ä little lämb", "", "Little lämb"]);
+        let lines: Vec<&str> = data.lines().collect();
+        assert_eq!(lines, vec!["", "Märy häd ä little lämb", "", "Little lämb"]);
     }
 
     #[test]
     fn test_split_strator() {
-        fn t<'a>(s: &str, sep: &'a str, u: ~[&str]) {
-            let v: ~[&str] = s.split_str(sep).collect();
-            assert_eq!(v, u);
+        fn t(s: &str, sep: &str, u: &[&str]) {
+            let v: Vec<&str> = s.split_str(sep).collect();
+            assert_eq!(v.as_slice(), u.as_slice());
         }
-        t("--1233345--", "12345", box ["--1233345--"]);
-        t("abc::hello::there", "::", box ["abc", "hello", "there"]);
-        t("::hello::there", "::", box ["", "hello", "there"]);
-        t("hello::there::", "::", box ["hello", "there", ""]);
-        t("::hello::there::", "::", box ["", "hello", "there", ""]);
-        t("ประเทศไทย中华Việt Nam", "中华", box ["ประเทศไทย", "Việt Nam"]);
-        t("zzXXXzzYYYzz", "zz", box ["", "XXX", "YYY", ""]);
-        t("zzXXXzYYYz", "XXX", box ["zz", "zYYYz"]);
-        t(".XXX.YYY.", ".", box ["", "XXX", "YYY", ""]);
-        t("", ".", box [""]);
-        t("zz", "zz", box ["",""]);
-        t("ok", "z", box ["ok"]);
-        t("zzz", "zz", box ["","z"]);
-        t("zzzzz", "zz", box ["","","z"]);
+        t("--1233345--", "12345", ["--1233345--"]);
+        t("abc::hello::there", "::", ["abc", "hello", "there"]);
+        t("::hello::there", "::", ["", "hello", "there"]);
+        t("hello::there::", "::", ["hello", "there", ""]);
+        t("::hello::there::", "::", ["", "hello", "there", ""]);
+        t("ประเทศไทย中华Việt Nam", "中华", ["ประเทศไทย", "Việt Nam"]);
+        t("zzXXXzzYYYzz", "zz", ["", "XXX", "YYY", ""]);
+        t("zzXXXzYYYz", "XXX", ["zz", "zYYYz"]);
+        t(".XXX.YYY.", ".", ["", "XXX", "YYY", ""]);
+        t("", ".", [""]);
+        t("zz", "zz", ["",""]);
+        t("ok", "z", ["ok"]);
+        t("zzz", "zz", ["","z"]);
+        t("zzzzz", "zz", ["","","z"]);
     }
 
     #[test]
diff --git a/src/libstd/strbuf.rs b/src/libstd/strbuf.rs
index ad703b8054b..8e05b2f527d 100644
--- a/src/libstd/strbuf.rs
+++ b/src/libstd/strbuf.rs
@@ -19,7 +19,7 @@ use io::Writer;
 use iter::{Extendable, FromIterator, Iterator, range};
 use option::{None, Option, Some};
 use ptr::RawPtr;
-use slice::{OwnedVector, Vector};
+use slice::{OwnedVector, Vector, CloneableVector};
 use str::{OwnedStr, Str, StrSlice, StrAllocating};
 use str;
 use vec::Vec;
@@ -273,11 +273,8 @@ impl Str for StrBuf {
 impl StrAllocating for StrBuf {
     #[inline]
     fn into_owned(self) -> ~str {
-        let StrBuf {
-            vec: vec
-        } = self;
         unsafe {
-            cast::transmute::<~[u8],~str>(vec.move_iter().collect())
+            cast::transmute(self.vec.as_slice().to_owned())
         }
     }
 
diff --git a/src/libstd/sync/arc.rs b/src/libstd/sync/arc.rs
index d277c514e44..676c836c459 100644
--- a/src/libstd/sync/arc.rs
+++ b/src/libstd/sync/arc.rs
@@ -69,14 +69,14 @@ impl<T: Send> UnsafeArc<T> {
 
     /// As new(), but returns a vector of as many pre-cloned handles as
     /// requested.
-    pub fn newN(data: T, num_handles: uint) -> ~[UnsafeArc<T>] {
+    pub fn newN(data: T, num_handles: uint) -> Vec<UnsafeArc<T>> {
         unsafe {
             if num_handles == 0 {
-                box [] // need to free data here
+                vec![] // need to free data here
             } else {
                 let ptr = new_inner(data, num_handles);
                 let v = Vec::from_fn(num_handles, |_| UnsafeArc { data: ptr });
-                v.move_iter().collect()
+                v
             }
         }
     }
diff --git a/src/libstd/sync/deque.rs b/src/libstd/sync/deque.rs
index d06062f02ac..8dfd691e6ff 100644
--- a/src/libstd/sync/deque.rs
+++ b/src/libstd/sync/deque.rs
@@ -407,7 +407,7 @@ mod tests {
     use rand::Rng;
     use sync::atomics::{AtomicBool, INIT_ATOMIC_BOOL, SeqCst,
                         AtomicUint, INIT_ATOMIC_UINT};
-    use slice;
+    use vec;
 
     #[test]
     fn smoke() {
@@ -603,7 +603,7 @@ mod tests {
         let mut pool = BufferPool::<(int, uint)>::new();
         let (mut w, s) = pool.deque();
 
-        let (threads, hits) = slice::unzip(range(0, NTHREADS).map(|_| {
+        let (threads, hits) = vec::unzip(range(0, NTHREADS).map(|_| {
             let s = s.clone();
             let unique_box = box AtomicUint::new(0);
             let thread_box = unsafe {
diff --git a/src/libstd/unstable/dynamic_lib.rs b/src/libstd/unstable/dynamic_lib.rs
index 68f0aaab05b..e2a9f6a5c48 100644
--- a/src/libstd/unstable/dynamic_lib.rs
+++ b/src/libstd/unstable/dynamic_lib.rs
@@ -18,13 +18,16 @@ A simple wrapper over the platform's dynamic library facilities
 
 use c_str::ToCStr;
 use cast;
+use iter::Iterator;
 use ops::*;
 use option::*;
 use os;
 use path::GenericPath;
 use path;
 use result::*;
+use slice::{Vector,OwnedVector};
 use str;
+use vec::Vec;
 
 pub struct DynamicLibrary { handle: *u8}
 
@@ -73,8 +76,10 @@ impl DynamicLibrary {
             ("LD_LIBRARY_PATH", ':' as u8)
         };
         let newenv = os::getenv_as_bytes(envvar).unwrap_or(box []);
-        let newenv = newenv + &[sep] + path.as_vec();
-        os::setenv(envvar, str::from_utf8(newenv).unwrap());
+        let mut newenv = newenv.move_iter().collect::<Vec<_>>();
+        newenv.push_all(&[sep]);
+        newenv.push_all(path.as_vec());
+        os::setenv(envvar, str::from_utf8(newenv.as_slice()).unwrap());
     }
 
     /// Access the value at the symbol of the dynamic library
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index af146b96e50..da01da26709 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -22,12 +22,13 @@ use mem::{size_of, move_val_init};
 use mem;
 use num;
 use num::{CheckedMul, CheckedAdd};
-use ops::Drop;
+use ops::{Add, Drop};
 use option::{None, Option, Some, Expect};
 use ptr::RawPtr;
 use ptr;
 use rt::global_heap::{malloc_raw, realloc_raw};
 use raw::Slice;
+use RawVec = raw::Vec;
 use slice::{ImmutableEqVector, ImmutableVector, Items, MutItems, MutableVector};
 use slice::{MutableTotalOrdVector, OwnedVector, Vector};
 use slice::{MutableVectorAllocating};
@@ -1370,6 +1371,16 @@ impl<T> Vector<T> for Vec<T> {
     }
 }
 
+impl<T: Clone, V: Vector<T>> Add<V, Vec<T>> for Vec<T> {
+    #[inline]
+    fn add(&self, rhs: &V) -> Vec<T> {
+        let mut res = Vec::with_capacity(self.len() + rhs.as_slice().len());
+        res.push_all(self.as_slice());
+        res.push_all(rhs.as_slice());
+        res
+    }
+}
+
 #[unsafe_destructor]
 impl<T> Drop for Vec<T> {
     fn drop(&mut self) {
@@ -1436,10 +1447,94 @@ impl<T> Drop for MoveItems<T> {
     }
 }
 
+/**
+ * Convert an iterator of pairs into a pair of vectors.
+ *
+ * Returns a tuple containing two vectors where the i-th element of the first
+ * vector contains the first element of the i-th tuple of the input iterator,
+ * and the i-th element of the second vector contains the second element
+ * of the i-th tuple of the input iterator.
+ */
+pub fn unzip<T, U, V: Iterator<(T, U)>>(mut iter: V) -> (Vec<T>, Vec<U>) {
+    let (lo, _) = iter.size_hint();
+    let mut ts = Vec::with_capacity(lo);
+    let mut us = Vec::with_capacity(lo);
+    for (t, u) in iter {
+        ts.push(t);
+        us.push(u);
+    }
+    (ts, us)
+}
+
+/// Mechanism to convert from a `Vec<T>` to a `[T]`.
+///
+/// In a post-DST world this will be used to convert to any `Ptr<[T]>`.
+///
+/// This could be implemented on more types than just pointers to vectors, but
+/// the recommended approach for those types is to implement `FromIterator`.
+// FIXME(#12938): Update doc comment when DST lands
+pub trait FromVec<T> {
+    /// Convert a `Vec<T>` into the receiver type.
+    fn from_vec(v: Vec<T>) -> Self;
+}
+
+impl<T> FromVec<T> for ~[T] {
+    fn from_vec(mut v: Vec<T>) -> ~[T] {
+        let len = v.len();
+        let data_size = len.checked_mul(&mem::size_of::<T>());
+        let data_size = data_size.expect("overflow in from_vec()");
+        let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
+        let size = size.expect("overflow in from_vec()");
+
+        // In a post-DST world, we can attempt to reuse the Vec allocation by calling
+        // shrink_to_fit() on it. That may involve a reallocation+memcpy, but that's no
+        // diffrent than what we're doing manually here.
+
+        let vp = v.as_mut_ptr();
+
+        unsafe {
+            let ret = malloc_raw(size) as *mut RawVec<()>;
+
+            (*ret).fill = len * mem::nonzero_size_of::<T>();
+            (*ret).alloc = len * mem::nonzero_size_of::<T>();
+
+            ptr::copy_nonoverlapping_memory(&mut (*ret).data as *mut _ as *mut u8,
+                                            vp as *u8, data_size);
+
+            // we've transferred ownership of the contents from v, but we can't drop it
+            // as it still needs to free its own allocation.
+            v.set_len(0);
+
+            transmute(ret)
+        }
+    }
+}
+
+/// Unsafe operations
+pub mod raw {
+    use super::Vec;
+    use ptr;
+
+    /// Constructs a vector from an unsafe pointer to a buffer.
+    ///
+    /// The elements of the buffer are copied into the vector without cloning,
+    /// as if `ptr::read()` were called on them.
+    #[inline]
+    pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> Vec<T> {
+        let mut dst = Vec::with_capacity(elts);
+        dst.set_len(elts);
+        ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), ptr, elts);
+        dst
+    }
+}
+
+
 #[cfg(test)]
 mod tests {
     use prelude::*;
     use mem::size_of;
+    use kinds::marker;
+    use super::{unzip, raw, FromVec};
 
     #[test]
     fn test_small_vec_struct() {
@@ -1649,4 +1744,75 @@ mod tests {
         unsafe { v.set_len(0); }
         assert_eq!(v.mut_iter().len(), 0);
     }
+
+    #[test]
+    fn test_partition() {
+        assert_eq!(vec![].partition(|x: &int| *x < 3), (vec![], vec![]));
+        assert_eq!(vec![1, 2, 3].partition(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
+        assert_eq!(vec![1, 2, 3].partition(|x: &int| *x < 2), (vec![1], vec![2, 3]));
+        assert_eq!(vec![1, 2, 3].partition(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
+    }
+
+    #[test]
+    fn test_partitioned() {
+        assert_eq!(vec![].partitioned(|x: &int| *x < 3), (vec![], vec![]))
+        assert_eq!(vec![1, 2, 3].partitioned(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
+        assert_eq!(vec![1, 2, 3].partitioned(|x: &int| *x < 2), (vec![1], vec![2, 3]));
+        assert_eq!(vec![1, 2, 3].partitioned(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
+    }
+
+    #[test]
+    fn test_zip_unzip() {
+        let z1 = vec![(1, 4), (2, 5), (3, 6)];
+
+        let (left, right) = unzip(z1.iter().map(|&x| x));
+
+        let (left, right) = (left.as_slice(), right.as_slice());
+        assert_eq!((1, 4), (left[0], right[0]));
+        assert_eq!((2, 5), (left[1], right[1]));
+        assert_eq!((3, 6), (left[2], right[2]));
+    }
+
+    #[test]
+    fn test_unsafe_ptrs() {
+        unsafe {
+            // Test on-stack copy-from-buf.
+            let a = [1, 2, 3];
+            let ptr = a.as_ptr();
+            let b = raw::from_buf(ptr, 3u);
+            assert_eq!(b, vec![1, 2, 3]);
+
+            // Test on-heap copy-from-buf.
+            let c = box [1, 2, 3, 4, 5];
+            let ptr = c.as_ptr();
+            let d = raw::from_buf(ptr, 5u);
+            assert_eq!(d, vec![1, 2, 3, 4, 5]);
+        }
+    }
+
+    #[test]
+    fn test_from_vec() {
+        let a = vec![1u, 2, 3];
+        let b: ~[uint] = FromVec::from_vec(a);
+        assert_eq!(b.as_slice(), &[1u, 2, 3]);
+
+        let a = vec![];
+        let b: ~[u8] = FromVec::from_vec(a);
+        assert_eq!(b.as_slice(), &[]);
+
+        let a = vec!["one".to_owned(), "two".to_owned()];
+        let b: ~[~str] = FromVec::from_vec(a);
+        assert_eq!(b.as_slice(), &["one".to_owned(), "two".to_owned()]);
+
+        struct Foo {
+            x: uint,
+            nocopy: marker::NoCopy
+        }
+
+        let a = vec![Foo{x: 42, nocopy: marker::NoCopy}, Foo{x: 84, nocopy: marker::NoCopy}];
+        let b: ~[Foo] = FromVec::from_vec(a);
+        assert_eq!(b.len(), 2);
+        assert_eq!(b[0].x, 42);
+        assert_eq!(b[1].x, 84);
+    }
 }