diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index e07f6dbd35d..955a1a5068b 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -87,6 +87,7 @@
 
 #![doc(primitive = "slice")]
 
+use alloc::boxed::Box;
 use core::cmp;
 use core::mem::size_of;
 use core::mem;
@@ -298,6 +299,23 @@ impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
     fn into_vec(self) -> Vec<T> { self.to_vec() }
 }
 
+#[experimental]
+pub trait BoxedSlice<T> {
+    /// Convert `self` into a vector without clones or allocation.
+    fn into_vec(self) -> Vec<T>;
+}
+
+impl<T> BoxedSlice<T> for Box<[T]> {
+    #[experimental]
+    fn into_vec(mut self) -> Vec<T> {
+        unsafe {
+            let xs = Vec::from_raw_parts(self.len(), self.len(), self.as_mut_ptr());
+            mem::forget(self);
+            xs
+        }
+    }
+}
+
 /// Extension methods for vectors containing `Clone` elements.
 pub trait ImmutableCloneableVector<T> {
     /// Partitions the vector into two vectors `(a, b)`, where all
@@ -2308,6 +2326,13 @@ mod tests {
         let y: &mut [int] = [];
         assert!(y.last_mut().is_none());
     }
+
+    #[test]
+    fn test_into_vec() {
+        let xs = box [1u, 2, 3];
+        let ys = xs.into_vec();
+        assert_eq!(ys.as_slice(), [1u, 2, 3].as_slice());
+    }
 }
 
 #[cfg(test)]
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 894ca3d7f2e..a82856c013d 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -14,6 +14,7 @@
 
 use core::prelude::*;
 
+use alloc::boxed::Box;
 use alloc::heap::{EMPTY, allocate, reallocate, deallocate};
 use core::cmp::max;
 use core::default::Default;
@@ -757,6 +758,20 @@ impl<T> Vec<T> {
         }
     }
 
+    /// Convert the vector into Box<[T]>.
+    ///
+    /// Note that this will drop any excess capacity. Calling this and converting back to a vector
+    /// with `into_vec()` is equivalent to calling `shrink_to_fit()`.
+    #[experimental]
+    pub fn into_boxed_slice(mut self) -> Box<[T]> {
+        self.shrink_to_fit();
+        unsafe {
+            let xs: Box<[T]> = mem::transmute(self.as_mut_slice());
+            mem::forget(self);
+            xs
+        }
+    }
+
     /// Deprecated, call `push` instead
     #[inline]
     #[deprecated = "call .push() instead"]
@@ -1734,7 +1749,7 @@ impl<T> MutableSeq<T> for Vec<T> {
             let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
             if old_size > size { fail!("capacity overflow") }
             unsafe {
-                self.ptr = alloc_or_realloc(self.ptr, self.cap * mem::size_of::<T>(), size);
+                self.ptr = alloc_or_realloc(self.ptr, old_size, size);
             }
             self.cap = max(self.cap, 2) * 2;
         }
@@ -1758,7 +1773,6 @@ impl<T> MutableSeq<T> for Vec<T> {
             }
         }
     }
-
 }
 
 /// An iterator that moves out of a vector.
@@ -2632,6 +2646,13 @@ mod tests {
         assert!(vec2 == vec!((), (), ()));
     }
 
+    #[test]
+    fn test_into_boxed_slice() {
+        let xs = vec![1u, 2, 3];
+        let ys = xs.into_boxed_slice();
+        assert_eq!(ys.as_slice(), [1u, 2, 3].as_slice());
+    }
+
     #[bench]
     fn bench_new(b: &mut Bencher) {
         b.iter(|| {
diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs
index cbd02abff7d..e2a850c58e4 100644
--- a/src/libstd/io/net/tcp.rs
+++ b/src/libstd/io/net/tcp.rs
@@ -18,7 +18,6 @@
 //! listener (socket server) implements the `Listener` and `Acceptor` traits.
 
 use clone::Clone;
-use collections::MutableSeq;
 use io::IoResult;
 use iter::Iterator;
 use slice::ImmutableSlice;
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index ca11a7c04b7..13adfeecf85 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -272,7 +272,9 @@ mod std {
     // The test runner calls ::std::os::args() but really wants realstd
     #[cfg(test)] pub use realstd::os as os;
     // The test runner requires std::slice::Vector, so re-export std::slice just for it.
-    #[cfg(test)] pub use slice;
+    //
+    // It is also used in vec![]
+    pub use slice;
 
-    pub use collections; // vec!() uses MutableSeq
+    pub use boxed; // used for vec![]
 }
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index fa356432a67..1ad3d6eed94 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -323,16 +323,14 @@ macro_rules! try(
 
 /// Create a `std::vec::Vec` containing the arguments.
 #[macro_export]
-macro_rules! vec(
-    ($($e:expr),*) => ({
-        // leading _ to allow empty construction without a warning.
-        let mut _temp = ::std::vec::Vec::new();
-        $(_temp.push($e);)*
-        _temp
+macro_rules! vec[
+    ($($x:expr),*) => ({
+        use std::slice::BoxedSlice;
+        let xs: ::std::boxed::Box<[_]> = box [$($x),*];
+        xs.into_vec()
     });
-    ($($e:expr),+,) => (vec!($($e),+))
-)
-
+    ($($x:expr,)*) => (vec![$($x),*])
+]
 
 /// A macro to select an event from a number of receivers.
 ///
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index abfb2de13c5..db9f3114cda 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -88,7 +88,7 @@
 #[doc(no_inline)] pub use slice::{MutableCloneableSlice, MutableOrdSlice};
 #[doc(no_inline)] pub use slice::{ImmutableSlice, MutableSlice};
 #[doc(no_inline)] pub use slice::{ImmutablePartialEqSlice, ImmutableOrdSlice};
-#[doc(no_inline)] pub use slice::{AsSlice, VectorVector};
+#[doc(no_inline)] pub use slice::{AsSlice, VectorVector, BoxedSlice};
 #[doc(no_inline)] pub use slice::MutableSliceAllocating;
 #[doc(no_inline)] pub use string::String;
 #[doc(no_inline)] pub use vec::Vec;