about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/compiletest/runtest.rs4
-rw-r--r--src/doc/guide-ffi.md6
-rw-r--r--src/doc/guide-tasks.md24
-rw-r--r--src/doc/guide-testing.md6
-rw-r--r--src/doc/guide-unsafe.md4
-rw-r--r--src/doc/tutorial.md4
-rwxr-xr-xsrc/etc/unicode.py6
-rw-r--r--src/libarena/lib.rs4
-rw-r--r--src/libcollections/bitv.rs22
-rw-r--r--src/libcollections/deque.rs4
-rw-r--r--src/libcollections/hashmap.rs10
-rw-r--r--src/libcollections/priority_queue.rs4
-rw-r--r--src/libcollections/ringbuf.rs4
-rw-r--r--src/libcollections/smallintmap.rs8
-rw-r--r--src/libcollections/trie.rs8
-rw-r--r--src/libgetopts/lib.rs4
-rw-r--r--src/libgreen/lib.rs6
-rw-r--r--src/liblog/directive.rs2
-rw-r--r--src/liblog/lib.rs6
-rw-r--r--src/libnative/io/file_unix.rs6
-rw-r--r--src/libnative/io/file_win32.rs5
-rw-r--r--src/libnative/io/process.rs8
-rw-r--r--src/libnum/bigint.rs10
-rw-r--r--src/libnum/rational.rs2
-rw-r--r--src/librand/isaac.rs12
-rw-r--r--src/librand/lib.rs10
-rw-r--r--src/librustc/back/archive.rs2
-rw-r--r--src/librustc/back/link.rs4
-rw-r--r--src/librustc/back/mips.rs2
-rw-r--r--src/librustc/back/rpath.rs6
-rw-r--r--src/librustc/back/target_strs.rs2
-rw-r--r--src/librustc/driver/driver.rs15
-rw-r--r--src/librustc/driver/session.rs4
-rw-r--r--src/librustc/front/config.rs2
-rw-r--r--src/librustc/front/feature_gate.rs2
-rw-r--r--src/librustc/front/std_inject.rs6
-rw-r--r--src/librustc/front/test.rs6
-rw-r--r--src/librustc/lib.rs6
-rw-r--r--src/librustc/metadata/creader.rs2
-rw-r--r--src/librustc/metadata/csearch.rs6
-rw-r--r--src/librustc/metadata/cstore.rs2
-rw-r--r--src/librustc/metadata/decoder.rs2
-rw-r--r--src/librustc/metadata/encoder.rs2
-rw-r--r--src/librustc/metadata/filesearch.rs2
-rw-r--r--src/librustc/metadata/loader.rs8
-rw-r--r--src/librustc/metadata/tydecode.rs5
-rw-r--r--src/librustc/metadata/tyencode.rs11
-rw-r--r--src/librustc/middle/astencode.rs2
-rw-r--r--src/librustc/middle/borrowck/check_loans.rs6
-rw-r--r--src/librustc/middle/borrowck/gather_loans/mod.rs120
-rw-r--r--src/librustc/middle/borrowck/gather_loans/restrictions.rs6
-rw-r--r--src/librustc/middle/borrowck/mod.rs27
-rw-r--r--src/librustc/middle/borrowck/move_data.rs2
-rw-r--r--src/librustc/middle/cfg/construct.rs2
-rw-r--r--src/librustc/middle/check_const.rs2
-rw-r--r--src/librustc/middle/check_match.rs22
-rw-r--r--src/librustc/middle/check_static.rs25
-rw-r--r--src/librustc/middle/const_eval.rs2
-rw-r--r--src/librustc/middle/dataflow.rs6
-rw-r--r--src/librustc/middle/dead.rs2
-rw-r--r--src/librustc/middle/entry.rs2
-rw-r--r--src/librustc/middle/freevars.rs2
-rw-r--r--src/librustc/middle/graph.rs2
-rw-r--r--src/librustc/middle/kind.rs10
-rw-r--r--src/librustc/middle/lang_items.rs24
-rw-r--r--src/librustc/middle/lint.rs6
-rw-r--r--src/librustc/middle/liveness.rs2
-rw-r--r--src/librustc/middle/mem_categorization.rs33
-rw-r--r--src/librustc/middle/moves.rs2
-rw-r--r--src/librustc/middle/pat_util.rs2
-rw-r--r--src/librustc/middle/privacy.rs2
-rw-r--r--src/librustc/middle/reachable.rs2
-rw-r--r--src/librustc/middle/region.rs2
-rw-r--r--src/librustc/middle/resolve.rs2
-rw-r--r--src/librustc/middle/resolve_lifetime.rs2
-rw-r--r--src/librustc/middle/subst.rs2
-rw-r--r--src/librustc/middle/trans/_match.rs26
-rw-r--r--src/librustc/middle/trans/adt.rs10
-rw-r--r--src/librustc/middle/trans/asm.rs2
-rw-r--r--src/librustc/middle/trans/base.rs4
-rw-r--r--src/librustc/middle/trans/builder.rs2
-rw-r--r--src/librustc/middle/trans/cabi.rs20
-rw-r--r--src/librustc/middle/trans/cabi_arm.rs2
-rw-r--r--src/librustc/middle/trans/cabi_mips.rs2
-rw-r--r--src/librustc/middle/trans/cabi_x86.rs17
-rw-r--r--src/librustc/middle/trans/cabi_x86_64.rs2
-rw-r--r--src/librustc/middle/trans/callee.rs10
-rw-r--r--src/librustc/middle/trans/closure.rs2
-rw-r--r--src/librustc/middle/trans/common.rs2
-rw-r--r--src/librustc/middle/trans/consts.rs12
-rw-r--r--src/librustc/middle/trans/context.rs2
-rw-r--r--src/librustc/middle/trans/debuginfo.rs10
-rw-r--r--src/librustc/middle/trans/expr.rs6
-rw-r--r--src/librustc/middle/trans/foreign.rs12
-rw-r--r--src/librustc/middle/trans/glue.rs2
-rw-r--r--src/librustc/middle/trans/intrinsic.rs2
-rw-r--r--src/librustc/middle/trans/meth.rs8
-rw-r--r--src/librustc/middle/trans/monomorphize.rs2
-rw-r--r--src/librustc/middle/trans/reflect.rs18
-rw-r--r--src/librustc/middle/trans/type_.rs6
-rw-r--r--src/librustc/middle/trans/type_of.rs2
-rw-r--r--src/librustc/middle/ty.rs133
-rw-r--r--src/librustc/middle/ty_fold.rs18
-rw-r--r--src/librustc/middle/typeck/astconv.rs2
-rw-r--r--src/librustc/middle/typeck/check/_match.rs2
-rw-r--r--src/librustc/middle/typeck/check/method.rs28
-rw-r--r--src/librustc/middle/typeck/check/mod.rs12
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs6
-rw-r--r--src/librustc/middle/typeck/check/regionmanip.rs2
-rw-r--r--src/librustc/middle/typeck/check/vtable.rs10
-rw-r--r--src/librustc/middle/typeck/check/writeback.rs2
-rw-r--r--src/librustc/middle/typeck/coherence.rs10
-rw-r--r--src/librustc/middle/typeck/collect.rs10
-rw-r--r--src/librustc/middle/typeck/infer/coercion.rs20
-rw-r--r--src/librustc/middle/typeck/infer/combine.rs20
-rw-r--r--src/librustc/middle/typeck/infer/error_reporting.rs2
-rw-r--r--src/librustc/middle/typeck/infer/lattice.rs2
-rw-r--r--src/librustc/middle/typeck/infer/mod.rs5
-rw-r--r--src/librustc/middle/typeck/infer/region_inference/mod.rs6
-rw-r--r--src/librustc/middle/typeck/infer/resolve.rs2
-rw-r--r--src/librustc/middle/typeck/infer/unify.rs2
-rw-r--r--src/librustc/middle/typeck/mod.rs2
-rw-r--r--src/librustc/middle/typeck/rscope.rs2
-rw-r--r--src/librustc/middle/typeck/variance.rs6
-rw-r--r--src/librustc/util/common.rs2
-rw-r--r--src/librustc/util/ppaux.rs10
-rw-r--r--src/librustc/util/sha2.rs10
-rw-r--r--src/librustdoc/clean.rs2
-rw-r--r--src/librustdoc/html/markdown.rs14
-rw-r--r--src/librustdoc/html/render.rs6
-rw-r--r--src/librustdoc/html/toc.rs2
-rw-r--r--src/librustdoc/markdown.rs2
-rw-r--r--src/librustdoc/passes.rs6
-rw-r--r--src/librustdoc/visit_ast.rs2
-rw-r--r--src/librustuv/file.rs4
-rw-r--r--src/librustuv/process.rs14
-rw-r--r--src/libsemver/lib.rs2
-rw-r--r--src/libserialize/base64.rs4
-rw-r--r--src/libserialize/ebml.rs16
-rw-r--r--src/libserialize/hex.rs6
-rw-r--r--src/libserialize/serialize.rs8
-rw-r--r--src/libstd/ascii.rs6
-rw-r--r--src/libstd/c_str.rs6
-rw-r--r--src/libstd/cell.rs33
-rw-r--r--src/libstd/comm/shared.rs2
-rw-r--r--src/libstd/comm/stream.rs2
-rw-r--r--src/libstd/fmt/mod.rs6
-rw-r--r--src/libstd/fmt/num.rs2
-rw-r--r--src/libstd/hash/mod.rs6
-rw-r--r--src/libstd/hash/sip.rs4
-rw-r--r--src/libstd/io/buffered.rs12
-rw-r--r--src/libstd/io/comm_adapters.rs2
-rw-r--r--src/libstd/io/extensions.rs8
-rw-r--r--src/libstd/io/fs.rs4
-rw-r--r--src/libstd/io/mem.rs14
-rw-r--r--src/libstd/io/mod.rs8
-rw-r--r--src/libstd/io/net/addrinfo.rs2
-rw-r--r--src/libstd/io/net/ip.rs2
-rw-r--r--src/libstd/io/signal.rs2
-rw-r--r--src/libstd/io/stdio.rs10
-rw-r--r--src/libstd/io/util.rs2
-rw-r--r--src/libstd/iter.rs2
-rw-r--r--src/libstd/kinds.rs23
-rw-r--r--src/libstd/lib.rs8
-rw-r--r--src/libstd/local_data.rs2
-rw-r--r--src/libstd/macros.rs4
-rw-r--r--src/libstd/num/mod.rs4
-rw-r--r--src/libstd/num/strconv.rs4
-rw-r--r--src/libstd/option.rs198
-rw-r--r--src/libstd/os.rs20
-rw-r--r--src/libstd/path/mod.rs10
-rw-r--r--src/libstd/path/posix.rs16
-rw-r--r--src/libstd/path/windows.rs2
-rw-r--r--src/libstd/prelude.rs10
-rw-r--r--src/libstd/ptr.rs2
-rw-r--r--src/libstd/rc.rs21
-rw-r--r--src/libstd/repr.rs2
-rw-r--r--src/libstd/rt/args.rs6
-rw-r--r--src/libstd/rt/at_exit_imp.rs2
-rw-r--r--src/libstd/rt/backtrace.rs4
-rw-r--r--src/libstd/rt/crate_map.rs2
-rw-r--r--src/libstd/rt/local_heap.rs4
-rw-r--r--src/libstd/rt/util.rs2
-rw-r--r--src/libstd/slice.rs4652
-rw-r--r--src/libstd/str.rs30
-rw-r--r--src/libstd/sync/arc.rs16
-rw-r--r--src/libstd/sync/atomics.rs110
-rw-r--r--src/libstd/sync/deque.rs6
-rw-r--r--src/libstd/sync/mpmc_bounded_queue.rs6
-rw-r--r--src/libstd/ty.rs82
-rw-r--r--src/libstd/unicode.rs16
-rw-r--r--src/libstd/vec.rs5197
-rw-r--r--src/libstd/vec_ng.rs1353
-rw-r--r--src/libsync/arc.rs32
-rw-r--r--src/libsync/task_pool.rs5
-rw-r--r--src/libsyntax/abi.rs2
-rw-r--r--src/libsyntax/ast.rs14
-rw-r--r--src/libsyntax/ast_map.rs8
-rw-r--r--src/libsyntax/ast_util.rs4
-rw-r--r--src/libsyntax/attr.rs2
-rw-r--r--src/libsyntax/codemap.rs2
-rw-r--r--src/libsyntax/crateid.rs2
-rw-r--r--src/libsyntax/ext/asm.rs2
-rw-r--r--src/libsyntax/ext/base.rs2
-rw-r--r--src/libsyntax/ext/build.rs4
-rw-r--r--src/libsyntax/ext/bytes.rs2
-rw-r--r--src/libsyntax/ext/cfg.rs2
-rw-r--r--src/libsyntax/ext/concat_idents.rs2
-rw-r--r--src/libsyntax/ext/deriving/clone.rs2
-rw-r--r--src/libsyntax/ext/deriving/cmp/eq.rs2
-rw-r--r--src/libsyntax/ext/deriving/cmp/ord.rs2
-rw-r--r--src/libsyntax/ext/deriving/cmp/totaleq.rs2
-rw-r--r--src/libsyntax/ext/deriving/cmp/totalord.rs2
-rw-r--r--src/libsyntax/ext/deriving/decodable.rs2
-rw-r--r--src/libsyntax/ext/deriving/default.rs2
-rw-r--r--src/libsyntax/ext/deriving/encodable.rs2
-rw-r--r--src/libsyntax/ext/deriving/generic.rs6
-rw-r--r--src/libsyntax/ext/deriving/hash.rs2
-rw-r--r--src/libsyntax/ext/deriving/primitive.rs2
-rw-r--r--src/libsyntax/ext/deriving/rand.rs2
-rw-r--r--src/libsyntax/ext/deriving/show.rs2
-rw-r--r--src/libsyntax/ext/deriving/ty.rs2
-rw-r--r--src/libsyntax/ext/deriving/zero.rs2
-rw-r--r--src/libsyntax/ext/env.rs2
-rw-r--r--src/libsyntax/ext/expand.rs4
-rw-r--r--src/libsyntax/ext/format.rs6
-rw-r--r--src/libsyntax/ext/mtwt.rs13
-rw-r--r--src/libsyntax/ext/quote.rs4
-rw-r--r--src/libsyntax/ext/registrar.rs2
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs2
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs2
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs2
-rw-r--r--src/libsyntax/fold.rs2
-rw-r--r--src/libsyntax/opt_vec.rs6
-rw-r--r--src/libsyntax/parse/attr.rs2
-rw-r--r--src/libsyntax/parse/comments.rs2
-rw-r--r--src/libsyntax/parse/lexer.rs2
-rw-r--r--src/libsyntax/parse/mod.rs4
-rw-r--r--src/libsyntax/parse/parser.rs44
-rw-r--r--src/libsyntax/parse/token.rs2
-rw-r--r--src/libsyntax/print/pp.rs2
-rw-r--r--src/libsyntax/print/pprust.rs4
-rw-r--r--src/libsyntax/util/interner.rs14
-rw-r--r--src/libsyntax/util/parser_testing.rs2
-rw-r--r--src/libsyntax/util/small_vector.rs8
-rw-r--r--src/libsyntax/visit.rs2
-rw-r--r--src/libterm/terminfo/parm.rs8
-rw-r--r--src/libterm/terminfo/parser/compiled.rs4
-rw-r--r--src/libtest/stats.rs4
-rw-r--r--src/liburl/lib.rs2
-rw-r--r--src/libuuid/lib.rs12
-rw-r--r--src/rt/rust_test_helpers.c23
-rw-r--r--src/test/auxiliary/issue-2526.rs6
-rw-r--r--src/test/bench/core-map.rs4
-rw-r--r--src/test/bench/core-std.rs14
-rw-r--r--src/test/bench/shootout-fannkuch-redux.rs8
-rw-r--r--src/test/bench/shootout-fasta-redux.rs6
-rw-r--r--src/test/bench/shootout-k-nucleotide-pipes.rs4
-rw-r--r--src/test/bench/shootout-k-nucleotide.rs6
-rw-r--r--src/test/bench/shootout-meteor.rs2
-rw-r--r--src/test/bench/shootout-spectralnorm.rs2
-rw-r--r--src/test/bench/sudoku.rs8
-rw-r--r--src/test/bench/task-perf-one-million.rs4
-rw-r--r--src/test/compile-fail/borrowck-forbid-static-unsafe-interior.rs47
-rw-r--r--src/test/compile-fail/builtin-superkinds-double-superkind.rs6
-rw-r--r--src/test/compile-fail/builtin-superkinds-self-type.rs4
-rw-r--r--src/test/compile-fail/builtin-superkinds-typaram-not-send.rs2
-rw-r--r--src/test/compile-fail/cant-implement-builtin-kinds.rs2
-rw-r--r--src/test/compile-fail/check-static-values-constraints.rs24
-rw-r--r--src/test/compile-fail/comm-not-freeze.rs8
-rw-r--r--src/test/compile-fail/issue-11873.rs2
-rw-r--r--src/test/compile-fail/issue-2611-4.rs2
-rw-r--r--src/test/compile-fail/lint-deprecated-owned-vector.rs2
-rw-r--r--src/test/compile-fail/lint-unused-imports.rs2
-rw-r--r--src/test/compile-fail/liveness-issue-2163.rs2
-rw-r--r--src/test/compile-fail/marker-no-share.rs (renamed from src/test/compile-fail/marker-no-freeze.rs)4
-rw-r--r--src/test/compile-fail/mut-not-freeze.rs4
-rw-r--r--src/test/compile-fail/no_share-enum.rs (renamed from src/test/compile-fail/no_freeze-enum.rs)8
-rw-r--r--src/test/compile-fail/no_share-rc.rs (renamed from src/test/compile-fail/no_freeze-rc.rs)4
-rw-r--r--src/test/compile-fail/no_share-struct.rs (renamed from src/test/compile-fail/no_freeze-struct.rs)8
-rw-r--r--src/test/run-pass/const-bound.rs2
-rw-r--r--src/test/run-pass/extern-pass-TwoU16s.rs4
-rw-r--r--src/test/run-pass/extern-pass-TwoU8s.rs4
-rw-r--r--src/test/run-pass/extern-pass-empty.rs55
-rw-r--r--src/test/run-pass/import-glob-crate.rs2
-rw-r--r--src/test/run-pass/issue-2611-3.rs2
-rw-r--r--src/test/run-pass/issue-2989.rs6
-rw-r--r--src/test/run-pass/issue-3563-3.rs6
-rw-r--r--src/test/run-pass/mod-view-items.rs4
-rw-r--r--src/test/run-pass/overloaded-autoderef-count.rs2
-rw-r--r--src/test/run-pass/overloaded-deref-count.rs2
-rw-r--r--src/test/run-pass/trait-bounds-in-arc.rs14
-rw-r--r--src/test/run-pass/typeck_type_placeholder_1.rs2
-rw-r--r--src/test/run-pass/uninit-empty-types.rs1
294 files changed, 7161 insertions, 6598 deletions
diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs
index b1c432ec50d..796fc2c802b 100644
--- a/src/compiletest/runtest.rs
+++ b/src/compiletest/runtest.rs
@@ -32,7 +32,7 @@ use std::io;
 use std::os;
 use std::str;
 use std::task;
-use std::vec;
+use std::slice;
 
 use test::MetricMap;
 
@@ -500,7 +500,7 @@ fn check_expected_errors(expected_errors: ~[errors::ExpectedError],
                          proc_res: &ProcRes) {
 
     // true if we found the error in question
-    let mut found_flags = vec::from_elem(
+    let mut found_flags = slice::from_elem(
         expected_errors.len(), false);
 
     if proc_res.status.success() {
diff --git a/src/doc/guide-ffi.md b/src/doc/guide-ffi.md
index f043d95b473..ee7c4064dd4 100644
--- a/src/doc/guide-ffi.md
+++ b/src/doc/guide-ffi.md
@@ -71,7 +71,7 @@ The raw C API needs to be wrapped to provide memory safety and make use of highe
 like vectors. A library can choose to expose only the safe, high-level interface and hide the unsafe
 internal details.
 
-Wrapping the functions which expect buffers involves using the `vec::raw` module to manipulate Rust
+Wrapping the functions which expect buffers involves using the `slice::raw` module to manipulate Rust
 vectors as pointers to memory. Rust's vectors are guaranteed to be a contiguous block of memory. The
 length is number of elements currently contained, and the capacity is the total size in elements of
 the allocated memory. The length is less than or equal to the capacity.
@@ -103,7 +103,7 @@ pub fn compress(src: &[u8]) -> ~[u8] {
         let psrc = src.as_ptr();
 
         let mut dstlen = snappy_max_compressed_length(srclen);
-        let mut dst = vec::with_capacity(dstlen as uint);
+        let mut dst = slice::with_capacity(dstlen as uint);
         let pdst = dst.as_mut_ptr();
 
         snappy_compress(psrc, srclen, pdst, &mut dstlen);
@@ -125,7 +125,7 @@ pub fn uncompress(src: &[u8]) -> Option<~[u8]> {
         let mut dstlen: size_t = 0;
         snappy_uncompressed_length(psrc, srclen, &mut dstlen);
 
-        let mut dst = vec::with_capacity(dstlen as uint);
+        let mut dst = slice::with_capacity(dstlen as uint);
         let pdst = dst.as_mut_ptr();
 
         if snappy_uncompress(psrc, srclen, pdst, &mut dstlen) == 0 {
diff --git a/src/doc/guide-tasks.md b/src/doc/guide-tasks.md
index 976077f70c8..969ade289d3 100644
--- a/src/doc/guide-tasks.md
+++ b/src/doc/guide-tasks.md
@@ -255,10 +255,10 @@ might look like the example below.
 
 ~~~
 # use std::task::spawn;
-# use std::vec;
+# use std::slice;
 
 // Create a vector of ports, one for each child task
-let rxs = vec::from_fn(3, |init_val| {
+let rxs = slice::from_fn(3, |init_val| {
     let (tx, rx) = channel();
     spawn(proc() {
         tx.send(some_expensive_computation(init_val));
@@ -304,7 +304,7 @@ be distributed on the available cores.
 
 ~~~
 # extern crate sync;
-# use std::vec;
+# use std::slice;
 fn partial_sum(start: uint) -> f64 {
     let mut local_sum = 0f64;
     for num in range(start*100000, (start+1)*100000) {
@@ -314,7 +314,7 @@ fn partial_sum(start: uint) -> f64 {
 }
 
 fn main() {
-    let mut futures = vec::from_fn(1000, |ind| sync::Future::spawn( proc() { partial_sum(ind) }));
+    let mut futures = slice::from_fn(1000, |ind| sync::Future::spawn( proc() { partial_sum(ind) }));
 
     let mut final_res = 0f64;
     for ft in futures.mut_iter()  {
@@ -342,7 +342,7 @@ a single large vector of floats. Each task needs the full vector to perform its
 extern crate rand;
 extern crate sync;
 
-use std::vec;
+use std::slice;
 use sync::Arc;
 
 fn pnorm(nums: &~[f64], p: uint) -> f64 {
@@ -350,7 +350,7 @@ fn pnorm(nums: &~[f64], p: uint) -> f64 {
 }
 
 fn main() {
-    let numbers = vec::from_fn(1000000, |_| rand::random::<f64>());
+    let numbers = slice::from_fn(1000000, |_| rand::random::<f64>());
     let numbers_arc = Arc::new(numbers);
 
     for num in range(1u, 10) {
@@ -374,9 +374,9 @@ created by the line
 # extern crate sync;
 # extern crate rand;
 # use sync::Arc;
-# use std::vec;
+# use std::slice;
 # fn main() {
-# let numbers = vec::from_fn(1000000, |_| rand::random::<f64>());
+# let numbers = slice::from_fn(1000000, |_| rand::random::<f64>());
 let numbers_arc=Arc::new(numbers);
 # }
 ~~~
@@ -387,9 +387,9 @@ and a clone of it is sent to each task
 # extern crate sync;
 # extern crate rand;
 # use sync::Arc;
-# use std::vec;
+# use std::slice;
 # fn main() {
-# let numbers=vec::from_fn(1000000, |_| rand::random::<f64>());
+# let numbers=slice::from_fn(1000000, |_| rand::random::<f64>());
 # let numbers_arc = Arc::new(numbers);
 # let (tx, rx) = channel();
 tx.send(numbers_arc.clone());
@@ -404,9 +404,9 @@ Each task recovers the underlying data by
 # extern crate sync;
 # extern crate rand;
 # use sync::Arc;
-# use std::vec;
+# use std::slice;
 # fn main() {
-# let numbers=vec::from_fn(1000000, |_| rand::random::<f64>());
+# let numbers=slice::from_fn(1000000, |_| rand::random::<f64>());
 # let numbers_arc=Arc::new(numbers);
 # let (tx, rx) = channel();
 # tx.send(numbers_arc.clone());
diff --git a/src/doc/guide-testing.md b/src/doc/guide-testing.md
index 1a01fad5da2..3efed4a215b 100644
--- a/src/doc/guide-testing.md
+++ b/src/doc/guide-testing.md
@@ -188,18 +188,18 @@ For example:
 # #[allow(unused_imports)];
 extern crate test;
 
-use std::vec;
+use std::slice;
 use test::BenchHarness;
 
 #[bench]
 fn bench_sum_1024_ints(b: &mut BenchHarness) {
-    let v = vec::from_fn(1024, |n| n);
+    let v = slice::from_fn(1024, |n| n);
     b.iter(|| {v.iter().fold(0, |old, new| old + *new);} );
 }
 
 #[bench]
 fn initialise_a_vector(b: &mut BenchHarness) {
-    b.iter(|| {vec::from_elem(1024, 0u64);} );
+    b.iter(|| {slice::from_elem(1024, 0u64);} );
     b.bytes = 1024 * 8;
 }
 
diff --git a/src/doc/guide-unsafe.md b/src/doc/guide-unsafe.md
index b085fe21fac..9835e50d547 100644
--- a/src/doc/guide-unsafe.md
+++ b/src/doc/guide-unsafe.md
@@ -595,10 +595,10 @@ Other features provided by lang items include:
 - stack unwinding and general failure; the `eh_personality`, `fail_`
   and `fail_bounds_checks` lang items.
 - the traits in `std::kinds` used to indicate types that satisfy
-  various kinds; lang items `send`, `freeze` and `pod`.
+  various kinds; lang items `send`, `share` and `pod`.
 - the marker types and variance indicators found in
   `std::kinds::markers`; lang items `covariant_type`,
-  `contravariant_lifetime`, `no_freeze_bound`, etc.
+  `contravariant_lifetime`, `no_share_bound`, etc.
 
 Lang items are loaded lazily by the compiler; e.g. if one never uses
 `~` then there is no need to define functions for `exchange_malloc`
diff --git a/src/doc/tutorial.md b/src/doc/tutorial.md
index cdb521b96c4..0a417a5a8bf 100644
--- a/src/doc/tutorial.md
+++ b/src/doc/tutorial.md
@@ -2095,6 +2095,10 @@ and may not be overridden:
 Types are sendable
 unless they contain managed boxes, managed closures, or references.
 
+* `Share` - Types that are *threadsafe*
+These are types that are safe to be used across several threads with access to
+a `&T` pointer. `MutexArc` is an example of a *sharable* type with internal mutable data.
+
 * `Freeze` - Constant (immutable) types.
 These are types that do not contain anything intrinsically mutable.
 Intrinsically mutable values include `Cell` in the standard library.
diff --git a/src/etc/unicode.py b/src/etc/unicode.py
index e32954c75d4..1ab705d7ece 100755
--- a/src/etc/unicode.py
+++ b/src/etc/unicode.py
@@ -162,7 +162,7 @@ def emit_bsearch_range_table(f):
     f.write("""
 fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
     use cmp::{Equal, Less, Greater};
-    use vec::ImmutableVector;
+    use slice::ImmutableVector;
     use option::None;
     r.bsearch(|&(lo,hi)| {
         if lo <= c && c <= hi { Equal }
@@ -200,7 +200,7 @@ def emit_conversions_module(f, lowerupper, upperlower):
     f.write("pub mod conversions {\n")
     f.write("""
     use cmp::{Equal, Less, Greater};
-    use vec::ImmutableVector;
+    use slice::ImmutableVector;
     use tuple::Tuple2;
     use option::{Option, Some, None};
 
@@ -264,7 +264,7 @@ def emit_decomp_module(f, canon, compat, combine):
     f.write("pub mod decompose {\n");
     f.write("    use option::Option;\n");
     f.write("    use option::{Some, None};\n");
-    f.write("    use vec::ImmutableVector;\n");
+    f.write("    use slice::ImmutableVector;\n");
     f.write("""
     fn bsearch_table(c: char, r: &'static [(char, &'static [char])]) -> Option<&'static [char]> {
         use cmp::{Equal, Less, Greater};
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index f2c98b8e5fc..8d6e0386526 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -42,7 +42,7 @@ use std::rc::Rc;
 use std::rt::global_heap;
 use std::intrinsics::{TyDesc, get_tydesc};
 use std::intrinsics;
-use std::vec;
+use std::slice;
 
 // The way arena uses arrays is really deeply awful. The arrays are
 // allocated, and have capacities reserved, but the fill for the array
@@ -111,7 +111,7 @@ impl Arena {
 
 fn chunk(size: uint, is_pod: bool) -> Chunk {
     Chunk {
-        data: Rc::new(RefCell::new(vec::with_capacity(size))),
+        data: Rc::new(RefCell::new(slice::with_capacity(size))),
         fill: Cell::new(0u),
         is_pod: Cell::new(is_pod),
     }
diff --git a/src/libcollections/bitv.rs b/src/libcollections/bitv.rs
index 87e9c3f238a..7075e47bddf 100644
--- a/src/libcollections/bitv.rs
+++ b/src/libcollections/bitv.rs
@@ -16,7 +16,7 @@ use std::iter::RandomAccessIterator;
 use std::iter::{Rev, Enumerate, Repeat, Map, Zip};
 use std::ops;
 use std::uint;
-use std::vec;
+use std::slice;
 
 #[deriving(Clone)]
 struct SmallBitv {
@@ -278,13 +278,13 @@ impl Bitv {
             let s =
                 if init {
                     if exact {
-                        vec::from_elem(nelems, !0u)
+                        slice::from_elem(nelems, !0u)
                     } else {
-                        let mut v = vec::from_elem(nelems-1, !0u);
+                        let mut v = slice::from_elem(nelems-1, !0u);
                         v.push((1<<nbits % uint::BITS)-1);
                         v
                     }
-                } else { vec::from_elem(nelems, 0u)};
+                } else { slice::from_elem(nelems, 0u)};
             Big(BigBitv::new(s))
         };
         Bitv {rep: rep, nbits: nbits}
@@ -452,7 +452,7 @@ impl Bitv {
      * Each `uint` in the resulting vector has either value `0u` or `1u`.
      */
     pub fn to_vec(&self) -> ~[uint] {
-        vec::from_fn(self.nbits, |x| self.init_to_vec(x))
+        slice::from_fn(self.nbits, |x| self.init_to_vec(x))
     }
 
     /**
@@ -473,7 +473,7 @@ impl Bitv {
 
         let len = self.nbits/8 +
                   if self.nbits % 8 == 0 { 0 } else { 1 };
-        vec::from_fn(len, |i|
+        slice::from_fn(len, |i|
             bit(self, i, 0) |
             bit(self, i, 1) |
             bit(self, i, 2) |
@@ -489,7 +489,7 @@ impl Bitv {
      * Transform `self` into a `[bool]` by turning each bit into a `bool`.
      */
     pub fn to_bools(&self) -> ~[bool] {
-        vec::from_fn(self.nbits, |i| self[i])
+        slice::from_fn(self.nbits, |i| self[i])
     }
 
     /**
@@ -879,7 +879,7 @@ impl BitvSet {
     /// and w1/w2 are the words coming from the two vectors self, other.
     fn commons<'a>(&'a self, other: &'a BitvSet)
         -> Map<'static, ((uint, &'a uint), &'a ~[uint]), (uint, uint, uint),
-               Zip<Enumerate<vec::Items<'a, uint>>, Repeat<&'a ~[uint]>>> {
+               Zip<Enumerate<slice::Items<'a, uint>>, Repeat<&'a ~[uint]>>> {
         let min = cmp::min(self.bitv.storage.len(), other.bitv.storage.len());
         self.bitv.storage.slice(0, min).iter().enumerate()
             .zip(Repeat::new(&other.bitv.storage))
@@ -895,7 +895,7 @@ impl BitvSet {
     /// `other`.
     fn outliers<'a>(&'a self, other: &'a BitvSet)
         -> Map<'static, ((uint, &'a uint), uint), (bool, uint, uint),
-               Zip<Enumerate<vec::Items<'a, uint>>, Repeat<uint>>> {
+               Zip<Enumerate<slice::Items<'a, uint>>, Repeat<uint>>> {
         let slen = self.bitv.storage.len();
         let olen = other.bitv.storage.len();
 
@@ -946,7 +946,7 @@ mod tests {
     use bitv;
 
     use std::uint;
-    use std::vec;
+    use std::slice;
     use rand;
     use rand::Rng;
 
@@ -964,7 +964,7 @@ mod tests {
     #[test]
     fn test_0_elements() {
         let act = Bitv::new(0u, false);
-        let exp = vec::from_elem::<bool>(0u, false);
+        let exp = slice::from_elem::<bool>(0u, false);
         assert!(act.eq_vec(exp));
     }
 
diff --git a/src/libcollections/deque.rs b/src/libcollections/deque.rs
index f84354f9b00..05df04d293f 100644
--- a/src/libcollections/deque.rs
+++ b/src/libcollections/deque.rs
@@ -44,7 +44,7 @@ pub mod bench {
     extern crate test;
     use self::test::BenchHarness;
     use std::container::MutableMap;
-    use std::vec;
+    use std::slice;
     use rand;
     use rand::Rng;
 
@@ -90,7 +90,7 @@ pub mod bench {
                                                 bh: &mut BenchHarness) {
         // setup
         let mut rng = rand::XorShiftRng::new();
-        let mut keys = vec::from_fn(n, |_| rng.gen::<uint>() % n);
+        let mut keys = slice::from_fn(n, |_| rng.gen::<uint>() % n);
 
         for k in keys.iter() {
             map.insert(*k, 1);
diff --git a/src/libcollections/hashmap.rs b/src/libcollections/hashmap.rs
index 46d3ab432cd..a1f815df72e 100644
--- a/src/libcollections/hashmap.rs
+++ b/src/libcollections/hashmap.rs
@@ -27,7 +27,7 @@ use std::option::{Option, Some, None};
 use rand;
 use rand::Rng;
 use std::result::{Ok, Err};
-use std::vec::{ImmutableVector};
+use std::slice::ImmutableVector;
 
 mod table {
     use std::clone::Clone;
@@ -1575,7 +1575,7 @@ mod test_map {
     use super::HashMap;
     use std::iter::{Iterator,range_inclusive,range_step_inclusive};
     use std::local_data;
-    use std::vec_ng;
+    use std::vec;
 
     #[test]
     fn test_create_capacity_zero() {
@@ -1599,7 +1599,7 @@ mod test_map {
         assert_eq!(*m.find(&2).unwrap(), 4);
     }
 
-    local_data_key!(drop_vector: vec_ng::Vec<int>)
+    local_data_key!(drop_vector: vec::Vec<int>)
 
     #[deriving(Hash, Eq)]
     struct Dropable {
@@ -1625,7 +1625,7 @@ mod test_map {
 
     #[test]
     fn test_drops() {
-        local_data::set(drop_vector, vec_ng::Vec::from_elem(200, 0));
+        local_data::set(drop_vector, vec::Vec::from_elem(200, 0));
 
         {
             let mut m = HashMap::new();
@@ -1958,7 +1958,7 @@ mod test_map {
 mod test_set {
     use super::HashSet;
     use std::container::Container;
-    use std::vec::ImmutableEqVector;
+    use std::slice::ImmutableEqVector;
 
     #[test]
     fn test_disjoint() {
diff --git a/src/libcollections/priority_queue.rs b/src/libcollections/priority_queue.rs
index 5463d267787..dc9e5a9700d 100644
--- a/src/libcollections/priority_queue.rs
+++ b/src/libcollections/priority_queue.rs
@@ -14,7 +14,7 @@
 
 use std::clone::Clone;
 use std::mem::{move_val_init, init, replace, swap};
-use std::vec;
+use std::slice;
 
 /// A priority queue implemented with a binary heap
 #[deriving(Clone)]
@@ -181,7 +181,7 @@ impl<T:Ord> PriorityQueue<T> {
 
 /// PriorityQueue iterator
 pub struct Items <'a, T> {
-    priv iter: vec::Items<'a, T>,
+    priv iter: slice::Items<'a, T>,
 }
 
 impl<'a, T> Iterator<&'a T> for Items<'a, T> {
diff --git a/src/libcollections/ringbuf.rs b/src/libcollections/ringbuf.rs
index e09bf1023d6..e083f3f600f 100644
--- a/src/libcollections/ringbuf.rs
+++ b/src/libcollections/ringbuf.rs
@@ -14,7 +14,7 @@
 //! extra::container::Deque`.
 
 use std::cmp;
-use std::vec;
+use std::slice;
 use std::iter::{Rev, RandomAccessIterator};
 
 use deque::Deque;
@@ -118,7 +118,7 @@ impl<T> RingBuf<T> {
     /// Create an empty RingBuf with space for at least `n` elements.
     pub fn with_capacity(n: uint) -> RingBuf<T> {
         RingBuf{nelts: 0, lo: 0,
-              elts: vec::from_fn(cmp::max(MINIMUM_CAPACITY, n), |_| None)}
+              elts: slice::from_fn(cmp::max(MINIMUM_CAPACITY, n), |_| None)}
     }
 
     /// Retrieve an element in the RingBuf by index
diff --git a/src/libcollections/smallintmap.rs b/src/libcollections/smallintmap.rs
index 603d5bb820d..64be1b92e26 100644
--- a/src/libcollections/smallintmap.rs
+++ b/src/libcollections/smallintmap.rs
@@ -17,7 +17,7 @@
 
 use std::iter::{Enumerate, FilterMap, Rev};
 use std::mem::replace;
-use std::vec;
+use std::slice;
 
 #[allow(missing_doc)]
 pub struct SmallIntMap<T> {
@@ -153,7 +153,7 @@ impl<V> SmallIntMap<V> {
     /// Empties the hash map, moving all values into the specified closure
     pub fn move_iter(&mut self)
         -> FilterMap<(uint, Option<V>), (uint, V),
-                Enumerate<vec::MoveItems<Option<V>>>>
+                Enumerate<slice::MoveItems<Option<V>>>>
     {
         let values = replace(&mut self.v, ~[]);
         values.move_iter().enumerate().filter_map(|(i, v)| {
@@ -236,7 +236,7 @@ macro_rules! double_ended_iterator {
 pub struct Entries<'a, T> {
     priv front: uint,
     priv back: uint,
-    priv iter: vec::Items<'a, Option<T>>
+    priv iter: slice::Items<'a, Option<T>>
 }
 
 iterator!(impl Entries -> (uint, &'a T), get_ref)
@@ -246,7 +246,7 @@ pub type RevEntries<'a, T> = Rev<Entries<'a, T>>;
 pub struct MutEntries<'a, T> {
     priv front: uint,
     priv back: uint,
-    priv iter: vec::MutItems<'a, Option<T>>
+    priv iter: slice::MutItems<'a, Option<T>>
 }
 
 iterator!(impl MutEntries -> (uint, &'a mut T), get_mut_ref)
diff --git a/src/libcollections/trie.rs b/src/libcollections/trie.rs
index 2232af98eb3..66bcd3cbdda 100644
--- a/src/libcollections/trie.rs
+++ b/src/libcollections/trie.rs
@@ -13,8 +13,8 @@
 use std::mem;
 use std::uint;
 use std::mem::init;
-use std::vec;
-use std::vec::{Items, MutItems};
+use std::slice;
+use std::slice::{Items, MutItems};
 
 // FIXME: #5244: need to manually update the TrieNode constructor
 static SHIFT: uint = 4;
@@ -474,7 +474,7 @@ fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
 
 /// Forward iterator over a map
 pub struct Entries<'a, T> {
-    priv stack: [vec::Items<'a, Child<T>>, .. NUM_CHUNKS],
+    priv stack: [slice::Items<'a, Child<T>>, .. NUM_CHUNKS],
     priv length: uint,
     priv remaining_min: uint,
     priv remaining_max: uint
@@ -483,7 +483,7 @@ pub struct Entries<'a, T> {
 /// Forward iterator over the key-value pairs of a map, with the
 /// values being mutable.
 pub struct MutEntries<'a, T> {
-    priv stack: [vec::MutItems<'a, Child<T>>, .. NUM_CHUNKS],
+    priv stack: [slice::MutItems<'a, Child<T>>, .. NUM_CHUNKS],
     priv length: uint,
     priv remaining_min: uint,
     priv remaining_max: uint
diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs
index 5abe96b1acc..c25e38fe055 100644
--- a/src/libgetopts/lib.rs
+++ b/src/libgetopts/lib.rs
@@ -94,7 +94,7 @@ use std::cmp::Eq;
 use std::result::{Err, Ok};
 use std::result;
 use std::option::{Some, None};
-use std::vec;
+use std::slice;
 
 /// Name of an option. Either a string or a single char.
 #[deriving(Clone, Eq)]
@@ -525,7 +525,7 @@ pub fn getopts(args: &[~str], optgrps: &[OptGroup]) -> Result {
 
     fn f(_x: uint) -> ~[Optval] { return ~[]; }
 
-    let mut vals = vec::from_fn(n_opts, f);
+    let mut vals = slice::from_fn(n_opts, f);
     let mut free: ~[~str] = ~[];
     let l = args.len();
     let mut i = 0;
diff --git a/src/libgreen/lib.rs b/src/libgreen/lib.rs
index 78ea407d4eb..1895717374b 100644
--- a/src/libgreen/lib.rs
+++ b/src/libgreen/lib.rs
@@ -188,7 +188,7 @@ use std::rt;
 use std::sync::atomics::{SeqCst, AtomicUint, INIT_ATOMIC_UINT};
 use std::sync::deque;
 use std::task::TaskOpts;
-use std::vec;
+use std::slice;
 use std::sync::arc::UnsafeArc;
 
 use sched::{Shutdown, Scheduler, SchedHandle, TaskFromFriend, NewNeighbor};
@@ -356,8 +356,8 @@ impl SchedPool {
 
         // Create a work queue for each scheduler, ntimes. Create an extra
         // for the main thread if that flag is set. We won't steal from it.
-        let arr = vec::from_fn(nscheds, |_| pool.deque_pool.deque());
-        let (workers, stealers) = vec::unzip(arr.move_iter());
+        let arr = slice::from_fn(nscheds, |_| pool.deque_pool.deque());
+        let (workers, stealers) = slice::unzip(arr.move_iter());
         pool.stealers = stealers;
 
         // Now that we've got all our work queues, create one scheduler per
diff --git a/src/liblog/directive.rs b/src/liblog/directive.rs
index d33ad0c8185..9d5e1a8f9ed 100644
--- a/src/liblog/directive.rs
+++ b/src/liblog/directive.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use std::cmp;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 #[deriving(Show, Clone)]
 pub struct LogDirective {
diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs
index 3ff7ee390f1..fa8daf79812 100644
--- a/src/liblog/lib.rs
+++ b/src/liblog/lib.rs
@@ -125,8 +125,8 @@ use std::io;
 use std::local_data;
 use std::os;
 use std::rt;
-use std::vec;
-use std::vec_ng::Vec;
+use std::slice;
+use std::vec::Vec;
 
 use sync::one::{Once, ONCE_INIT};
 
@@ -247,7 +247,7 @@ pub fn mod_enabled(level: u32, module: &str) -> bool {
 }
 
 fn enabled(level: u32, module: &str,
-           iter: vec::Items<directive::LogDirective>) -> bool {
+           iter: slice::Items<directive::LogDirective>) -> bool {
     // Search for the longest match, the vector is assumed to be pre-sorted.
     for directive in iter.rev() {
         match directive.name {
diff --git a/src/libnative/io/file_unix.rs b/src/libnative/io/file_unix.rs
index 1d7938be226..a55dedd594d 100644
--- a/src/libnative/io/file_unix.rs
+++ b/src/libnative/io/file_unix.rs
@@ -18,8 +18,8 @@ use std::libc::{c_int, c_void};
 use std::libc;
 use std::mem;
 use std::rt::rtio;
-use std::vec;
-use std::vec_ng::Vec;
+use std::slice;
+use std::vec::Vec;
 
 use io::{IoResult, retry, keep_going};
 
@@ -417,7 +417,7 @@ pub fn readlink(p: &CString) -> IoResult<Path> {
     if len == -1 {
         len = 1024; // FIXME: read PATH_MAX from C ffi?
     }
-    let mut buf = vec::with_capacity::<u8>(len as uint);
+    let mut buf = slice::with_capacity::<u8>(len as uint);
     match retry(|| unsafe {
         libc::readlink(p, buf.as_ptr() as *mut libc::c_char,
                        len as libc::size_t) as libc::c_int
diff --git a/src/libnative/io/file_win32.rs b/src/libnative/io/file_win32.rs
index c5ae4f00017..28b963ab348 100644
--- a/src/libnative/io/file_win32.rs
+++ b/src/libnative/io/file_win32.rs
@@ -22,7 +22,7 @@ use std::ptr;
 use std::rt::rtio;
 use std::str;
 use std::sync::arc::UnsafeArc;
-use std::vec;
+use std::slice;
 
 use io::IoResult;
 
@@ -353,8 +353,7 @@ pub fn readdir(p: &CString) -> IoResult<~[Path]> {
                 if fp_buf as uint == 0 {
                     fail!("os::list_dir() failure: got null ptr from wfd");
                 } else {
-                    let fp_vec = vec::from_buf(fp_buf,
-                                               libc::wcslen(fp_buf) as uint);
+                    let fp_vec = slice::from_buf(fp_buf, libc::wcslen(fp_buf) as uint);
                     let fp_trimmed = str::truncate_utf16_at_nul(fp_vec);
                     let fp_str = str::from_utf16(fp_trimmed)
                             .expect("rust_list_dir_wfd_fp_buf returned invalid UTF-16");
diff --git a/src/libnative/io/process.rs b/src/libnative/io/process.rs
index 6ac1f2b3692..591c34e9be5 100644
--- a/src/libnative/io/process.rs
+++ b/src/libnative/io/process.rs
@@ -572,12 +572,12 @@ fn spawn_process_os(config: p::ProcessConfig,
 
 #[cfg(unix)]
 fn with_argv<T>(prog: &str, args: &[~str], cb: |**libc::c_char| -> T) -> T {
-    use std::vec;
+    use std::slice;
 
     // We can't directly convert `str`s into `*char`s, as someone needs to hold
     // a reference to the intermediary byte buffers. So first build an array to
     // hold all the ~[u8] byte strings.
-    let mut tmps = vec::with_capacity(args.len() + 1);
+    let mut tmps = slice::with_capacity(args.len() + 1);
 
     tmps.push(prog.to_c_str());
 
@@ -598,14 +598,14 @@ fn with_argv<T>(prog: &str, args: &[~str], cb: |**libc::c_char| -> T) -> T {
 
 #[cfg(unix)]
 fn with_envp<T>(env: Option<~[(~str, ~str)]>, cb: |*c_void| -> T) -> T {
-    use std::vec;
+    use std::slice;
 
     // On posixy systems we can pass a char** for envp, which is a
     // null-terminated array of "k=v\n" strings. Like `with_argv`, we have to
     // have a temporary buffer to hold the intermediary `~[u8]` byte strings.
     match env {
         Some(env) => {
-            let mut tmps = vec::with_capacity(env.len());
+            let mut tmps = slice::with_capacity(env.len());
 
             for pair in env.iter() {
                 let kv = format!("{}={}", *pair.ref0(), *pair.ref1());
diff --git a/src/libnum/bigint.rs b/src/libnum/bigint.rs
index 8861f90b928..cba24b478fc 100644
--- a/src/libnum/bigint.rs
+++ b/src/libnum/bigint.rs
@@ -28,8 +28,8 @@ use rand::Rng;
 use std::str;
 use std::uint;
 use std::{i64, u64};
-use std::vec_ng;
-use std::vec_ng::Vec;
+use std::vec;
+use std::vec::Vec;
 
 /**
 A `BigDigit` is a `BigUint`'s composing element.
@@ -753,7 +753,7 @@ impl BigUint {
     fn shl_unit(&self, n_unit: uint) -> BigUint {
         if n_unit == 0 || self.is_zero() { return (*self).clone(); }
 
-        return BigUint::new(vec_ng::append(Vec::from_elem(n_unit, ZERO_BIG_DIGIT),
+        return BigUint::new(vec::append(Vec::from_elem(n_unit, ZERO_BIG_DIGIT),
                                            self.data.as_slice()));
     }
 
@@ -1461,7 +1461,7 @@ mod biguint_tests {
     use std::num::CheckedDiv;
     use rand::{task_rng};
     use std::u64;
-    use std::vec_ng::Vec;
+    use std::vec::Vec;
 
     #[test]
     fn test_from_slice() {
@@ -2195,7 +2195,7 @@ mod bigint_tests {
     use std::num::{ToPrimitive, FromPrimitive};
     use rand::{task_rng};
     use std::u64;
-    use std::vec_ng::Vec;
+    use std::vec::Vec;
 
     #[test]
     fn test_from_biguint() {
diff --git a/src/libnum/rational.rs b/src/libnum/rational.rs
index 6d0b6128f88..1e97d85aa17 100644
--- a/src/libnum/rational.rs
+++ b/src/libnum/rational.rs
@@ -16,7 +16,7 @@ use std::cmp;
 use std::fmt;
 use std::from_str::FromStr;
 use std::num::{Zero,One,ToStrRadix,FromStrRadix,Round};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use bigint::{BigInt, BigUint, Sign, Plus, Minus};
 
 /// Represents the ratio between 2 numbers.
diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs
index b3226d60095..d0dc5b90867 100644
--- a/src/librand/isaac.rs
+++ b/src/librand/isaac.rs
@@ -12,7 +12,7 @@
 
 use {Rng, SeedableRng, OSRng};
 use std::iter::{range_step, Repeat};
-use std::vec::raw;
+use std::slice::raw;
 use std::mem;
 
 static RAND_SIZE_LEN: u32 = 8;
@@ -431,7 +431,7 @@ impl<'a> SeedableRng<&'a [u64]> for Isaac64Rng {
 mod test {
     use super::{IsaacRng, Isaac64Rng};
     use {Rng, SeedableRng, OSRng};
-    use std::vec;
+    use std::slice;
 
     #[test]
     fn test_rng_32_rand_seeded() {
@@ -491,7 +491,7 @@ mod test {
         let seed = &[1, 23, 456, 7890, 12345];
         let mut ra: IsaacRng = SeedableRng::from_seed(seed);
         // Regression test that isaac is actually using the above vector
-        let v = vec::from_fn(10, |_| ra.next_u32());
+        let v = slice::from_fn(10, |_| ra.next_u32());
         assert_eq!(v,
                    ~[2558573138, 873787463, 263499565, 2103644246, 3595684709,
                      4203127393, 264982119, 2765226902, 2737944514, 3900253796]);
@@ -501,7 +501,7 @@ mod test {
         // skip forward to the 10000th number
         for _ in range(0, 10000) { rb.next_u32(); }
 
-        let v = vec::from_fn(10, |_| rb.next_u32());
+        let v = slice::from_fn(10, |_| rb.next_u32());
         assert_eq!(v,
                    ~[3676831399, 3183332890, 2834741178, 3854698763, 2717568474,
                      1576568959, 3507990155, 179069555, 141456972, 2478885421]);
@@ -511,7 +511,7 @@ mod test {
         let seed = &[1, 23, 456, 7890, 12345];
         let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
         // Regression test that isaac is actually using the above vector
-        let v = vec::from_fn(10, |_| ra.next_u64());
+        let v = slice::from_fn(10, |_| ra.next_u64());
         assert_eq!(v,
                    ~[547121783600835980, 14377643087320773276, 17351601304698403469,
                      1238879483818134882, 11952566807690396487, 13970131091560099343,
@@ -523,7 +523,7 @@ mod test {
         // skip forward to the 10000th number
         for _ in range(0, 10000) { rb.next_u64(); }
 
-        let v = vec::from_fn(10, |_| rb.next_u64());
+        let v = slice::from_fn(10, |_| rb.next_u64());
         assert_eq!(v,
                    ~[18143823860592706164, 8491801882678285927, 2699425367717515619,
                      17196852593171130876, 2606123525235546165, 15790932315217671084,
diff --git a/src/librand/lib.rs b/src/librand/lib.rs
index dc4e3e50b65..0086b385b79 100644
--- a/src/librand/lib.rs
+++ b/src/librand/lib.rs
@@ -80,7 +80,7 @@ use std::cast;
 use std::kinds::marker;
 use std::local_data;
 use std::str;
-use std::vec;
+use std::slice;
 
 pub use isaac::{IsaacRng, Isaac64Rng};
 pub use os::OSRng;
@@ -202,7 +202,7 @@ pub trait Rng {
     /// println!("{:?}", rng.gen_vec::<(f64, bool)>(5));
     /// ```
     fn gen_vec<T: Rand>(&mut self, len: uint) -> ~[T] {
-        vec::from_fn(len, |_| self.gen())
+        slice::from_fn(len, |_| self.gen())
     }
 
     /// Generate a random value in the range [`low`, `high`). Fails if
@@ -342,7 +342,7 @@ pub trait Rng {
     /// println!("{:?}", sample);
     /// ```
     fn sample<A, T: Iterator<A>>(&mut self, iter: T, n: uint) -> ~[A] {
-        let mut reservoir : ~[A] = vec::with_capacity(n);
+        let mut reservoir : ~[A] = slice::with_capacity(n);
         for (i, elem) in iter.enumerate() {
             if i < n {
                 reservoir.push(elem);
@@ -677,7 +677,7 @@ pub struct Closed01<F>(F);
 
 #[cfg(test)]
 mod test {
-    use std::vec;
+    use std::slice;
     use super::{Rng, task_rng, random, OSRng, SeedableRng, StdRng};
 
     struct ConstRng { i: u64 }
@@ -696,7 +696,7 @@ mod test {
         let lengths = [0, 1, 2, 3, 4, 5, 6, 7,
                        80, 81, 82, 83, 84, 85, 86, 87];
         for &n in lengths.iter() {
-            let mut v = vec::from_elem(n, 0u8);
+            let mut v = slice::from_elem(n, 0u8);
             r.fill_bytes(v);
 
             // use this to get nicer error messages.
diff --git a/src/librustc/back/archive.rs b/src/librustc/back/archive.rs
index 863b91f9b32..e684c8b6528 100644
--- a/src/librustc/back/archive.rs
+++ b/src/librustc/back/archive.rs
@@ -16,7 +16,7 @@ use metadata::filesearch;
 use lib::llvm::{ArchiveRef, llvm};
 
 use std::cast;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use std::io;
 use std::io::{fs, TempDir};
 use std::libc;
diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs
index edb9d11b11a..25802ac9d51 100644
--- a/src/librustc/back/link.rs
+++ b/src/librustc/back/link.rs
@@ -33,7 +33,7 @@ use std::ptr;
 use std::str;
 use std::io;
 use std::io::{fs, TempDir, Process};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use flate;
 use serialize::hex::ToHex;
 use syntax::abi;
@@ -105,7 +105,7 @@ pub mod write {
     use std::io::Process;
     use std::libc::{c_uint, c_int};
     use std::str;
-    use std::vec_ng::Vec;
+    use std::vec::Vec;
 
     // On android, we by default compile for armv7 processors. This enables
     // things like double word CAS instructions (rather than emulating them)
diff --git a/src/librustc/back/mips.rs b/src/librustc/back/mips.rs
index 0de256ba8d8..c870e69b324 100644
--- a/src/librustc/back/mips.rs
+++ b/src/librustc/back/mips.rs
@@ -11,7 +11,7 @@
 use back::target_strs;
 use driver::session::sess_os_to_meta_os;
 use metadata::loader::meta_section_name;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::abi;
 
 pub fn get_target_strs(target_triple: ~str, target_os: abi::Os) -> target_strs::t {
diff --git a/src/librustc/back/rpath.rs b/src/librustc/back/rpath.rs
index d8feb0a47b3..ede7b7f3d42 100644
--- a/src/librustc/back/rpath.rs
+++ b/src/librustc/back/rpath.rs
@@ -14,8 +14,8 @@ use metadata::cstore;
 use metadata::filesearch;
 
 use collections::HashSet;
-use std::{os, vec};
-use std::vec_ng::Vec;
+use std::{os, slice};
+use std::vec::Vec;
 use syntax::abi;
 
 fn not_win32(os: abi::Os) -> bool {
@@ -46,7 +46,7 @@ pub fn get_rpath_flags(sess: &Session, out_filename: &Path) -> Vec<~str> {
     let libs = libs.move_iter().filter_map(|(_, l)| l.map(|p| p.clone())).collect();
     // We don't currently rpath extern libraries, but we know
     // where rustrt is and we know every rust program needs it
-    let libs = vec::append_one(libs, get_sysroot_absolute_rt_lib(sess));
+    let libs = slice::append_one(libs, get_sysroot_absolute_rt_lib(sess));
 
     let rpaths = get_rpaths(os, sysroot, output, libs,
                             sess.opts.target_triple);
diff --git a/src/librustc/back/target_strs.rs b/src/librustc/back/target_strs.rs
index c2a1a5598d5..b07c0b2136f 100644
--- a/src/librustc/back/target_strs.rs
+++ b/src/librustc/back/target_strs.rs
@@ -10,7 +10,7 @@
 
 #[allow(non_camel_case_types)];
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub struct t {
     module_asm: ~str,
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index 94965e7e0dc..0156ca12084 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -37,8 +37,8 @@ use std::io::fs;
 use std::io::MemReader;
 use std::mem::drop;
 use std::os;
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 use getopts::{optopt, optmulti, optflag, optflagopt};
 use getopts;
 use syntax::ast;
@@ -138,7 +138,7 @@ pub fn build_configuration(sess: &Session) -> ast::CrateConfig {
     } else {
         InternedString::new("nogc")
     });
-    return vec_ng::append(user_cfg.move_iter().collect(),
+    return vec::append(user_cfg.move_iter().collect(),
                           default_cfg.as_slice());
 }
 
@@ -305,6 +305,9 @@ pub fn phase_3_run_analysis_passes(sess: Session,
         time(time_passes, "resolution", (), |_|
              middle::resolve::resolve_crate(&sess, lang_items, krate));
 
+    // Discard MTWT tables that aren't required past resolution.
+    syntax::ext::mtwt::clear_tables();
+
     let named_region_map = time(time_passes, "lifetime resolution", (),
                                 |_| middle::resolve_lifetime::krate(&sess, krate));
 
@@ -585,6 +588,10 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input,
         if stop_after_phase_3(&analysis.ty_cx.sess) { return; }
         let (tcx, trans) = phase_4_translate_to_llvm(expanded_crate,
                                                      analysis, &outputs);
+
+        // Discard interned strings as they are no longer required.
+        token::get_ident_interner().clear();
+
         (outputs, trans, tcx.sess)
     };
     phase_5_run_llvm_passes(&sess, &trans, &outputs);
@@ -828,7 +835,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> session::Options {
 
         let level_short = level_name.slice_chars(0, 1);
         let level_short = level_short.to_ascii().to_upper().into_str();
-        let flags = vec_ng::append(matches.opt_strs(level_short)
+        let flags = vec::append(matches.opt_strs(level_short)
                                           .move_iter()
                                           .collect(),
                                    matches.opt_strs(level_name));
diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs
index 8d3048a80b2..b7b7019a28b 100644
--- a/src/librustc/driver/session.rs
+++ b/src/librustc/driver/session.rs
@@ -28,7 +28,7 @@ use syntax::{abi, ast, codemap};
 use syntax;
 
 use std::cell::{Cell, RefCell};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use collections::HashSet;
 
 pub struct Config {
@@ -407,7 +407,7 @@ macro_rules! cgoptions(
             }
         }
 
-        fn parse_list(slot: &mut ::std::vec_ng::Vec<~str>, v: Option<&str>)
+        fn parse_list(slot: &mut ::std::vec::Vec<~str>, v: Option<&str>)
                       -> bool {
             match v {
                 Some(s) => {
diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs
index 514d2a4a6e1..349451b4205 100644
--- a/src/librustc/front/config.rs
+++ b/src/librustc/front/config.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::fold::Folder;
 use syntax::{ast, fold, attr};
 use syntax::codemap;
diff --git a/src/librustc/front/feature_gate.rs b/src/librustc/front/feature_gate.rs
index 99de2060eee..bb6d3fe3b10 100644
--- a/src/librustc/front/feature_gate.rs
+++ b/src/librustc/front/feature_gate.rs
@@ -31,7 +31,7 @@ use syntax::parse::token;
 use driver::session::Session;
 
 use std::cell::Cell;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 /// This is a list of all known features since the beginning of time. This list
 /// can never shrink, it may only be expanded (in order to prevent old programs
diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs
index 40747646167..8b403628f77 100644
--- a/src/librustc/front/std_inject.rs
+++ b/src/librustc/front/std_inject.rs
@@ -11,8 +11,8 @@
 
 use driver::session::Session;
 
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 use syntax::ast;
 use syntax::attr;
 use syntax::codemap::DUMMY_SP;
@@ -182,7 +182,7 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
             span: DUMMY_SP,
         };
 
-        let vis = vec_ng::append(vec!(vi2), module.view_items.as_slice());
+        let vis = vec::append(vec!(vi2), module.view_items.as_slice());
 
         // FIXME #2543: Bad copy.
         let new_module = ast::Mod {
diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs
index 6d8029b1638..2b71b0919c6 100644
--- a/src/librustc/front/test.rs
+++ b/src/librustc/front/test.rs
@@ -19,9 +19,9 @@ use front::std_inject::with_version;
 use metadata::creader::Loader;
 
 use std::cell::RefCell;
+use std::slice;
+use std::vec::Vec;
 use std::vec;
-use std::vec_ng::Vec;
-use std::vec_ng;
 use syntax::ast_util::*;
 use syntax::attr::AttrMetaMethods;
 use syntax::attr;
@@ -281,7 +281,7 @@ fn should_fail(i: @ast::Item) -> bool {
 fn add_test_module(cx: &TestCtxt, m: &ast::Mod) -> ast::Mod {
     let testmod = mk_test_module(cx);
     ast::Mod {
-        items: vec_ng::append_one(m.items.clone(), testmod),
+        items: vec::append_one(m.items.clone(), testmod),
         ..(*m).clone()
     }
 }
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 9409d8c457f..ba2760afe5d 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -55,8 +55,8 @@ use std::io;
 use std::os;
 use std::str;
 use std::task;
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 use syntax::ast;
 use syntax::diagnostic::Emitter;
 use syntax::diagnostic;
@@ -241,7 +241,7 @@ pub fn run_compiler(args: &[~str]) {
         return;
     }
 
-    let lint_flags = vec_ng::append(matches.opt_strs("W")
+    let lint_flags = vec::append(matches.opt_strs("W")
                                            .move_iter()
                                            .collect(),
                                     matches.opt_strs("warn"));
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index 74e180072fa..4133a742c60 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc/metadata/creader.rs
@@ -23,7 +23,7 @@ use metadata::loader;
 use metadata::loader::Os;
 
 use std::cell::RefCell;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use collections::HashMap;
 use syntax::ast;
 use syntax::abi;
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index d41d01f3c85..5ee01322913 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -20,8 +20,8 @@ use middle::typeck;
 
 use reader = serialize::ebml::reader;
 use std::rc::Rc;
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 use syntax::ast;
 use syntax::ast_map;
 use syntax::diagnostic::expect;
@@ -94,7 +94,7 @@ pub fn get_item_path(tcx: &ty::ctxt, def: ast::DefId) -> Vec<ast_map::PathElem>
 
     // FIXME #1920: This path is not always correct if the crate is not linked
     // into the root namespace.
-    vec_ng::append(vec!(ast_map::PathMod(token::intern(cdata.name))),
+    vec::append(vec!(ast_map::PathMod(token::intern(cdata.name))),
                    path.as_slice())
 }
 
diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs
index deadfb42904..886e46dc2a0 100644
--- a/src/librustc/metadata/cstore.rs
+++ b/src/librustc/metadata/cstore.rs
@@ -18,7 +18,7 @@ use metadata::decoder;
 use metadata::loader;
 
 use std::cell::RefCell;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use std::c_vec::CVec;
 use collections::HashMap;
 use syntax::ast;
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 8f785268ae0..449bda1eb5f 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -33,7 +33,7 @@ use std::io;
 use std::io::extensions::u64_from_be_bytes;
 use std::option;
 use std::rc::Rc;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use serialize::ebml::reader;
 use serialize::ebml;
 use serialize::Decodable;
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index b869e0a7d91..a50cb1cbdba 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -32,7 +32,7 @@ use std::hash;
 use std::hash::Hash;
 use std::io::MemWriter;
 use std::str;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use collections::HashMap;
 use syntax::abi::AbiSet;
 use syntax::ast::*;
diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs
index f73a3f35c2b..666f44c685f 100644
--- a/src/librustc/metadata/filesearch.rs
+++ b/src/librustc/metadata/filesearch.rs
@@ -13,7 +13,7 @@
 use std::cell::RefCell;
 use std::os;
 use std::io::fs;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use collections::HashSet;
 
 pub enum FileMatch { FileMatches, FileDoesntMatch }
diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs
index 28556105c7b..6a1e3663a54 100644
--- a/src/librustc/metadata/loader.rs
+++ b/src/librustc/metadata/loader.rs
@@ -30,8 +30,8 @@ use std::cmp;
 use std::io;
 use std::os::consts::{macos, freebsd, linux, android, win32};
 use std::str;
-use std::vec;
-use std::vec_ng::Vec;
+use std::slice;
+use std::vec::Vec;
 
 use collections::{HashMap, HashSet};
 use flate;
@@ -443,7 +443,7 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Result<MetadataBlob, ~st
                 debug!("checking {} bytes of metadata-version stamp",
                        vlen);
                 let minsz = cmp::min(vlen, csz);
-                let version_ok = vec::raw::buf_as_slice(cvbuf, minsz,
+                let version_ok = slice::raw::buf_as_slice(cvbuf, minsz,
                     |buf0| buf0 == encoder::metadata_encoding_version);
                 if !version_ok { return Err(format!("incompatible metadata version found: '{}'",
                                                     filename.display()));}
@@ -451,7 +451,7 @@ fn get_metadata_section_imp(os: Os, filename: &Path) -> Result<MetadataBlob, ~st
                 let cvbuf1 = cvbuf.offset(vlen as int);
                 debug!("inflating {} bytes of compressed metadata",
                        csz - vlen);
-                vec::raw::buf_as_slice(cvbuf1, csz-vlen, |bytes| {
+                slice::raw::buf_as_slice(cvbuf1, csz-vlen, |bytes| {
                     let inflated = flate::inflate_bytes(bytes);
                     found = Ok(MetadataVec(inflated));
                 });
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 1abbf1307c1..a990310a648 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -20,7 +20,7 @@ use middle::ty;
 
 use std::str;
 use std::uint;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::abi::AbiSet;
 use syntax::abi;
 use syntax::ast;
@@ -603,6 +603,9 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
             'P' => {
                 param_bounds.builtin_bounds.add(ty::BoundPod);
             }
+            'T' => {
+                param_bounds.builtin_bounds.add(ty::BoundShare);
+            }
             'I' => {
                 param_bounds.trait_bounds.push(@parse_trait_ref(st, |x,y| conv(x,y)));
             }
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index e78fe8e72a8..911729cd68a 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -19,7 +19,7 @@ use std::io;
 use std::io::MemWriter;
 use std::str;
 use std::fmt;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 use middle::ty::param_ty;
 use middle::ty;
@@ -280,11 +280,11 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) {
             enc_substs(w, cx, substs);
             mywrite!(w, "]");
         }
-        ty::ty_trait(def, ref substs, store, mt, bounds) => {
-            mywrite!(w, "x[{}|", (cx.ds)(def));
+        ty::ty_trait(~ty::TyTrait { def_id, ref substs, store, mutability, bounds }) => {
+            mywrite!(w, "x[{}|", (cx.ds)(def_id));
             enc_substs(w, cx, substs);
             enc_trait_store(w, cx, store);
-            enc_mutability(w, mt);
+            enc_mutability(w, mutability);
             let bounds = ty::ParamBounds {builtin_bounds: bounds,
                                           trait_bounds: Vec::new()};
             enc_bounds(w, cx, &bounds);
@@ -315,7 +315,7 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) {
         ty::ty_unboxed_vec(mt) => { mywrite!(w, "U"); enc_mt(w, cx, mt); }
         ty::ty_closure(ref f) => {
             mywrite!(w, "f");
-            enc_closure_ty(w, cx, f);
+            enc_closure_ty(w, cx, *f);
         }
         ty::ty_bare_fn(ref f) => {
             mywrite!(w, "F");
@@ -410,6 +410,7 @@ fn enc_bounds(w: &mut MemWriter, cx: &ctxt, bs: &ty::ParamBounds) {
             ty::BoundStatic => mywrite!(w, "O"),
             ty::BoundSized => mywrite!(w, "Z"),
             ty::BoundPod => mywrite!(w, "P"),
+            ty::BoundShare => mywrite!(w, "T"),
         }
     }
 
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 883883e5046..5fea567fc7d 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -37,7 +37,7 @@ use std::cast;
 use std::cell::RefCell;
 use std::io::Seek;
 use std::rc::Rc;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 use serialize::ebml::reader;
 use serialize::ebml;
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs
index 841123906cc..5db1324b3fe 100644
--- a/src/librustc/middle/borrowck/check_loans.rs
+++ b/src/librustc/middle/borrowck/check_loans.rs
@@ -23,7 +23,7 @@ use middle::borrowck::*;
 use middle::moves;
 use middle::ty;
 use middle::typeck::MethodCall;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::ast_util;
 use syntax::codemap::Span;
@@ -518,11 +518,11 @@ impl<'a> CheckLoanCtxt<'a> {
                                             expr: &ast::Expr,
                                             cmt: mc::cmt)
                                             -> bool {
-            match cmt.freely_aliasable() {
+            match cmt.freely_aliasable(this.tcx()) {
                 None => {
                     return true;
                 }
-                Some(mc::AliasableStaticMut) => {
+                Some(mc::AliasableStaticMut(..)) => {
                     return true;
                 }
                 Some(cause) => {
diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs
index 3c3c4371ebb..6e98d282f8f 100644
--- a/src/librustc/middle/borrowck/gather_loans/mod.rs
+++ b/src/librustc/middle/borrowck/gather_loans/mod.rs
@@ -27,7 +27,7 @@ use middle::typeck::MethodCall;
 use util::common::indenter;
 use util::ppaux::{Repr};
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::ast_util;
 use syntax::ast_util::IdRange;
@@ -82,10 +82,12 @@ impl<'a> visit::Visitor<()> for GatherLoanCtxt<'a> {
     fn visit_block(&mut self, b: &Block, _: ()) {
         gather_loans_in_block(self, b);
     }
-    fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block,
-                s: Span, n: NodeId, _: ()) {
-        gather_loans_in_fn(self, fk, fd, b, s, n);
-    }
+
+    /// Do not visit closures or fn items here, the outer loop in
+    /// borrowck/mod will visit them for us in turn.
+    fn visit_fn(&mut self, _: &FnKind, _: &FnDecl, _: &Block,
+                _: Span, _: NodeId, _: ()) {}
+
     fn visit_stmt(&mut self, s: &Stmt, _: ()) {
         visit::walk_stmt(self, s, ());
     }
@@ -99,10 +101,20 @@ impl<'a> visit::Visitor<()> for GatherLoanCtxt<'a> {
     // #7740: Do not visit items here, not even fn items nor methods
     // of impl items; the outer loop in borrowck/mod will visit them
     // for us in turn.  Thus override visit_item's walk with a no-op.
-    fn visit_item(&mut self, _: &ast::Item, _: ()) { }
+    fn visit_item(&mut self, _: &ast::Item, _: ()) {}
+}
+
+fn add_pat_to_id_range(this: &mut GatherLoanCtxt,
+                       p: &ast::Pat) {
+    // NB: This visitor function just adds the pat ids into the id
+    // range. We gather loans that occur in patterns using the
+    // `gather_pat()` method below. Eventually these two should be
+    // brought together.
+    this.id_range.add(p.id);
+    visit::walk_pat(this, p, ());
 }
 
-pub fn gather_loans(bccx: &BorrowckCtxt, decl: &ast::FnDecl, body: &ast::Block)
+pub fn gather_loans_in_fn(bccx: &BorrowckCtxt, decl: &ast::FnDecl, body: &ast::Block)
                     -> (IdRange, Vec<Loan>, move_data::MoveData) {
     let mut glcx = GatherLoanCtxt {
         bccx: bccx,
@@ -119,27 +131,6 @@ pub fn gather_loans(bccx: &BorrowckCtxt, decl: &ast::FnDecl, body: &ast::Block)
     (id_range, all_loans, move_data)
 }
 
-fn add_pat_to_id_range(this: &mut GatherLoanCtxt,
-                       p: &ast::Pat) {
-    // NB: This visitor function just adds the pat ids into the id
-    // range. We gather loans that occur in patterns using the
-    // `gather_pat()` method below. Eventually these two should be
-    // brought together.
-    this.id_range.add(p.id);
-    visit::walk_pat(this, p, ());
-}
-
-fn gather_loans_in_fn(_v: &mut GatherLoanCtxt,
-                      _fk: &FnKind,
-                      _decl: &ast::FnDecl,
-                      _body: &ast::Block,
-                      _sp: Span,
-                      _id: ast::NodeId) {
-    // Do not visit closures or fn items here, the outer loop in
-    // borrowck/mod will visit them for us in turn.
-    return;
-}
-
 fn gather_loans_in_block(this: &mut GatherLoanCtxt,
                          blk: &ast::Block) {
     this.id_range.add(blk.id);
@@ -171,6 +162,28 @@ fn gather_loans_in_local(this: &mut GatherLoanCtxt,
     visit::walk_local(this, local, ());
 }
 
+pub fn gather_loans_in_static_initializer(bccx: &mut BorrowckCtxt, expr: &ast::Expr) {
+
+    debug!("gather_loans_in_item(expr={})", expr.repr(bccx.tcx));
+
+    let mut glcx = GatherLoanCtxt {
+        bccx: bccx,
+        id_range: IdRange::max(),
+        all_loans: Vec::new(),
+        item_ub: expr.id,
+        repeating_ids: vec!(expr.id),
+        move_data: MoveData::new()
+    };
+
+    // FIXME #13005 This should also walk the
+    // expression.
+    match expr.node {
+        ast::ExprAddrOf(..) => {
+            glcx.visit_expr(expr, ());
+        }
+        _ => {}
+    }
+}
 
 fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
                         ex: &ast::Expr) {
@@ -673,34 +686,45 @@ impl<'a> GatherLoanCtxt<'a> {
                               -> Result<(),()> {
             //! Implements the A-* rules in doc.rs.
 
-            match req_kind {
-                ty::ImmBorrow => {
+            match (cmt.freely_aliasable(bccx.tcx), req_kind) {
+                (None, _) => {
+                    /* Uniquely accessible path -- OK for `&` and `&mut` */
                     Ok(())
                 }
-
-                ty::UniqueImmBorrow | ty::MutBorrow => {
-                    // Check for those cases where we cannot control
-                    // the aliasing and make sure that we are not
-                    // being asked to.
-                    match cmt.freely_aliasable() {
-                        None => {
-                            Ok(())
+                (Some(mc::AliasableStatic(safety)), ty::ImmBorrow) => {
+                    // Borrow of an immutable static item:
+                    match safety {
+                        mc::InteriorUnsafe => {
+                            // If the static item contains an Unsafe<T>, it has interior mutability.
+                            // In such cases, we cannot permit it to be borrowed, because the
+                            // static item resides in immutable memory and mutating it would
+                            // cause segfaults.
+                            bccx.tcx.sess.span_err(borrow_span,
+                                                   format!("borrow of immutable static items with \
+                                                            unsafe interior is not allowed"));
+                            Err(())
                         }
-                        Some(mc::AliasableStaticMut) => {
-                            // This is nasty, but we ignore the
-                            // aliasing rules if the data is based in
-                            // a `static mut`, since those are always
-                            // unsafe. At your own peril and all that.
+                        mc::InteriorSafe => {
+                            // Immutable static can be borrowed, no problem.
                             Ok(())
                         }
-                        Some(alias_cause) => {
-                            bccx.report_aliasability_violation(
+                    }
+                }
+                (Some(mc::AliasableStaticMut(..)), _) => {
+                    // Even touching a static mut is considered unsafe. We assume the
+                    // user knows what they're doing in these cases.
+                    Ok(())
+                }
+                (Some(alias_cause), ty::UniqueImmBorrow) |
+                (Some(alias_cause), ty::MutBorrow) => {
+                    bccx.report_aliasability_violation(
                                 borrow_span,
                                 BorrowViolation(loan_cause),
                                 alias_cause);
-                            Err(())
-                        }
-                    }
+                    Err(())
+                }
+                (_, _) => {
+                    Ok(())
                 }
             }
         }
diff --git a/src/librustc/middle/borrowck/gather_loans/restrictions.rs b/src/librustc/middle/borrowck/gather_loans/restrictions.rs
index 228e02fa0ac..fc5763b8841 100644
--- a/src/librustc/middle/borrowck/gather_loans/restrictions.rs
+++ b/src/librustc/middle/borrowck/gather_loans/restrictions.rs
@@ -12,8 +12,8 @@
  * Computes the restrictions that result from a borrow.
  */
 
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 use middle::borrowck::*;
 use mc = middle::mem_categorization;
 use middle::ty;
@@ -174,7 +174,7 @@ impl<'a> RestrictionsContext<'a> {
             Safe => Safe,
             SafeIf(base_lp, base_vec) => {
                 let lp = @LpExtend(base_lp, mc, elem);
-                SafeIf(lp, vec_ng::append_one(base_vec,
+                SafeIf(lp, vec::append_one(base_vec,
                                               Restriction {
                                                   loan_path: lp,
                                                   set: restrictions
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index bb6956556b5..1242fdbae6a 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -25,7 +25,7 @@ use std::cell::{Cell, RefCell};
 use collections::HashMap;
 use std::ops::{BitOr, BitAnd};
 use std::result::{Result};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util;
@@ -69,6 +69,10 @@ impl<'a> Visitor<()> for BorrowckCtxt<'a> {
                 b: &Block, s: Span, n: NodeId, _: ()) {
         borrowck_fn(self, fk, fd, b, s, n);
     }
+
+    fn visit_item(&mut self, item: &ast::Item, _: ()) {
+        borrowck_item(self, item);
+    }
 }
 
 pub fn check_crate(tcx: &ty::ctxt,
@@ -117,6 +121,21 @@ pub fn check_crate(tcx: &ty::ctxt,
     }
 }
 
+fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) {
+    // Gather loans for items. Note that we don't need
+    // to check loans for single expressions. The check
+    // loan step is intended for things that have a data
+    // flow dependent conditions.
+    match item.node {
+        ast::ItemStatic(_, _, ex) => {
+            gather_loans::gather_loans_in_static_initializer(this, ex);
+        }
+        _ => {
+            visit::walk_item(this, item, ());
+        }
+    }
+}
+
 fn borrowck_fn(this: &mut BorrowckCtxt,
                fk: &FnKind,
                decl: &ast::FnDecl,
@@ -127,7 +146,7 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
 
     // Check the body of fn items.
     let (id_range, all_loans, move_data) =
-        gather_loans::gather_loans(this, decl, body);
+        gather_loans::gather_loans_in_fn(this, decl, body);
     let mut loan_dfcx =
         DataFlowContext::new(this.tcx,
                              this.method_map,
@@ -715,8 +734,8 @@ impl<'a> BorrowckCtxt<'a> {
                     span,
                     format!("{} in an aliasable location", prefix));
             }
-            mc::AliasableStatic |
-            mc::AliasableStaticMut => {
+            mc::AliasableStatic(..) |
+            mc::AliasableStaticMut(..) => {
                 self.tcx.sess.span_err(
                     span,
                     format!("{} in a static location", prefix));
diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs
index 66e92583edb..5b2cca047cc 100644
--- a/src/librustc/middle/borrowck/move_data.rs
+++ b/src/librustc/middle/borrowck/move_data.rs
@@ -17,7 +17,7 @@ comments in the section "Moves and initialization" and in `doc.rs`.
 
 use std::cell::RefCell;
 use std::uint;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use collections::{HashMap, HashSet};
 use middle::borrowck::*;
 use middle::dataflow::DataFlowContext;
diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs
index 1c3f62df73f..8fee8b1bf9d 100644
--- a/src/librustc/middle/cfg/construct.rs
+++ b/src/librustc/middle/cfg/construct.rs
@@ -12,7 +12,7 @@ use middle::cfg::*;
 use middle::graph;
 use middle::typeck;
 use middle::ty;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::ast_util;
 use syntax::opt_vec;
diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs
index e980712d1aa..c6f114cfbc5 100644
--- a/src/librustc/middle/check_const.rs
+++ b/src/librustc/middle/check_const.rs
@@ -15,7 +15,7 @@ use middle::ty;
 use middle::typeck;
 use util::ppaux;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast::*;
 use syntax::{ast_util, ast_map};
 use syntax::visit::Visitor;
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index ee759e65240..fe4a58a62eb 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -21,8 +21,8 @@ use util::ppaux::ty_to_str;
 
 use std::cmp;
 use std::iter;
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 use syntax::ast::*;
 use syntax::ast_util::{unguarded_pat, walk_pat};
 use syntax::codemap::{DUMMY_SP, Span};
@@ -569,10 +569,10 @@ fn specialize(cx: &MatchCheckCtxt,
         Pat{id: pat_id, node: n, span: pat_span} =>
             match n {
             PatWild => {
-                Some(vec_ng::append(Vec::from_elem(arity, wild()), r.tail()))
+                Some(vec::append(Vec::from_elem(arity, wild()), r.tail()))
             }
             PatWildMulti => {
-                Some(vec_ng::append(Vec::from_elem(arity, wild_multi()),
+                Some(vec::append(Vec::from_elem(arity, wild_multi()),
                                     r.tail()))
             }
             PatIdent(_, _, _) => {
@@ -628,7 +628,7 @@ fn specialize(cx: &MatchCheckCtxt,
                     }
                     _ => {
                         Some(
-                            vec_ng::append(
+                            vec::append(
                                 Vec::from_elem(arity, wild()),
                                 r.tail()
                             )
@@ -682,7 +682,7 @@ fn specialize(cx: &MatchCheckCtxt,
                             Some(args) => args.iter().map(|x| *x).collect(),
                             None => Vec::from_elem(arity, wild())
                         };
-                        Some(vec_ng::append(args, r.tail()))
+                        Some(vec::append(args, r.tail()))
                     }
                     DefVariant(_, _, _) => None,
 
@@ -695,7 +695,7 @@ fn specialize(cx: &MatchCheckCtxt,
                             }
                             None => new_args = Vec::from_elem(arity, wild())
                         }
-                        Some(vec_ng::append(new_args, r.tail()))
+                        Some(vec::append(new_args, r.tail()))
                     }
                     _ => None
                 }
@@ -716,7 +716,7 @@ fn specialize(cx: &MatchCheckCtxt,
                                     _ => wild()
                                 }
                             });
-                            Some(vec_ng::append(args, r.tail()))
+                            Some(vec::append(args, r.tail()))
                         } else {
                             None
                         }
@@ -747,15 +747,15 @@ fn specialize(cx: &MatchCheckCtxt,
                                 _ => wild()
                             }
                         }).collect();
-                        Some(vec_ng::append(args, r.tail()))
+                        Some(vec::append(args, r.tail()))
                     }
                 }
             }
             PatTup(args) => {
-                Some(vec_ng::append(args.iter().map(|x| *x).collect(), r.tail()))
+                Some(vec::append(args.iter().map(|x| *x).collect(), r.tail()))
             }
             PatUniq(a) | PatRegion(a) => {
-                Some(vec_ng::append(vec!(a), r.tail()))
+                Some(vec::append(vec!(a), r.tail()))
             }
             PatLit(expr) => {
                 let e_v = eval_const_expr(cx.tcx, expr);
diff --git a/src/librustc/middle/check_static.rs b/src/librustc/middle/check_static.rs
index 83f987a0bd0..ecc3ba59dd5 100644
--- a/src/librustc/middle/check_static.rs
+++ b/src/librustc/middle/check_static.rs
@@ -18,8 +18,11 @@
 // - For each *immutable* static item, it checks that its **value**:
 //       - doesn't own owned, managed pointers
 //       - doesn't contain a struct literal or a call to an enum variant / struct constructor where
-//           - the type of the struct/enum is not freeze
 //           - the type of the struct/enum has a dtor
+//
+// Rules Enforced Elsewhere:
+// - It's not possible to take the address of a static item with unsafe interior. This is enforced
+// by borrowck::gather_loans
 
 use middle::ty;
 
@@ -121,21 +124,6 @@ impl<'a> Visitor<bool> for CheckStaticVisitor<'a> {
                 self.tcx.sess.span_err(e.span,
                                    "static items are not allowed to have owned pointers");
             }
-            ast::ExprProc(..) => {
-                self.report_error(e.span,
-                                  Some(~"immutable static items must be `Freeze`"));
-                return;
-            }
-            ast::ExprAddrOf(mutability, _) => {
-                match mutability {
-                    ast::MutMutable => {
-                        self.report_error(e.span,
-                                  Some(~"immutable static items must be `Freeze`"));
-                        return;
-                    }
-                    _ => {}
-                }
-            }
             _ => {
                 let node_ty = ty::node_id_to_type(self.tcx, e.id);
 
@@ -147,11 +135,6 @@ impl<'a> Visitor<bool> for CheckStaticVisitor<'a> {
                                      Some(~"static items are not allowed to have destructors"));
                             return;
                         }
-                        if Some(did) == self.tcx.lang_items.no_freeze_bound() {
-                            self.report_error(e.span,
-                                              Some(~"immutable static items must be `Freeze`"));
-                            return;
-                        }
                     }
                     _ => {}
                 }
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index c5a466f599d..0507c2541d6 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -26,7 +26,7 @@ use syntax::{ast, ast_map, ast_util};
 use std::cell::RefCell;
 use collections::HashMap;
 use std::rc::Rc;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 //
 // This pass classifies expressions by their constant-ness.
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index be49784cba1..949eabb30de 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -19,8 +19,8 @@
 
 use std::io;
 use std::uint;
-use std::vec;
-use std::vec_ng::Vec;
+use std::slice;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::ast_util;
 use syntax::ast_util::IdRange;
@@ -332,7 +332,7 @@ impl<'a, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, O> {
                 changed: true
             };
 
-            let mut temp = vec::from_elem(self.words_per_id, 0u);
+            let mut temp = slice::from_elem(self.words_per_id, 0u);
             let mut loop_scopes = Vec::new();
 
             while propcx.changed {
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 03d51f06ab5..58b8b55a2a0 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -19,7 +19,7 @@ use middle::typeck;
 use util::nodemap::NodeSet;
 
 use collections::HashSet;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util::{local_def, def_id_of_def, is_local};
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
index 88a6f7aa1e2..62e578886c5 100644
--- a/src/librustc/middle/entry.rs
+++ b/src/librustc/middle/entry.rs
@@ -11,7 +11,7 @@
 
 use driver::session;
 use driver::session::Session;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast::{Crate, Name, NodeId, Item, ItemFn};
 use syntax::ast_map;
 use syntax::attr;
diff --git a/src/librustc/middle/freevars.rs b/src/librustc/middle/freevars.rs
index 1ccc5e51487..af1d0c57237 100644
--- a/src/librustc/middle/freevars.rs
+++ b/src/librustc/middle/freevars.rs
@@ -17,7 +17,7 @@ use middle::resolve;
 use middle::ty;
 use util::nodemap::{NodeMap, NodeSet};
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::codemap::Span;
 use syntax::{ast, ast_util};
 use syntax::visit;
diff --git a/src/librustc/middle/graph.rs b/src/librustc/middle/graph.rs
index 160a541bc34..8f2cbb4d241 100644
--- a/src/librustc/middle/graph.rs
+++ b/src/librustc/middle/graph.rs
@@ -35,7 +35,7 @@ be indexed by the direction (see the type `Direction`).
 */
 
 use std::uint;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub struct Graph<N,E> {
     priv nodes: Vec<Node<N>> ,
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index cc1fdc76991..5c79020505a 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -16,7 +16,7 @@ use middle::typeck;
 use util::ppaux::{Repr, ty_to_str};
 use util::ppaux::UserString;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast::*;
 use syntax::attr;
 use syntax::codemap::Span;
@@ -208,21 +208,21 @@ fn with_appropriate_checker(cx: &Context,
 
     let fty = ty::node_id_to_type(cx.tcx, id);
     match ty::get(fty).sty {
-        ty::ty_closure(ty::ClosureTy {
+        ty::ty_closure(~ty::ClosureTy {
             sigil: OwnedSigil,
             bounds: bounds,
             ..
         }) => {
             b(|cx, fv| check_for_uniq(cx, fv, bounds))
         }
-        ty::ty_closure(ty::ClosureTy {
+        ty::ty_closure(~ty::ClosureTy {
             sigil: ManagedSigil,
             ..
         }) => {
             // can't happen
             fail!("internal error: saw closure with managed sigil (@fn)");
         }
-        ty::ty_closure(ty::ClosureTy {
+        ty::ty_closure(~ty::ClosureTy {
             sigil: BorrowedSigil,
             bounds: bounds,
             region: region,
@@ -358,7 +358,7 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
 fn check_trait_cast(cx: &mut Context, source_ty: ty::t, target_ty: ty::t, span: Span) {
     check_cast_for_escaping_regions(cx, source_ty, target_ty, span);
     match ty::get(target_ty).sty {
-        ty::ty_trait(_, _, _, _, bounds) => {
+        ty::ty_trait(~ty::TyTrait { bounds, .. }) => {
             check_trait_cast_bounds(cx, span, source_ty, bounds);
         }
         _ => {}
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 2ce34a31129..193c924f4e4 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -22,7 +22,7 @@
 
 use driver::session::Session;
 use metadata::csearch::each_lang_item;
-use middle::ty::{BuiltinBound, BoundFreeze, BoundPod, BoundSend, BoundSized};
+use middle::ty;
 use syntax::ast;
 use syntax::ast_util::local_def;
 use syntax::attr::AttrMetaMethods;
@@ -32,8 +32,8 @@ use syntax::visit;
 
 use collections::HashMap;
 use std::iter::Enumerate;
-use std::vec;
-use std::vec_ng::Vec;
+use std::slice;
+use std::vec::Vec;
 
 // The actual lang items defined come at the end of this file in one handy table.
 // So you probably just want to nip down to the end.
@@ -60,7 +60,7 @@ impl LanguageItems {
         }
     }
 
-    pub fn items<'a>(&'a self) -> Enumerate<vec::Items<'a, Option<ast::DefId>>> {
+    pub fn items<'a>(&'a self) -> Enumerate<slice::Items<'a, Option<ast::DefId>>> {
         self.items.iter().enumerate()
     }
 
@@ -82,15 +82,17 @@ impl LanguageItems {
         }
     }
 
-    pub fn to_builtin_kind(&self, id: ast::DefId) -> Option<BuiltinBound> {
+    pub fn to_builtin_kind(&self, id: ast::DefId) -> Option<ty::BuiltinBound> {
         if Some(id) == self.freeze_trait() {
-            Some(BoundFreeze)
+            Some(ty::BoundFreeze)
         } else if Some(id) == self.send_trait() {
-            Some(BoundSend)
+            Some(ty::BoundSend)
         } else if Some(id) == self.sized_trait() {
-            Some(BoundSized)
+            Some(ty::BoundSized)
         } else if Some(id) == self.pod_trait() {
-            Some(BoundPod)
+            Some(ty::BoundPod)
+        } else if Some(id) == self.share_trait() {
+            Some(ty::BoundShare)
         } else {
             None
         }
@@ -213,6 +215,7 @@ lets_do_this! {
     SendTraitLangItem,               "send",                    send_trait;
     SizedTraitLangItem,              "sized",                   sized_trait;
     PodTraitLangItem,                "pod",                     pod_trait;
+    ShareTraitLangItem,              "share",                   share_trait;
 
     DropTraitLangItem,               "drop",                    drop_trait;
 
@@ -230,6 +233,8 @@ lets_do_this! {
     ShrTraitLangItem,                "shr",                     shr_trait;
     IndexTraitLangItem,              "index",                   index_trait;
 
+    UnsafeTypeLangItem,              "unsafe",                  unsafe_type;
+
     DerefTraitLangItem,              "deref",                   deref_trait;
     DerefMutTraitLangItem,           "deref_mut",               deref_mut_trait;
 
@@ -274,5 +279,6 @@ lets_do_this! {
     NoFreezeItem,                    "no_freeze_bound",         no_freeze_bound;
     NoSendItem,                      "no_send_bound",           no_send_bound;
     NoPodItem,                       "no_pod_bound",            no_pod_bound;
+    NoShareItem,                     "no_share_bound",          no_share_bound;
     ManagedItem,                     "managed_bound",           managed_bound;
 }
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index 6ea26a9c5aa..0bdc8384b04 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -58,7 +58,7 @@ use std::u16;
 use std::u32;
 use std::u64;
 use std::u8;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use collections::SmallIntMap;
 use syntax::ast_map;
 use syntax::ast_util::IdVisitingOperation;
@@ -911,7 +911,7 @@ fn check_heap_type(cx: &Context, span: Span, ty: ty::t) {
                 }
                 ty::ty_uniq(_) | ty::ty_str(ty::vstore_uniq) |
                 ty::ty_vec(_, ty::vstore_uniq) |
-                ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => {
+                ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) => {
                     n_uniq += 1;
                 }
                 ty::ty_closure(ref c) if c.sigil == ast::OwnedSigil => {
@@ -1121,7 +1121,7 @@ fn check_deprecated_owned_vector(cx: &Context, e: &ast::Expr) {
     match ty::get(t).sty {
         ty::ty_vec(_, ty::vstore_uniq) => {
             cx.span_lint(DeprecatedOwnedVector, e.span,
-                         "use of deprecated `~[]` vector; replaced by `std::vec_ng::Vec`")
+                         "use of deprecated `~[]` vector; replaced by `std::vec::Vec`")
         }
         _ => {}
     }
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 62998186ba3..ee526f81c28 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -116,7 +116,7 @@ use std::io;
 use std::rc::Rc;
 use std::str;
 use std::uint;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast::*;
 use syntax::codemap::Span;
 use syntax::parse::token::special_idents;
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index be0aef64351..04d4b4c67de 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -66,7 +66,7 @@ use middle::ty;
 use middle::typeck;
 use util::ppaux::{ty_to_str, region_ptr_to_str, Repr};
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast::{MutImmutable, MutMutable};
 use syntax::ast;
 use syntax::codemap::Span;
@@ -170,10 +170,10 @@ pub enum deref_kind {
 pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
     match ty::get(t).sty {
         ty::ty_uniq(_) |
-        ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
+        ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) |
         ty::ty_vec(_, ty::vstore_uniq) |
         ty::ty_str(ty::vstore_uniq) |
-        ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, ..}) => {
+        ty::ty_closure(~ty::ClosureTy {sigil: ast::OwnedSigil, ..}) => {
             Some(deref_ptr(OwnedPtr))
         }
 
@@ -183,13 +183,13 @@ pub fn opt_deref_kind(t: ty::t) -> Option<deref_kind> {
             Some(deref_ptr(BorrowedPtr(kind, r)))
         }
 
-        ty::ty_trait(_, _, ty::RegionTraitStore(r), m, _) => {
+        ty::ty_trait(~ty::TyTrait { store: ty::RegionTraitStore(r), mutability: m, .. }) => {
             let kind = ty::BorrowKind::from_mutbl(m);
             Some(deref_ptr(BorrowedPtr(kind, r)))
         }
 
         ty::ty_str(ty::vstore_slice(r)) |
-        ty::ty_closure(ty::ClosureTy {sigil: ast::BorrowedSigil,
+        ty::ty_closure(~ty::ClosureTy {sigil: ast::BorrowedSigil,
                                       region: r, ..}) => {
             Some(deref_ptr(BorrowedPtr(ty::ImmBorrow, r)))
         }
@@ -1222,12 +1222,17 @@ pub fn field_mutbl(tcx: &ty::ctxt,
     return None;
 }
 
+pub enum InteriorSafety {
+    InteriorUnsafe,
+    InteriorSafe
+}
+
 pub enum AliasableReason {
     AliasableManaged,
     AliasableBorrowed,
     AliasableOther,
-    AliasableStatic,
-    AliasableStaticMut,
+    AliasableStatic(InteriorSafety),
+    AliasableStaticMut(InteriorSafety),
 }
 
 impl cmt_ {
@@ -1257,7 +1262,7 @@ impl cmt_ {
         }
     }
 
-    pub fn freely_aliasable(&self) -> Option<AliasableReason> {
+    pub fn freely_aliasable(&self, ctxt: &ty::ctxt) -> Option<AliasableReason> {
         /*!
          * Returns `Some(_)` if this lvalue represents a freely aliasable
          * pointer type.
@@ -1275,7 +1280,7 @@ impl cmt_ {
             cat_interior(b, _) |
             cat_discr(b, _) => {
                 // Aliasability depends on base cmt
-                b.freely_aliasable()
+                b.freely_aliasable(ctxt)
             }
 
             cat_copied_upvar(CopiedUpvar {onceness: ast::Once, ..}) |
@@ -1292,10 +1297,16 @@ impl cmt_ {
             }
 
             cat_static_item(..) => {
+                let int_safe = if ty::type_interior_is_unsafe(ctxt, self.ty) {
+                    InteriorUnsafe
+                } else {
+                    InteriorSafe
+                };
+
                 if self.mutbl.is_mutable() {
-                    Some(AliasableStaticMut)
+                    Some(AliasableStaticMut(int_safe))
                 } else {
-                    Some(AliasableStatic)
+                    Some(AliasableStatic(int_safe))
                 }
             }
 
diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs
index 3d476832fd6..0135b8d360b 100644
--- a/src/librustc/middle/moves.rs
+++ b/src/librustc/middle/moves.rs
@@ -138,7 +138,7 @@ use util::ppaux::UserString;
 use util::nodemap::{NodeMap, NodeSet};
 
 use std::rc::Rc;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast::*;
 use syntax::ast_util;
 use syntax::visit;
diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs
index 3e645491699..431f2820d6e 100644
--- a/src/librustc/middle/pat_util.rs
+++ b/src/librustc/middle/pat_util.rs
@@ -12,7 +12,7 @@
 use middle::resolve;
 
 use collections::HashMap;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast::*;
 use syntax::ast_util::{path_to_ident, walk_pat};
 use syntax::codemap::Span;
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index 1de38d8a461..e4f5b175836 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -13,7 +13,7 @@
 //! which are available for use externally when compiled as a library.
 
 use std::mem::replace;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 use metadata::csearch;
 use middle::lint;
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index 44a0fb61b24..a0ca416380f 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -20,7 +20,7 @@ use middle::typeck;
 use middle::privacy;
 use util::nodemap::NodeSet;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use collections::HashSet;
 use syntax::ast;
 use syntax::ast_map;
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index a13dce65f51..c0218429bb1 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -27,7 +27,7 @@ use middle::ty;
 use util::nodemap::NodeMap;
 
 use std::cell::RefCell;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use collections::{HashMap, HashSet};
 use syntax::codemap::Span;
 use syntax::{ast, visit};
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 7a14452158f..10f0002ea46 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -34,7 +34,7 @@ use syntax::visit::Visitor;
 use std::cell::{Cell, RefCell};
 use std::uint;
 use std::mem::replace;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use collections::{HashMap, HashSet};
 
 // Definition mapping
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index da424ea2e15..5d77d437bb9 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -18,7 +18,7 @@
  */
 
 use driver::session::Session;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use util::nodemap::NodeMap;
 use syntax::ast;
 use syntax::codemap::Span;
diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs
index f82b43adc43..25a2763ed2b 100644
--- a/src/librustc/middle/subst.rs
+++ b/src/librustc/middle/subst.rs
@@ -16,7 +16,7 @@ use middle::ty_fold::TypeFolder;
 use util::ppaux::Repr;
 
 use std::rc::Rc;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::codemap::Span;
 use syntax::opt_vec::OptVec;
 
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index 7d69db92af2..060cb692bce 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -225,8 +225,8 @@ use util::ppaux::{Repr, vec_map_to_str};
 
 use collections::HashMap;
 use std::cell::Cell;
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 use syntax::ast;
 use syntax::ast::Ident;
 use syntax::ast_util::path_to_ident;
@@ -463,9 +463,9 @@ fn expand_nested_bindings<'r,'b>(
     m.iter().map(|br| {
         match br.pats.get(col).node {
             ast::PatIdent(_, ref path, Some(inner)) => {
-                let pats = vec_ng::append(
+                let pats = vec::append(
                     Vec::from_slice(br.pats.slice(0u, col)),
-                    vec_ng::append(vec!(inner),
+                    vec::append(vec!(inner),
                                 br.pats.slice(col + 1u,
                                            br.pats.len())).as_slice());
 
@@ -513,8 +513,8 @@ fn enter_match<'r,'b>(
         match e(*br.pats.get(col)) {
             Some(sub) => {
                 let pats =
-                    vec_ng::append(
-                        vec_ng::append(sub, br.pats.slice(0u, col)),
+                    vec::append(
+                        vec::append(sub, br.pats.slice(0u, col)),
                         br.pats.slice(col + 1u, br.pats.len()));
 
                 let this = *br.pats.get(col);
@@ -1537,7 +1537,7 @@ fn compile_submatch_continue<'r,
     let tcx = bcx.tcx();
     let dm = tcx.def_map;
 
-    let vals_left = vec_ng::append(Vec::from_slice(vals.slice(0u, col)),
+    let vals_left = vec::append(Vec::from_slice(vals.slice(0u, col)),
                                    vals.slice(col + 1u, vals.len()));
     let ccx = bcx.fcx.ccx;
     let mut pat_id = 0;
@@ -1570,7 +1570,7 @@ fn compile_submatch_continue<'r,
                                             col,
                                             rec_fields.as_slice(),
                                             val).as_slice(),
-                        vec_ng::append(rec_vals,
+                        vec::append(rec_vals,
                                        vals_left.as_slice()).as_slice(),
                         chk);
             });
@@ -1596,7 +1596,7 @@ fn compile_submatch_continue<'r,
                                    col,
                                    val,
                                    n_tup_elts).as_slice(),
-                         vec_ng::append(tup_vals,
+                         vec::append(tup_vals,
                                         vals_left.as_slice()).as_slice(),
                          chk);
         return;
@@ -1622,7 +1622,7 @@ fn compile_submatch_continue<'r,
         compile_submatch(bcx,
                          enter_tuple_struct(bcx, dm, m, col, val,
                                             struct_element_count).as_slice(),
-                         vec_ng::append(llstructvals,
+                         vec::append(llstructvals,
                                         vals_left.as_slice()).as_slice(),
                          chk);
         return;
@@ -1632,7 +1632,7 @@ fn compile_submatch_continue<'r,
         let llbox = Load(bcx, val);
         compile_submatch(bcx,
                          enter_uniq(bcx, dm, m, col, val).as_slice(),
-                         vec_ng::append(vec!(llbox),
+                         vec::append(vec!(llbox),
                                         vals_left.as_slice()).as_slice(),
                          chk);
         return;
@@ -1642,7 +1642,7 @@ fn compile_submatch_continue<'r,
         let loaded_val = Load(bcx, val);
         compile_submatch(bcx,
                          enter_region(bcx, dm, m, col, val).as_slice(),
-                         vec_ng::append(vec!(loaded_val),
+                         vec::append(vec!(loaded_val),
                                         vals_left.as_slice()).as_slice(),
                          chk);
         return;
@@ -1824,7 +1824,7 @@ fn compile_submatch_continue<'r,
             lit(_) | range(_, _) => ()
         }
         let opt_ms = enter_opt(opt_cx, m, opt, col, size, val);
-        let opt_vals = vec_ng::append(unpacked, vals_left.as_slice());
+        let opt_vals = vec::append(unpacked, vals_left.as_slice());
 
         match branch_chk {
             None => {
diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs
index eb57ad022b6..7248792a51f 100644
--- a/src/librustc/middle/trans/adt.rs
+++ b/src/librustc/middle/trans/adt.rs
@@ -57,8 +57,8 @@ use middle::trans::type_::Type;
 use middle::trans::type_of;
 use middle::ty;
 use middle::ty::Disr;
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 use syntax::abi::{X86, X86_64, Arm, Mips};
 use syntax::ast;
 use syntax::attr;
@@ -226,7 +226,7 @@ fn represent_type_uncached(cx: &CrateContext, t: ty::t) -> Repr {
             return General(ity, cases.map(|c| {
                 let discr = vec!(ty_of_inttype(ity));
                 mk_struct(cx,
-                          vec_ng::append(discr, c.tys.as_slice()).as_slice(),
+                          vec::append(discr, c.tys.as_slice()).as_slice(),
                           false)
             }))
         }
@@ -758,10 +758,10 @@ pub fn trans_const(ccx: &CrateContext, r: &Repr, discr: Disr,
             let lldiscr = C_integral(ll_inttype(ccx, ity), discr as u64, true);
             let contents = build_const_struct(ccx,
                                               case,
-                                              vec_ng::append(
+                                              vec::append(
                                                   vec!(lldiscr),
                                                   vals).as_slice());
-            C_struct(ccx, vec_ng::append(
+            C_struct(ccx, vec::append(
                         contents,
                         &[padding(ccx, max_sz - case.size)]).as_slice(),
                      false)
diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs
index 7b04b519101..9624b58f566 100644
--- a/src/librustc/middle/trans/asm.rs
+++ b/src/librustc/middle/trans/asm.rs
@@ -23,7 +23,7 @@ use middle::trans::type_of;
 use middle::trans::type_::Type;
 
 use std::c_str::ToCStr;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 
 // Take an inline assembly expression and splat it out via LLVM
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index bcf0b5d5f64..20881eb243a 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -76,7 +76,7 @@ use std::c_str::ToCStr;
 use std::cell::{Cell, RefCell};
 use std::libc::c_uint;
 use std::local_data;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic, OsWin32};
 use syntax::ast_map::PathName;
 use syntax::ast_util::{local_def, is_local};
@@ -269,7 +269,7 @@ pub fn decl_rust_fn(ccx: &CrateContext, has_env: bool,
             // noalias because the actual object pointer is nested.
             ty::ty_uniq(..) | // ty::ty_trait(_, _, ty::UniqTraitStore, _, _) |
             ty::ty_vec(_, ty::vstore_uniq) | ty::ty_str(ty::vstore_uniq) |
-            ty::ty_closure(ty::ClosureTy {sigil: ast::OwnedSigil, ..}) => {
+            ty::ty_closure(~ty::ClosureTy {sigil: ast::OwnedSigil, ..}) => {
                 unsafe {
                     llvm::LLVMAddAttribute(llarg, lib::llvm::NoAliasAttribute as c_uint);
                 }
diff --git a/src/librustc/middle/trans/builder.rs b/src/librustc/middle/trans/builder.rs
index c403d323bf4..9b071807429 100644
--- a/src/librustc/middle/trans/builder.rs
+++ b/src/librustc/middle/trans/builder.rs
@@ -20,7 +20,7 @@ use middle::trans::type_::Type;
 
 use collections::HashMap;
 use std::libc::{c_uint, c_ulonglong, c_char};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::codemap::Span;
 
 pub struct Builder<'a> {
diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs
index d760c645441..79fdd737135 100644
--- a/src/librustc/middle/trans/cabi.rs
+++ b/src/librustc/middle/trans/cabi.rs
@@ -16,7 +16,7 @@ use middle::trans::cabi_x86_64;
 use middle::trans::cabi_arm;
 use middle::trans::cabi_mips;
 use middle::trans::type_::Type;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::abi::{X86, X86_64, Arm, Mips};
 
 #[deriving(Clone, Eq)]
@@ -25,7 +25,9 @@ pub enum ArgKind {
     /// LLVM type or by coercing to another specified type
     Direct,
     /// Pass the argument indirectly via a hidden pointer
-    Indirect
+    Indirect,
+    /// Ignore the argument (useful for empty struct)
+    Ignore,
 }
 
 /// Information about how a specific C type
@@ -68,6 +70,16 @@ impl ArgType {
         }
     }
 
+    pub fn ignore(ty: Type) -> ArgType {
+        ArgType {
+            kind: Ignore,
+            ty: ty,
+            cast: None,
+            pad: None,
+            attr: None,
+        }
+    }
+
     pub fn is_direct(&self) -> bool {
         return self.kind == Direct;
     }
@@ -75,6 +87,10 @@ impl ArgType {
     pub fn is_indirect(&self) -> bool {
         return self.kind == Indirect;
     }
+
+    pub fn is_ignore(&self) -> bool {
+        return self.kind == Ignore;
+    }
 }
 
 /// Metadata describing how the arguments to a native function
diff --git a/src/librustc/middle/trans/cabi_arm.rs b/src/librustc/middle/trans/cabi_arm.rs
index 83805cf844f..94e2a50c620 100644
--- a/src/librustc/middle/trans/cabi_arm.rs
+++ b/src/librustc/middle/trans/cabi_arm.rs
@@ -18,7 +18,7 @@ use middle::trans::type_::Type;
 
 use std::cmp;
 use std::option::{None, Some};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 fn align_up_to(off: uint, a: uint) -> uint {
     return (off + a - 1u) / a * a;
diff --git a/src/librustc/middle/trans/cabi_mips.rs b/src/librustc/middle/trans/cabi_mips.rs
index 68d9bb82a6c..7e94bf8e666 100644
--- a/src/librustc/middle/trans/cabi_mips.rs
+++ b/src/librustc/middle/trans/cabi_mips.rs
@@ -18,7 +18,7 @@ use middle::trans::context::CrateContext;
 use middle::trans::cabi::*;
 use middle::trans::type_::Type;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 fn align_up_to(off: uint, a: uint) -> uint {
     return (off + a - 1u) / a * a;
diff --git a/src/librustc/middle/trans/cabi_x86.rs b/src/librustc/middle/trans/cabi_x86.rs
index b2cb6970597..243a9dffdc6 100644
--- a/src/librustc/middle/trans/cabi_x86.rs
+++ b/src/librustc/middle/trans/cabi_x86.rs
@@ -15,7 +15,7 @@ use super::cabi::*;
 use super::common::*;
 use super::machine::*;
 use middle::trans::type_::Type;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn compute_abi_info(ccx: &CrateContext,
                         atys: &[Type],
@@ -63,8 +63,19 @@ pub fn compute_abi_info(ccx: &CrateContext,
         ret_ty = ArgType::direct(rty, None, None, None);
     }
 
-    for &a in atys.iter() {
-        arg_tys.push(ArgType::direct(a, None, None, None));
+    for &t in atys.iter() {
+        let ty = match t.kind() {
+            Struct => {
+                let size = llsize_of_alloc(ccx, t);
+                if size == 0 {
+                    ArgType::ignore(t)
+                } else {
+                    ArgType::indirect(t, Some(ByValAttribute))
+                }
+            }
+            _ => ArgType::direct(t, None, None, None),
+        };
+        arg_tys.push(ty);
     }
 
     return FnType {
diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs
index c1ae28005d9..bf9c969b7ef 100644
--- a/src/librustc/middle/trans/cabi_x86_64.rs
+++ b/src/librustc/middle/trans/cabi_x86_64.rs
@@ -21,7 +21,7 @@ use middle::trans::context::CrateContext;
 use middle::trans::type_::Type;
 
 use std::cmp;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 #[deriving(Clone, Eq)]
 enum RegClass {
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index 61a855a7f09..5af126615a1 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -16,7 +16,7 @@
  * closure.
  */
 
-use std::vec;
+use std::slice;
 
 use back::abi;
 use driver::session;
@@ -49,8 +49,8 @@ use util::ppaux::Repr;
 
 use middle::trans::type_::Type;
 
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 use syntax::ast;
 use syntax::abi::AbiSet;
 use syntax::ast_map;
@@ -230,10 +230,10 @@ fn resolve_default_method_vtables(bcx: &Block,
                 vtables.len() - num_method_vtables;
             vtables.tailn(num_impl_type_parameters).to_owned()
         },
-        None => vec::from_elem(num_method_vtables, @Vec::new())
+        None => slice::from_elem(num_method_vtables, @Vec::new())
     };
 
-    let param_vtables = @(vec_ng::append((*trait_vtables_fixed).clone(),
+    let param_vtables = @(vec::append((*trait_vtables_fixed).clone(),
                                           method_vtables));
 
     let self_vtables = resolve_param_vtables_under_param_substs(
diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs
index 05375ebeb31..daeafe4c897 100644
--- a/src/librustc/middle/trans/closure.rs
+++ b/src/librustc/middle/trans/closure.rs
@@ -27,7 +27,7 @@ use util::ppaux::Repr;
 use util::ppaux::ty_to_str;
 
 use arena::TypedArena;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::ast_util;
 
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index e812f36e85d..cb01d187957 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -35,7 +35,7 @@ use collections::HashMap;
 use std::c_str::ToCStr;
 use std::cell::{Cell, RefCell};
 use std::libc::{c_uint, c_longlong, c_ulonglong, c_char};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast::Ident;
 use syntax::ast;
 use syntax::ast_map::{PathElem, PathName};
diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs
index 390c40c0a75..49f07e140a3 100644
--- a/src/librustc/middle/trans/consts.rs
+++ b/src/librustc/middle/trans/consts.rs
@@ -33,9 +33,9 @@ use util::ppaux::{Repr, ty_to_str};
 
 use std::c_str::ToCStr;
 use std::libc::c_uint;
+use std::slice;
+use std::vec::Vec;
 use std::vec;
-use std::vec_ng::Vec;
-use std::vec_ng;
 use syntax::{ast, ast_util};
 
 pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: ast::Lit)
@@ -95,7 +95,7 @@ fn const_vec(cx: &CrateContext, e: &ast::Expr,
     let vec_ty = ty::expr_ty(cx.tcx(), e);
     let unit_ty = ty::sequence_element_type(cx.tcx(), vec_ty);
     let llunitty = type_of::type_of(cx, unit_ty);
-    let (vs, inlineable) = vec::unzip(es.iter().map(|e| const_expr(cx, *e, is_local)));
+    let (vs, inlineable) = slice::unzip(es.iter().map(|e| const_expr(cx, *e, is_local)));
     // If the vector contains enums, an LLVM array won't work.
     let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
         C_struct(cx, vs, false)
@@ -304,7 +304,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
         exprs.iter().map(|&e| const_expr(cx, e, is_local))
              .fold((Vec::new(), true),
                    |(l, all_inlineable), (val, inlineable)| {
-                (vec_ng::append_one(l, val), all_inlineable && inlineable)
+                (vec::append_one(l, val), all_inlineable && inlineable)
              })
     };
     unsafe {
@@ -563,7 +563,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
                           }
                       }
                   }).to_owned_vec();
-                  let (cs, inlineable) = vec::unzip(cs.move_iter());
+                  let (cs, inlineable) = slice::unzip(cs.move_iter());
                   (adt::trans_const(cx, repr, discr, cs),
                    inlineable.iter().fold(true, |a, &b| a && b))
               })
@@ -612,7 +612,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
                 const_eval::const_uint(i) => i as uint,
                 _ => cx.sess().span_bug(count.span, "count must be integral const expression.")
             };
-            let vs = vec::from_elem(n, const_expr(cx, elem, is_local).val0());
+            let vs = slice::from_elem(n, const_expr(cx, elem, is_local).val0());
             let v = if vs.iter().any(|vi| val_ty(*vi) != llunitty) {
                 C_struct(cx, vs, false)
             } else {
diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs
index 4ed4f0fb310..73869aa4622 100644
--- a/src/librustc/middle/trans/context.rs
+++ b/src/librustc/middle/trans/context.rs
@@ -33,7 +33,7 @@ use std::cell::{Cell, RefCell};
 use std::c_str::ToCStr;
 use std::libc::c_uint;
 use std::ptr;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use collections::{HashMap, HashSet};
 use syntax::ast;
 use syntax::parse::token::InternedString;
diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs
index b044ee15b3b..dc4a6e37c3e 100644
--- a/src/librustc/middle/trans/debuginfo.rs
+++ b/src/librustc/middle/trans/debuginfo.rs
@@ -148,8 +148,8 @@ use collections::HashSet;
 use std::libc::{c_uint, c_ulonglong, c_longlong};
 use std::ptr;
 use std::sync::atomics;
-use std::vec;
-use std::vec_ng::Vec;
+use std::slice;
+use std::vec::Vec;
 use syntax::codemap::{Span, Pos};
 use syntax::{abi, ast, codemap, ast_util, ast_map, opt_vec};
 use syntax::parse::token;
@@ -709,7 +709,7 @@ pub fn create_function_debug_context(cx: &CrateContext,
             return create_DIArray(DIB(cx), []);
         }
 
-        let mut signature = vec::with_capacity(fn_decl.inputs.len() + 1);
+        let mut signature = slice::with_capacity(fn_decl.inputs.len() + 1);
 
         // Return type -- llvm::DIBuilder wants this at index 0
         match fn_decl.output.node {
@@ -2126,7 +2126,9 @@ fn type_metadata(cx: &CrateContext,
         ty::ty_closure(ref closurety) => {
             subroutine_type_metadata(cx, &closurety.sig, usage_site_span)
         },
-        ty::ty_trait(def_id, ref substs, trait_store, mutability, ref bounds) => {
+        ty::ty_trait(~ty::TyTrait { def_id, ref substs,
+                                store: trait_store, mutability,
+                                ref bounds }) => {
             trait_metadata(cx, def_id, t, substs, trait_store, mutability, bounds)
         },
         ty::ty_struct(def_id, ref substs) => {
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index a38322ef0dc..75b14c081f9 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -70,8 +70,8 @@ use util::nodemap::NodeMap;
 use middle::trans::machine::llsize_of;
 use middle::trans::type_::Type;
 
-use std::vec;
-use std::vec_ng::Vec;
+use std::slice;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::codemap;
 use syntax::print::pprust::{expr_to_str};
@@ -1010,7 +1010,7 @@ fn trans_rec_or_struct<'a>(
     let ty = node_id_type(bcx, id);
     let tcx = bcx.tcx();
     with_field_tys(tcx, ty, Some(id), |discr, field_tys| {
-        let mut need_base = vec::from_elem(field_tys.len(), true);
+        let mut need_base = slice::from_elem(field_tys.len(), true);
 
         let numbered_fields = fields.map(|field| {
             let opt_pos =
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs
index 7f6781096f5..be9888a61d7 100644
--- a/src/librustc/middle/trans/foreign.rs
+++ b/src/librustc/middle/trans/foreign.rs
@@ -27,7 +27,7 @@ use middle::ty::FnSig;
 use middle::ty;
 use std::cmp;
 use std::libc::c_uint;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::abi::{Cdecl, Aapcs, C, AbiSet, Win64};
 use syntax::abi::{RustIntrinsic, Rust, Stdcall, Fastcall, System};
 use syntax::codemap::Span;
@@ -325,6 +325,10 @@ pub fn trans_native_call<'a>(
     for (i, &llarg_rust) in llargs_rust.iter().enumerate() {
         let mut llarg_rust = llarg_rust;
 
+        if arg_tys[i].is_ignore() {
+            continue;
+        }
+
         // Does Rust pass this argument by pointer?
         let rust_indirect = type_of::arg_is_indirect(ccx,
                                                      *passed_arg_tys.get(i));
@@ -901,6 +905,9 @@ fn lltype_for_fn_from_foreign_types(ccx: &CrateContext, tys: &ForeignTypes) -> T
     };
 
     for &arg_ty in tys.fn_ty.arg_tys.iter() {
+        if arg_ty.is_ignore() {
+            continue;
+        }
         // add padding
         match arg_ty.pad {
             Some(ty) => llargument_tys.push(ty),
@@ -949,6 +956,9 @@ fn add_argument_attributes(tys: &ForeignTypes,
     }
 
     for &arg_ty in tys.fn_ty.arg_tys.iter() {
+        if arg_ty.is_ignore() {
+            continue;
+        }
         // skip padding
         if arg_ty.pad.is_some() { i += 1; }
 
diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs
index 3a1572559dd..836433e1dae 100644
--- a/src/librustc/middle/trans/glue.rs
+++ b/src/librustc/middle/trans/glue.rs
@@ -310,7 +310,7 @@ fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) -> &'a Block<'
                 }
             }
         }
-        ty::ty_trait(_, _, ty::UniqTraitStore, _, _) => {
+        ty::ty_trait(~ty::TyTrait { store: ty::UniqTraitStore, .. }) => {
             let lluniquevalue = GEPi(bcx, v0, [0, abi::trt_field_box]);
             // Only drop the value when it is non-null
             with_cond(bcx, IsNotNull(bcx, Load(bcx, lluniquevalue)), |bcx| {
diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs
index 98e63641c12..e7ccb52108f 100644
--- a/src/librustc/middle/trans/intrinsic.rs
+++ b/src/librustc/middle/trans/intrinsic.rs
@@ -25,7 +25,7 @@ use middle::trans::machine;
 use middle::trans::machine::llsize_of;
 use middle::trans::type_::Type;
 use middle::ty;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::ast_map;
 use syntax::parse::token;
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index cd33bcf6031..b248bf39645 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -34,8 +34,8 @@ use util::common::indenter;
 use util::ppaux::Repr;
 
 use std::c_str::ToCStr;
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 use syntax::parse::token;
 use syntax::{ast, ast_map, visit};
 
@@ -324,7 +324,7 @@ fn combine_impl_and_methods_tps(bcx: &Block,
     let node_substs = node_id_type_params(bcx, node);
     debug!("rcvr_substs={:?}", rcvr_substs.repr(ccx.tcx()));
     let ty_substs
-        = vec_ng::append(Vec::from_slice(rcvr_substs),
+        = vec::append(Vec::from_slice(rcvr_substs),
                          node_substs.tailn(node_substs.len() - n_m_tps));
     debug!("n_m_tps={:?}", n_m_tps);
     debug!("node_substs={:?}", node_substs.repr(ccx.tcx()));
@@ -348,7 +348,7 @@ fn combine_impl_and_methods_tps(bcx: &Block,
         None => @Vec::from_elem(node_substs.len(), @Vec::new())
     };
     let vtables
-        = @vec_ng::append(Vec::from_slice(rcvr_origins.as_slice()),
+        = @vec::append(Vec::from_slice(rcvr_origins.as_slice()),
                           r_m_origins.tailn(r_m_origins.len() - n_m_tps));
 
     (ty_substs, vtables)
diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs
index 0d9b6a087f9..aed1f1b24d0 100644
--- a/src/librustc/middle/trans/monomorphize.rs
+++ b/src/librustc/middle/trans/monomorphize.rs
@@ -23,7 +23,7 @@ use middle::ty;
 use middle::typeck;
 use util::ppaux::Repr;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util::local_def;
diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs
index 397361b83e0..833f33c720a 100644
--- a/src/librustc/middle/trans/reflect.rs
+++ b/src/librustc/middle/trans/reflect.rs
@@ -28,8 +28,8 @@ use util::ppaux::ty_to_str;
 use arena::TypedArena;
 use std::libc::c_uint;
 use std::option::{Some,None};
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 use syntax::ast::DefId;
 use syntax::ast;
 use syntax::ast_map;
@@ -134,7 +134,7 @@ impl<'a> Reflector<'a> {
                                  -> (~str, Vec<ValueRef> ) {
         match vstore {
             ty::vstore_fixed(n) => {
-                let extra = vec_ng::append(vec!(self.c_uint(n)),
+                let extra = vec::append(vec!(self.c_uint(n)),
                                            self.c_size_and_align(t)
                                                .as_slice());
                 (~"fixed", extra)
@@ -184,7 +184,7 @@ impl<'a> Reflector<'a> {
           }
           ty::ty_vec(ref mt, vst) => {
               let (name, extra) = self.vstore_name_and_extra(t, vst);
-              let extra = vec_ng::append(extra, self.c_mt(mt).as_slice());
+              let extra = vec::append(extra, self.c_mt(mt).as_slice());
               self.visit(~"evec_" + name, extra.as_slice())
           }
           // Should remove mt from box and uniq.
@@ -212,7 +212,7 @@ impl<'a> Reflector<'a> {
           }
 
           ty::ty_tup(ref tys) => {
-              let extra = vec_ng::append(vec!(self.c_uint(tys.len())),
+              let extra = vec::append(vec!(self.c_uint(tys.len())),
                                          self.c_size_and_align(t).as_slice());
               self.bracketed("tup", extra.as_slice(), |this| {
                   for (i, t) in tys.iter().enumerate() {
@@ -260,7 +260,7 @@ impl<'a> Reflector<'a> {
                       special_idents::unnamed_field.name;
               }
 
-              let extra = vec_ng::append(vec!(
+              let extra = vec::append(vec!(
                   self.c_slice(token::intern_and_get_ident(ty_to_str(tcx,
                                                                      t))),
                   self.c_bool(named_fields),
@@ -268,7 +268,7 @@ impl<'a> Reflector<'a> {
               ), self.c_size_and_align(t).as_slice());
               self.bracketed("class", extra.as_slice(), |this| {
                   for (i, field) in fields.iter().enumerate() {
-                      let extra = vec_ng::append(vec!(
+                      let extra = vec::append(vec!(
                         this.c_uint(i),
                         this.c_slice(token::get_ident(field.ident)),
                         this.c_bool(named_fields)
@@ -321,7 +321,7 @@ impl<'a> Reflector<'a> {
                 llfdecl
             };
 
-            let enum_args = vec_ng::append(vec!(self.c_uint(variants.len()),
+            let enum_args = vec::append(vec!(self.c_uint(variants.len()),
                                                 make_get_disr()),
                                            self.c_size_and_align(t)
                                                .as_slice());
@@ -351,7 +351,7 @@ impl<'a> Reflector<'a> {
             })
           }
 
-          ty::ty_trait(_, _, _, _, _) => {
+          ty::ty_trait(..) => {
               let extra = [
                   self.c_slice(token::intern_and_get_ident(ty_to_str(tcx, t)))
               ];
diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs
index bd1a7498d21..2a0c65216a7 100644
--- a/src/librustc/middle/trans/type_.rs
+++ b/src/librustc/middle/trans/type_.rs
@@ -20,8 +20,8 @@ use syntax::abi::{X86, X86_64, Arm, Mips};
 
 use std::c_str::ToCStr;
 use std::cast;
-use std::vec;
-use std::vec_ng::Vec;
+use std::slice;
+use std::vec::Vec;
 
 use std::libc::{c_uint};
 
@@ -263,7 +263,7 @@ impl Type {
     pub fn get_field(&self, idx: uint) -> Type {
         unsafe {
             let num_fields = llvm::LLVMCountStructElementTypes(self.to_ref()) as uint;
-            let mut elems = vec::from_elem(num_fields, 0 as TypeRef);
+            let mut elems = slice::from_elem(num_fields, 0 as TypeRef);
 
             llvm::LLVMGetStructElementTypes(self.to_ref(), elems.as_mut_ptr());
 
diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs
index 32821f32df5..c8f8df17a74 100644
--- a/src/librustc/middle/trans/type_of.rs
+++ b/src/librustc/middle/trans/type_of.rs
@@ -19,7 +19,7 @@ use util::ppaux::Repr;
 
 use middle::trans::type_::Type;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::opt_vec;
 
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index ae940ebeef2..6dc31f7fdaa 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -40,8 +40,8 @@ use std::fmt;
 use std::hash::{Hash, sip};
 use std::ops;
 use std::rc::Rc;
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 use collections::{HashMap, HashSet};
 use syntax::ast::*;
 use syntax::ast_util::{is_local, lit_is_str};
@@ -746,8 +746,8 @@ pub enum sty {
     ty_ptr(mt),
     ty_rptr(Region, mt),
     ty_bare_fn(BareFnTy),
-    ty_closure(ClosureTy),
-    ty_trait(DefId, substs, TraitStore, ast::Mutability, BuiltinBounds),
+    ty_closure(~ClosureTy),
+    ty_trait(~TyTrait),
     ty_struct(DefId, substs),
     ty_tup(Vec<t>),
 
@@ -764,6 +764,15 @@ pub enum sty {
     ty_unboxed_vec(mt),
 }
 
+#[deriving(Clone, Eq, Hash)]
+pub struct TyTrait {
+    def_id: DefId,
+    substs: substs,
+    store: TraitStore,
+    mutability: ast::Mutability,
+    bounds: BuiltinBounds
+}
+
 #[deriving(Eq, Hash)]
 pub struct TraitRef {
     def_id: DefId,
@@ -841,6 +850,7 @@ pub enum BuiltinBound {
     BoundFreeze,
     BoundSized,
     BoundPod,
+    BoundShare,
 }
 
 pub fn EmptyBuiltinBounds() -> BuiltinBounds {
@@ -853,6 +863,7 @@ pub fn AllBuiltinBounds() -> BuiltinBounds {
     set.add(BoundSend);
     set.add(BoundFreeze);
     set.add(BoundSized);
+    set.add(BoundShare);
     set
 }
 
@@ -1205,10 +1216,10 @@ pub fn mk_t(cx: &ctxt, st: sty) -> t {
       &ty_infer(_) => flags |= needs_infer as uint,
       &ty_self(_) => flags |= has_self as uint,
       &ty_enum(_, ref substs) | &ty_struct(_, ref substs) |
-      &ty_trait(_, ref substs, _, _, _) => {
+      &ty_trait(~ty::TyTrait { ref substs, .. }) => {
           flags |= sflags(substs);
           match st {
-              ty_trait(_, _, RegionTraitStore(r), _, _) => {
+              ty_trait(~ty::TyTrait { store: RegionTraitStore(r), .. }) => {
                     flags |= rflags(r);
                 }
               _ => {}
@@ -1398,7 +1409,7 @@ pub fn mk_mut_unboxed_vec(cx: &ctxt, ty: t) -> t {
 pub fn mk_tup(cx: &ctxt, ts: Vec<t>) -> t { mk_t(cx, ty_tup(ts)) }
 
 pub fn mk_closure(cx: &ctxt, fty: ClosureTy) -> t {
-    mk_t(cx, ty_closure(fty))
+    mk_t(cx, ty_closure(~fty))
 }
 
 pub fn mk_bare_fn(cx: &ctxt, fty: BareFnTy) -> t {
@@ -1432,7 +1443,14 @@ pub fn mk_trait(cx: &ctxt,
                 bounds: BuiltinBounds)
              -> t {
     // take a copy of substs so that we own the vectors inside
-    mk_t(cx, ty_trait(did, substs, store, mutability, bounds))
+    let inner = ~TyTrait {
+        def_id: did,
+        substs: substs,
+        store: store,
+        mutability: mutability,
+        bounds: bounds
+    };
+    mk_t(cx, ty_trait(inner))
 }
 
 pub fn mk_struct(cx: &ctxt, struct_id: ast::DefId, substs: substs) -> t {
@@ -1472,7 +1490,7 @@ pub fn maybe_walk_ty(ty: t, f: |t| -> bool) {
             maybe_walk_ty(tm.ty, f);
         }
         ty_enum(_, ref substs) | ty_struct(_, ref substs) |
-        ty_trait(_, ref substs, _, _, _) => {
+        ty_trait(~TyTrait { ref substs, .. }) => {
             for subty in (*substs).tps.iter() { maybe_walk_ty(*subty, |x| f(x)); }
         }
         ty_tup(ref ts) => { for tt in ts.iter() { maybe_walk_ty(*tt, |x| f(x)); } }
@@ -1856,31 +1874,33 @@ macro_rules! def_type_content_sets(
 
 def_type_content_sets!(
     mod TC {
-        None                                = 0b0000__00000000__0000,
+        None                                = 0b0000_0000__0000_0000__0000,
 
         // Things that are interior to the value (first nibble):
-        InteriorUnsized                     = 0b0000__00000000__0001,
-        // InteriorAll                         = 0b0000__00000000__1111,
+        InteriorUnsized                     = 0b0000_0000__0000_0000__0001,
+        InteriorUnsafe                      = 0b0000_0000__0000_0000__0010,
+        // InteriorAll                         = 0b00000000__00000000__1111,
 
         // Things that are owned by the value (second and third nibbles):
-        OwnsOwned                           = 0b0000__00000001__0000,
-        OwnsDtor                            = 0b0000__00000010__0000,
-        OwnsManaged /* see [1] below */     = 0b0000__00000100__0000,
-        OwnsAffine                          = 0b0000__00001000__0000,
-        OwnsAll                             = 0b0000__11111111__0000,
+        OwnsOwned                           = 0b0000_0000__0000_0001__0000,
+        OwnsDtor                            = 0b0000_0000__0000_0010__0000,
+        OwnsManaged /* see [1] below */     = 0b0000_0000__0000_0100__0000,
+        OwnsAffine                          = 0b0000_0000__0000_1000__0000,
+        OwnsAll                             = 0b0000_0000__1111_1111__0000,
 
         // Things that are reachable by the value in any way (fourth nibble):
-        ReachesNonsendAnnot                 = 0b0001__00000000__0000,
-        ReachesBorrowed                     = 0b0010__00000000__0000,
-        // ReachesManaged /* see [1] below */  = 0b0100__00000000__0000,
-        ReachesMutable                      = 0b1000__00000000__0000,
-        ReachesAll                          = 0b1111__00000000__0000,
+        ReachesNonsendAnnot                 = 0b0000_0001__0000_0000__0000,
+        ReachesBorrowed                     = 0b0000_0010__0000_0000__0000,
+        // ReachesManaged /* see [1] below */  = 0b0000_0100__0000_0000__0000,
+        ReachesMutable                      = 0b0000_1000__0000_0000__0000,
+        ReachesNoShare                      = 0b0001_0000__0000_0000__0000,
+        ReachesAll                          = 0b0001_1111__0000_0000__0000,
 
         // Things that cause values to *move* rather than *copy*
-        Moves                               = 0b0000__00001011__0000,
+        Moves                               = 0b0000_0000__0000_1011__0000,
 
         // Things that mean drop glue is necessary
-        NeedsDrop                           = 0b0000__00000111__0000,
+        NeedsDrop                           = 0b0000_0000__0000_0111__0000,
 
         // Things that prevent values from being sent
         //
@@ -1889,31 +1909,34 @@ def_type_content_sets!(
         //       both ReachesManaged and OwnsManaged so that when
         //       a parameter has a bound T:Send, we are able to deduce
         //       that it neither reaches nor owns a managed pointer.
-        Nonsendable                         = 0b0111__00000100__0000,
+        Nonsendable                         = 0b0000_0111__0000_0100__0000,
 
         // Things that prevent values from being considered freezable
-        Nonfreezable                        = 0b1000__00000000__0000,
+        Nonfreezable                        = 0b0000_1000__0000_0000__0000,
 
         // Things that prevent values from being considered 'static
-        Nonstatic                           = 0b0010__00000000__0000,
+        Nonstatic                           = 0b0000_0010__0000_0000__0000,
 
         // Things that prevent values from being considered sized
-        Nonsized                            = 0b0000__00000000__0001,
+        Nonsized                            = 0b0000_0000__0000_0000__0001,
+
+        // Things that prevent values from being shared
+        Nonsharable                         = 0b0001_0000__0000_0000__0000,
 
         // Things that make values considered not POD (would be same
         // as `Moves`, but for the fact that managed data `@` is
         // not considered POD)
-        Nonpod                              = 0b0000__00001111__0000,
+        Nonpod                              = 0b0000_0000__0000_1111__0000,
 
         // Bits to set when a managed value is encountered
         //
         // [1] Do not set the bits TC::OwnsManaged or
         //     TC::ReachesManaged directly, instead reference
         //     TC::Managed to set them both at once.
-        Managed                             = 0b0100__00000100__0000,
+        Managed                             = 0b0000_0100__0000_0100__0000,
 
         // All bits
-        All                                 = 0b1111__11111111__1111
+        All                                 = 0b1111_1111__1111_1111__1111
     }
 )
 
@@ -1929,6 +1952,7 @@ impl TypeContents {
             BoundSend => self.is_sendable(cx),
             BoundSized => self.is_sized(cx),
             BoundPod => self.is_pod(cx),
+            BoundShare => self.is_sharable(cx),
         }
     }
 
@@ -1948,6 +1972,10 @@ impl TypeContents {
         !self.intersects(TC::Nonsendable)
     }
 
+    pub fn is_sharable(&self, _: &ctxt) -> bool {
+        !self.intersects(TC::Nonsharable)
+    }
+
     pub fn owns_managed(&self) -> bool {
         self.intersects(TC::OwnsManaged)
     }
@@ -1968,6 +1996,10 @@ impl TypeContents {
         !self.intersects(TC::Nonpod)
     }
 
+    pub fn interior_unsafe(&self) -> bool {
+        self.intersects(TC::InteriorUnsafe)
+    }
+
     pub fn moves_by_default(&self, _: &ctxt) -> bool {
         self.intersects(TC::Moves)
     }
@@ -2064,6 +2096,10 @@ pub fn type_is_freezable(cx: &ctxt, t: ty::t) -> bool {
     type_contents(cx, t).is_freezable(cx)
 }
 
+pub fn type_interior_is_unsafe(cx: &ctxt, t: ty::t) -> bool {
+    type_contents(cx, t).interior_unsafe()
+}
+
 pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
     let ty_id = type_id(ty);
 
@@ -2133,7 +2169,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
             }
 
             ty_closure(ref c) => {
-                closure_contents(cx, c)
+                closure_contents(cx, *c)
             }
 
             ty_box(typ) => {
@@ -2144,8 +2180,8 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
                 tc_ty(cx, typ, cache).owned_pointer()
             }
 
-            ty_trait(_, _, store, mutbl, bounds) => {
-                object_contents(cx, store, mutbl, bounds)
+            ty_trait(~ty::TyTrait { store, mutability, bounds, .. }) => {
+                object_contents(cx, store, mutability, bounds)
             }
 
             ty_ptr(ref mt) => {
@@ -2268,6 +2304,10 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
             tc | TC::Managed
         } else if Some(did) == cx.lang_items.no_pod_bound() {
             tc | TC::OwnsAffine
+        } else if Some(did) == cx.lang_items.no_share_bound() {
+            tc | TC::ReachesNoShare
+        } else if Some(did) == cx.lang_items.unsafe_type() {
+            tc | TC::InteriorUnsafe
         } else {
             tc
         }
@@ -2346,6 +2386,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
                 BoundFreeze => TC::Nonfreezable,
                 BoundSized => TC::Nonsized,
                 BoundPod => TC::Nonpod,
+                BoundShare => TC::Nonsharable,
             };
         });
         return tc;
@@ -2437,7 +2478,7 @@ pub fn is_instantiable(cx: &ctxt, r_ty: t) -> bool {
                 false           // unsafe ptrs can always be NULL
             }
 
-            ty_trait(_, _, _, _, _) => {
+            ty_trait(..) => {
                 false
             }
 
@@ -2854,7 +2895,7 @@ pub fn ty_region(tcx: &ctxt,
 pub fn replace_fn_sig(cx: &ctxt, fsty: &sty, new_sig: FnSig) -> t {
     match *fsty {
         ty_bare_fn(ref f) => mk_bare_fn(cx, BareFnTy {sig: new_sig, ..*f}),
-        ty_closure(ref f) => mk_closure(cx, ClosureTy {sig: new_sig, ..*f}),
+        ty_closure(ref f) => mk_closure(cx, ClosureTy {sig: new_sig, ..**f}),
         ref s => {
             cx.sess.bug(
                 format!("ty_fn_sig() called on non-fn type: {:?}", s));
@@ -2872,7 +2913,7 @@ pub fn replace_closure_return_type(tcx: &ctxt, fn_type: t, ret_type: t) -> t {
         ty::ty_closure(ref fty) => {
             ty::mk_closure(tcx, ClosureTy {
                 sig: FnSig {output: ret_type, ..fty.sig.clone()},
-                ..(*fty).clone()
+                ..(**fty).clone()
             })
         }
         _ => {
@@ -2885,7 +2926,7 @@ pub fn replace_closure_return_type(tcx: &ctxt, fn_type: t, ret_type: t) -> t {
 
 // Returns a vec of all the input and output types of fty.
 pub fn tys_in_fn_sig(sig: &FnSig) -> Vec<t> {
-    vec_ng::append_one(sig.inputs.map(|a| *a), sig.output)
+    vec::append_one(sig.inputs.map(|a| *a), sig.output)
 }
 
 // Type accessors for AST nodes
@@ -3124,7 +3165,7 @@ pub fn adjust_ty(cx: &ctxt,
                 ty::mk_closure(cx, ClosureTy {
                     sigil: BorrowedSigil,
                     region: r,
-                    ..(*fty).clone()
+                    ..(**fty).clone()
                 })
             }
 
@@ -3140,9 +3181,9 @@ pub fn adjust_ty(cx: &ctxt,
     fn borrow_obj(cx: &ctxt, span: Span, r: Region,
                   m: ast::Mutability, ty: ty::t) -> ty::t {
         match get(ty).sty {
-            ty_trait(trt_did, ref trt_substs, _, _, b) => {
-                ty::mk_trait(cx, trt_did, trt_substs.clone(),
-                             RegionTraitStore(r), m, b)
+            ty_trait(~ty::TyTrait {def_id, ref substs, bounds, .. }) => {
+                ty::mk_trait(cx, def_id, substs.clone(),
+                             RegionTraitStore(r), m, bounds)
             }
             ref s => {
                 cx.sess.span_bug(
@@ -3218,7 +3259,7 @@ pub fn method_call_type_param_defs(tcx: &ctxt, origin: typeck::MethodOrigin)
             // trait itself.  This ought to be harmonized.
             let trait_type_param_defs =
                 lookup_trait_def(tcx, trt_id).generics.type_param_defs();
-            Rc::new(vec_ng::append(
+            Rc::new(vec::append(
                 Vec::from_slice(trait_type_param_defs),
                 ty::trait_method(tcx,
                                  trt_id,
@@ -3479,7 +3520,7 @@ pub fn ty_sort_str(cx: &ctxt, t: t) -> ~str {
         ty_rptr(_, _) => ~"&-ptr",
         ty_bare_fn(_) => ~"extern fn",
         ty_closure(_) => ~"fn",
-        ty_trait(id, _, _, _, _) => format!("trait {}", item_path_str(cx, id)),
+        ty_trait(ref inner) => format!("trait {}", item_path_str(cx, inner.def_id)),
         ty_struct(id, _) => format!("struct {}", item_path_str(cx, id)),
         ty_tup(_) => ~"tuple",
         ty_infer(TyVar(_)) => ~"inferred type",
@@ -3865,7 +3906,7 @@ pub fn try_add_builtin_trait(tcx: &ctxt,
 
 pub fn ty_to_def_id(ty: t) -> Option<ast::DefId> {
     match get(ty).sty {
-      ty_trait(id, _, _, _, _) | ty_struct(id, _) | ty_enum(id, _) => Some(id),
+      ty_trait(~TyTrait { def_id: id, .. }) | ty_struct(id, _) | ty_enum(id, _) => Some(id),
       _ => None
     }
 }
@@ -4951,7 +4992,7 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
                 hash!(c.bounds);
                 region(&mut state, c.region);
             }
-            ty_trait(d, _, store, m, bounds) => {
+            ty_trait(~ty::TyTrait { def_id: d, store, mutability: m, bounds, .. }) => {
                 byte!(17);
                 did(&mut state, d);
                 match store {
diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs
index 2456c607317..caec263389f 100644
--- a/src/librustc/middle/ty_fold.rs
+++ b/src/librustc/middle/ty_fold.rs
@@ -13,7 +13,7 @@
 use middle::ty;
 use util::ppaux::Repr;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub trait TypeFolder {
     fn tcx<'a>(&'a self) -> &'a ty::ctxt;
@@ -159,12 +159,14 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
         ty::ty_enum(tid, ref substs) => {
             ty::ty_enum(tid, this.fold_substs(substs))
         }
-        ty::ty_trait(did, ref substs, st, mutbl, bounds) => {
-            ty::ty_trait(did,
-                     this.fold_substs(substs),
-                     this.fold_trait_store(st),
-                     mutbl,
-                     bounds)
+        ty::ty_trait(~ty::TyTrait { def_id, ref substs, store, mutability, bounds }) => {
+            ty::ty_trait(~ty::TyTrait{
+                def_id: def_id,
+                substs: this.fold_substs(substs),
+                store: this.fold_trait_store(store),
+                mutability: mutability,
+                bounds: bounds
+            })
         }
         ty::ty_tup(ref ts) => {
             ty::ty_tup(fold_ty_vec(this, ts.as_slice()))
@@ -173,7 +175,7 @@ pub fn super_fold_sty<T:TypeFolder>(this: &mut T,
             ty::ty_bare_fn(this.fold_bare_fn_ty(f))
         }
         ty::ty_closure(ref f) => {
-            ty::ty_closure(this.fold_closure_ty(f))
+            ty::ty_closure(~this.fold_closure_ty(*f))
         }
         ty::ty_rptr(r, ref tm) => {
             ty::ty_rptr(this.fold_region(r),
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index 658538bcec8..177cadbce46 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -60,7 +60,7 @@ use middle::typeck::rscope::{RegionScope};
 use middle::typeck::lookup_def_tcx;
 use util::ppaux::Repr;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::abi::AbiSet;
 use syntax::{ast, ast_util};
 use syntax::codemap::Span;
diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs
index bfb0ab6400d..8ba2c63ecb1 100644
--- a/src/librustc/middle/typeck/check/_match.rs
+++ b/src/librustc/middle/typeck/check/_match.rs
@@ -20,7 +20,7 @@ use middle::typeck::infer;
 use middle::typeck::require_same_types;
 
 use collections::{HashMap, HashSet};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::ast_util;
 use syntax::parse::token;
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index 5d232b488a6..0a95a891398 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -97,8 +97,8 @@ use util::ppaux::Repr;
 
 use collections::HashSet;
 use std::result;
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 use syntax::ast::{DefId, SelfValue, SelfRegion};
 use syntax::ast::{SelfUniq, SelfStatic};
 use syntax::ast::{MutMutable, MutImmutable};
@@ -417,9 +417,9 @@ impl<'a> LookupContext<'a> {
         let span = self.self_expr.map_or(self.span, |e| e.span);
         check::autoderef(self.fcx, span, self_ty, None, PreferMutLvalue, |self_ty, _| {
             match get(self_ty).sty {
-                ty_trait(did, ref substs, _, _, _) => {
-                    self.push_inherent_candidates_from_object(did, substs);
-                    self.push_inherent_impl_candidates_for_type(did);
+                ty_trait(~TyTrait { def_id, ref substs, .. }) => {
+                    self.push_inherent_candidates_from_object(def_id, substs);
+                    self.push_inherent_impl_candidates_for_type(def_id);
                 }
                 ty_enum(did, _) | ty_struct(did, _) => {
                     if self.check_traits == CheckTraitsAndInherentMethods {
@@ -775,10 +775,12 @@ impl<'a> LookupContext<'a> {
                      autoderefs: autoderefs,
                      autoref: Some(ty::AutoBorrowVec(region, self_mt.mutbl))})
             }
-            ty::ty_trait(did, ref substs, ty::RegionTraitStore(_), mutbl, bounds) => {
+            ty::ty_trait(~ty::TyTrait {
+                def_id, ref substs, store: ty::RegionTraitStore(_), mutability: mutbl, bounds
+            }) => {
                 let region =
                     self.infcx().next_region_var(infer::Autoref(self.span));
-                (ty::mk_trait(tcx, did, substs.clone(),
+                (ty::mk_trait(tcx, def_id, substs.clone(),
                               ty::RegionTraitStore(region),
                               mutbl, bounds),
                  ty::AutoDerefRef {
@@ -860,7 +862,7 @@ impl<'a> LookupContext<'a> {
                     })
             }
 
-            ty_trait(trt_did, trt_substs, _, _, b) => {
+            ty_trait(~ty::TyTrait { def_id: trt_did, substs: trt_substs, bounds: b, .. }) => {
                 // Coerce ~/@/&Trait instances to &Trait.
 
                 self.search_for_some_kind_of_autorefd_method(
@@ -1116,7 +1118,7 @@ impl<'a> LookupContext<'a> {
         // Construct the full set of type parameters for the method,
         // which is equal to the class tps + the method tps.
         let all_substs = substs {
-            tps: vec_ng::append(candidate.rcvr_substs.tps.clone(),
+            tps: vec::append(candidate.rcvr_substs.tps.clone(),
                                 m_substs.as_slice()),
             regions: NonerasedRegions(all_regions),
             self_ty: candidate.rcvr_substs.self_ty,
@@ -1301,7 +1303,9 @@ impl<'a> LookupContext<'a> {
                         rcvr_matches_ty(self.fcx, mt.ty, candidate)
                     }
 
-                    ty::ty_trait(self_did, _, RegionTraitStore(_), self_m, _) => {
+                    ty::ty_trait(~ty::TyTrait {
+                        def_id: self_did, store: RegionTraitStore(_), mutability: self_m, ..
+                    }) => {
                         mutability_matches(self_m, m) &&
                         rcvr_matches_object(self_did, candidate)
                     }
@@ -1317,7 +1321,9 @@ impl<'a> LookupContext<'a> {
                         rcvr_matches_ty(self.fcx, typ, candidate)
                     }
 
-                    ty::ty_trait(self_did, _, UniqTraitStore, _, _) => {
+                    ty::ty_trait(~ty::TyTrait {
+                        def_id: self_did, store: UniqTraitStore, ..
+                    }) => {
                         rcvr_matches_object(self_did, candidate)
                     }
 
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 205c1c106dd..13808d6df13 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -118,9 +118,9 @@ use std::cell::{Cell, RefCell};
 use collections::HashMap;
 use std::mem::replace;
 use std::result;
+use std::slice;
+use std::vec::Vec;
 use std::vec;
-use std::vec_ng::Vec;
-use std::vec_ng;
 use syntax::abi::AbiSet;
 use syntax::ast::{Provided, Required};
 use syntax::ast;
@@ -910,7 +910,7 @@ fn compare_impl_method(tcx: &ty::ctxt,
                 bound_region: ty::BrNamed(l.def_id, l.name)})).
         collect();
     let dummy_substs = ty::substs {
-        tps: vec_ng::append(dummy_impl_tps, dummy_method_tps.as_slice()),
+        tps: vec::append(dummy_impl_tps, dummy_method_tps.as_slice()),
         regions: ty::NonerasedRegions(dummy_impl_regions),
         self_ty: None };
 
@@ -937,7 +937,7 @@ fn compare_impl_method(tcx: &ty::ctxt,
                      self_ty: self_ty } = trait_substs.subst(tcx, &dummy_substs);
         let substs = substs {
             regions: trait_regions,
-            tps: vec_ng::append(trait_tps, dummy_method_tps.as_slice()),
+            tps: vec::append(trait_tps, dummy_method_tps.as_slice()),
             self_ty: self_ty,
         };
         debug!("trait_fty (pre-subst): {} substs={}",
@@ -1860,7 +1860,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
 
         let fn_sig = match *fn_sty {
             ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, ..}) |
-            ty::ty_closure(ty::ClosureTy {sig: ref sig, ..}) => sig,
+            ty::ty_closure(~ty::ClosureTy {sig: ref sig, ..}) => sig,
             _ => {
                 fcx.type_error_message(call_expr.span, |actual| {
                     format!("expected function but \
@@ -3978,7 +3978,7 @@ pub fn check_bounds_are_used(ccx: &CrateCtxt,
 
     // make a vector of booleans initially false, set to true when used
     if tps.len() == 0u { return; }
-    let mut tps_used = vec::from_elem(tps.len(), false);
+    let mut tps_used = slice::from_elem(tps.len(), false);
 
     ty::walk_ty(ty, |t| {
             match ty::get(t).sty {
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index 4610305a70b..1533943a55c 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -542,7 +542,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             // explaining how it goes about doing that.
             let target_ty = rcx.resolve_node_type(expr.id);
             match ty::get(target_ty).sty {
-                ty::ty_trait(_, _, ty::RegionTraitStore(trait_region), _, _) => {
+                ty::ty_trait(~ty::TyTrait { store: ty::RegionTraitStore(trait_region), .. }) => {
                     let source_ty = rcx.resolve_expr_type_adjusted(source);
                     constrain_regions_in_type(
                         rcx,
@@ -610,7 +610,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
     let tcx = rcx.fcx.tcx();
     let function_type = rcx.resolve_node_type(expr.id);
     match ty::get(function_type).sty {
-        ty::ty_closure(ty::ClosureTy {
+        ty::ty_closure(~ty::ClosureTy {
                 sigil: ast::BorrowedSigil, region: region, ..}) => {
             let freevars = freevars::get_freevars(tcx, expr.id);
             if freevars.is_empty() {
@@ -635,7 +635,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
     rcx.set_repeating_scope(repeating_scope);
 
     match ty::get(function_type).sty {
-        ty::ty_closure(ty::ClosureTy {sigil: ast::BorrowedSigil, ..}) => {
+        ty::ty_closure(~ty::ClosureTy {sigil: ast::BorrowedSigil, ..}) => {
             let freevars = freevars::get_freevars(tcx, expr.id);
             propagate_upupvar_borrow_kind(rcx, expr, freevars);
         }
diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs
index 45eab7c7e62..479a1e94b67 100644
--- a/src/librustc/middle/typeck/check/regionmanip.rs
+++ b/src/librustc/middle/typeck/check/regionmanip.rs
@@ -15,7 +15,7 @@ use middle::ty_fold;
 use middle::ty_fold::TypeFolder;
 
 use collections::HashMap;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use util::ppaux::Repr;
 use util::ppaux;
 
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
index 600f0d6e3f2..9d181b27b4f 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -30,7 +30,7 @@ use util::ppaux::Repr;
 use collections::HashSet;
 use std::cell::RefCell;
 use std::result;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::ast_util;
 use syntax::codemap::Span;
@@ -479,7 +479,7 @@ fn fixup_substs(vcx: &VtableContext,
                          ty::EmptyBuiltinBounds());
     fixup_ty(vcx, span, t, is_early).map(|t_f| {
         match ty::get(t_f).sty {
-          ty::ty_trait(_, ref substs_f, _, _, _) => (*substs_f).clone(),
+          ty::ty_trait(ref inner) => inner.substs.clone(),
           _ => fail!("t_f should be a trait")
         }
     })
@@ -537,8 +537,10 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
     let resolve_object_cast = |src: &ast::Expr, target_ty: ty::t| {
       match ty::get(target_ty).sty {
           // Bounds of type's contents are not checked here, but in kind.rs.
-          ty::ty_trait(target_def_id, ref target_substs, store,
-                       target_mutbl, _bounds) => {
+          ty::ty_trait(~ty::TyTrait {
+              def_id: target_def_id, substs: ref target_substs, store: store,
+              mutability: target_mutbl, bounds: _bounds
+          }) => {
               fn mutability_allowed(a_mutbl: ast::Mutability,
                                     b_mutbl: ast::Mutability) -> bool {
                   a_mutbl == b_mutbl ||
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs
index 1c03328bcea..e68fb5c7f13 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc/middle/typeck/check/writeback.rs
@@ -28,7 +28,7 @@ use middle::typeck::write_ty_to_tcx;
 use util::ppaux;
 use util::ppaux::Repr;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::print::pprust::pat_to_str;
diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs
index 894c70c7b61..c50f15ed816 100644
--- a/src/librustc/middle/typeck/coherence.rs
+++ b/src/librustc/middle/typeck/coherence.rs
@@ -48,8 +48,8 @@ use syntax::visit;
 use collections::HashSet;
 use std::cell::RefCell;
 use std::rc::Rc;
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 
 struct UniversalQuantificationResult {
     monotype: t,
@@ -106,7 +106,7 @@ fn type_is_defined_in_local_crate(original_type: t) -> bool {
     ty::walk_ty(original_type, |t| {
         match get(t).sty {
             ty_enum(def_id, _) |
-            ty_trait(def_id, _, _, _, _) |
+            ty_trait(~ty::TyTrait { def_id, .. }) |
             ty_struct(def_id, _) => {
                 if def_id.krate == ast::LOCAL_CRATE {
                     found_nominal = true;
@@ -132,7 +132,7 @@ fn get_base_type_def_id(inference_context: &InferCtxt,
             match get(base_type).sty {
                 ty_enum(def_id, _) |
                 ty_struct(def_id, _) |
-                ty_trait(def_id, _, _, _, _) => {
+                ty_trait(~ty::TyTrait { def_id, .. }) => {
                     return Some(def_id);
                 }
                 _ => {
@@ -347,7 +347,7 @@ impl<'a> CoherenceChecker<'a> {
             // construct the polytype for the method based on the method_ty
             let new_generics = ty::Generics {
                 type_param_defs:
-                    Rc::new(vec_ng::append(
+                    Rc::new(vec::append(
                         Vec::from_slice(impl_poly_type.generics
                                                       .type_param_defs()),
                             new_method_ty.generics.type_param_defs())),
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index f65c168f382..6d15b3fd1f0 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -46,8 +46,8 @@ use util::ppaux;
 use util::ppaux::Repr;
 
 use std::rc::Rc;
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 use collections::HashSet;
 
 use syntax::abi::AbiSet;
@@ -330,7 +330,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt, trait_id: ast::NodeId) {
         let substs = substs {
             regions: ty::NonerasedRegions(rps_from_trait),
             self_ty: Some(self_param),
-            tps: vec_ng::append(non_shifted_trait_tps,
+            tps: vec::append(non_shifted_trait_tps,
                                 shifted_method_tps.as_slice())
         };
 
@@ -510,11 +510,11 @@ fn convert_methods(ccx: &CrateCtxt,
                 // itself
                 ty_param_bounds_and_ty {
                     generics: ty::Generics {
-                        type_param_defs: Rc::new(vec_ng::append(
+                        type_param_defs: Rc::new(vec::append(
                             Vec::from_slice(
                                 rcvr_ty_generics.type_param_defs()),
                             m_ty_generics.type_param_defs())),
-                        region_param_defs: Rc::new(vec_ng::append(
+                        region_param_defs: Rc::new(vec::append(
                                 Vec::from_slice(rcvr_ty_generics.region_param_defs()),
                                 m_ty_generics.region_param_defs())),
                     },
diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs
index d8166108947..5dc55ab4b5c 100644
--- a/src/librustc/middle/typeck/infer/coercion.rs
+++ b/src/librustc/middle/typeck/infer/coercion.rs
@@ -119,7 +119,7 @@ impl<'f> Coerce<'f> {
                 });
             }
 
-            ty::ty_closure(ty::ClosureTy {sigil: ast::BorrowedSigil, ..}) => {
+            ty::ty_closure(~ty::ClosureTy {sigil: ast::BorrowedSigil, ..}) => {
                 return self.unpack_actual_value(a, |sty_a| {
                     self.coerce_borrowed_fn(a, sty_a, b)
                 });
@@ -131,7 +131,9 @@ impl<'f> Coerce<'f> {
                 });
             }
 
-            ty::ty_trait(def_id, ref substs, ty::UniqTraitStore, m, bounds) => {
+            ty::ty_trait(~ty::TyTrait {
+                def_id, ref substs, store: ty::UniqTraitStore, mutability: m, bounds
+            }) => {
                 let result = self.unpack_actual_value(a, |sty_a| {
                     match *sty_a {
                         ty::ty_uniq(..) => {
@@ -148,7 +150,9 @@ impl<'f> Coerce<'f> {
                 }
             }
 
-            ty::ty_trait(def_id, ref substs, ty::RegionTraitStore(region), m, bounds) => {
+            ty::ty_trait(~ty::TyTrait {
+                def_id, ref substs, store: ty::RegionTraitStore(region), mutability: m, bounds
+            }) => {
                 let result = self.unpack_actual_value(a, |sty_a| {
                     match *sty_a {
                         ty::ty_rptr(..) => {
@@ -313,9 +317,9 @@ impl<'f> Coerce<'f> {
         let r_a = self.get_ref().infcx.next_region_var(Coercion(self.get_ref().trace));
 
         let a_borrowed = match *sty_a {
-            ty::ty_trait(did, ref substs, _, _, b) => {
-                ty::mk_trait(tcx, did, substs.clone(),
-                             ty::RegionTraitStore(r_a), b_mutbl, b)
+            ty::ty_trait(~ty::TyTrait { def_id, ref substs, bounds, .. }) => {
+                ty::mk_trait(tcx, def_id, substs.clone(),
+                             ty::RegionTraitStore(r_a), b_mutbl, bounds)
             }
             _ => {
                 return self.subtype(a, b);
@@ -357,7 +361,7 @@ impl<'f> Coerce<'f> {
             ty::ClosureTy {
                 sigil: ast::BorrowedSigil,
                 region: r_borrow,
-                ..fn_ty
+                .. *fn_ty
             });
 
         if_ok!(self.subtype(a_borrowed, b));
@@ -393,7 +397,7 @@ impl<'f> Coerce<'f> {
             let a_closure = ty::mk_closure(self.get_ref().infcx.tcx,
                                            ty::ClosureTy {
                                                 sig: fn_ty_a.sig.clone(),
-                                                ..fn_ty_b
+                                                .. *fn_ty_b
                                            });
             if_ok!(self.subtype(a_closure, b));
             Ok(Some(adj))
diff --git a/src/librustc/middle/typeck/infer/combine.rs b/src/librustc/middle/typeck/infer/combine.rs
index f6894f44099..5b52a3551dd 100644
--- a/src/librustc/middle/typeck/infer/combine.rs
+++ b/src/librustc/middle/typeck/infer/combine.rs
@@ -63,7 +63,7 @@ use util::common::indent;
 use util::ppaux::Repr;
 
 use std::result;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast::{Onceness, Purity};
 use syntax::ast;
 use syntax::opt_vec;
@@ -500,18 +500,18 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
           Ok(ty::mk_enum(tcx, a_id, substs))
       }
 
-      (&ty::ty_trait(a_id, ref a_substs, a_store, a_mutbl, a_bounds),
-       &ty::ty_trait(b_id, ref b_substs, b_store, b_mutbl, b_bounds))
-      if a_id == b_id && a_mutbl == b_mutbl => {
+      (&ty::ty_trait(ref a_),
+       &ty::ty_trait(ref b_))
+      if a_.def_id == b_.def_id && a_.mutability == b_.mutability => {
           debug!("Trying to match traits {:?} and {:?}", a, b);
-          let substs = if_ok!(this.substs(a_id, a_substs, b_substs));
-          let s = if_ok!(this.trait_stores(ty::terr_trait, a_store, b_store));
-          let bounds = if_ok!(this.bounds(a_bounds, b_bounds));
+          let substs = if_ok!(this.substs(a_.def_id, &a_.substs, &b_.substs));
+          let s = if_ok!(this.trait_stores(ty::terr_trait, a_.store, b_.store));
+          let bounds = if_ok!(this.bounds(a_.bounds, b_.bounds));
           Ok(ty::mk_trait(tcx,
-                          a_id,
+                          a_.def_id,
                           substs.clone(),
                           s,
-                          a_mutbl,
+                          a_.mutability,
                           bounds))
       }
 
@@ -570,7 +570,7 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
       }
 
       (&ty::ty_closure(ref a_fty), &ty::ty_closure(ref b_fty)) => {
-        this.closure_tys(a_fty, b_fty).and_then(|fty| {
+        this.closure_tys(*a_fty, *b_fty).and_then(|fty| {
             Ok(ty::mk_closure(tcx, fty))
         })
       }
diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs
index b0cd5e361e9..1f6708a6f5c 100644
--- a/src/librustc/middle/typeck/infer/error_reporting.rs
+++ b/src/librustc/middle/typeck/infer/error_reporting.rs
@@ -76,7 +76,7 @@ use middle::typeck::infer::region_inference::ProcessedErrors;
 use middle::typeck::infer::region_inference::SameRegions;
 use std::cell::{Cell, RefCell};
 use std::char::from_u32;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::ast_map;
 use syntax::ast_util;
diff --git a/src/librustc/middle/typeck/infer/lattice.rs b/src/librustc/middle/typeck/infer/lattice.rs
index a97f1561c8d..ce344c9d561 100644
--- a/src/librustc/middle/typeck/infer/lattice.rs
+++ b/src/librustc/middle/typeck/infer/lattice.rs
@@ -46,7 +46,7 @@ use middle::typeck::infer::to_str::InferStr;
 use util::common::indenter;
 
 use collections::HashMap;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub trait LatticeValue {
     fn sub(cf: &CombineFields, a: &Self, b: &Self) -> ures;
diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs
index 07948477800..ccc589f0eef 100644
--- a/src/librustc/middle/typeck/infer/mod.rs
+++ b/src/librustc/middle/typeck/infer/mod.rs
@@ -39,7 +39,7 @@ use middle::typeck::infer::unify::{ValsAndBindings, Root};
 use middle::typeck::infer::error_reporting::ErrorReporting;
 use std::cell::{Cell, RefCell};
 use std::result;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast::{MutImmutable, MutMutable};
 use syntax::ast;
 use syntax::codemap;
@@ -719,7 +719,7 @@ impl<'a> InferCtxt<'a> {
                                   ty::EmptyBuiltinBounds());
         let dummy1 = self.resolve_type_vars_if_possible(dummy0);
         match ty::get(dummy1).sty {
-            ty::ty_trait(ref def_id, ref substs, _, _, _) => {
+            ty::ty_trait(~ty::TyTrait { ref def_id, ref substs, .. }) => {
                 ty::TraitRef {
                     def_id: *def_id,
                     substs: (*substs).clone(),
@@ -976,4 +976,3 @@ impl Repr for RegionVariableOrigin {
         }
     }
 }
-
diff --git a/src/librustc/middle/typeck/infer/region_inference/mod.rs b/src/librustc/middle/typeck/infer/region_inference/mod.rs
index 415367eea62..6019de0b2d9 100644
--- a/src/librustc/middle/typeck/infer/region_inference/mod.rs
+++ b/src/librustc/middle/typeck/infer/region_inference/mod.rs
@@ -26,8 +26,8 @@ use util::ppaux::{Repr};
 
 use std::cell::{Cell, RefCell};
 use std::uint;
-use std::vec;
-use std::vec_ng::Vec;
+use std::slice;
+use std::vec::Vec;
 use collections::{HashMap, HashSet};
 use syntax::ast;
 use syntax::opt_vec;
@@ -1049,7 +1049,7 @@ impl<'a> RegionVarBindings<'a> {
         // idea is to report errors that derive from independent
         // regions of the graph, but not those that derive from
         // overlapping locations.
-        let mut dup_vec = vec::from_elem(self.num_vars(), uint::MAX);
+        let mut dup_vec = slice::from_elem(self.num_vars(), uint::MAX);
 
         let mut opt_graph = None;
 
diff --git a/src/librustc/middle/typeck/infer/resolve.rs b/src/librustc/middle/typeck/infer/resolve.rs
index f91e20a649b..929b4ac433c 100644
--- a/src/librustc/middle/typeck/infer/resolve.rs
+++ b/src/librustc/middle/typeck/infer/resolve.rs
@@ -58,7 +58,7 @@ use middle::typeck::infer::unify::{Root, UnifyInferCtxtMethods};
 use util::common::{indent, indenter};
 use util::ppaux::ty_to_str;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 
 pub static resolve_nested_tvar: uint = 0b0000000001;
diff --git a/src/librustc/middle/typeck/infer/unify.rs b/src/librustc/middle/typeck/infer/unify.rs
index 57a08d211c7..a5c95bbfd5a 100644
--- a/src/librustc/middle/typeck/infer/unify.rs
+++ b/src/librustc/middle/typeck/infer/unify.rs
@@ -17,7 +17,7 @@ use middle::typeck::infer::{Bounds, uok, ures};
 use middle::typeck::infer::InferCtxt;
 use middle::typeck::infer::to_str::InferStr;
 use std::cell::RefCell;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 
 #[deriving(Clone)]
diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs
index bf34e7c1351..28e5559b32b 100644
--- a/src/librustc/middle/typeck/mod.rs
+++ b/src/librustc/middle/typeck/mod.rs
@@ -72,7 +72,7 @@ use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
 
 use std::cell::RefCell;
 use std::rc::Rc;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use collections::List;
 use syntax::codemap::Span;
 use syntax::print::pprust::*;
diff --git a/src/librustc/middle/typeck/rscope.rs b/src/librustc/middle/typeck/rscope.rs
index 078415bc644..3ead54ee9f5 100644
--- a/src/librustc/middle/typeck/rscope.rs
+++ b/src/librustc/middle/typeck/rscope.rs
@@ -12,7 +12,7 @@
 use middle::ty;
 
 use std::cell::Cell;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::opt_vec::OptVec;
diff --git a/src/librustc/middle/typeck/variance.rs b/src/librustc/middle/typeck/variance.rs
index 468d97a8392..90bb1eb59a9 100644
--- a/src/librustc/middle/typeck/variance.rs
+++ b/src/librustc/middle/typeck/variance.rs
@@ -197,7 +197,7 @@ use arena;
 use arena::Arena;
 use middle::ty;
 use std::fmt;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::ast;
 use syntax::ast_util;
 use syntax::opt_vec;
@@ -675,7 +675,7 @@ impl<'a> ConstraintContext<'a> {
                                                  substs, variance);
             }
 
-            ty::ty_trait(def_id, ref substs, _, _, _) => {
+            ty::ty_trait(~ty::TyTrait { def_id, ref substs, .. }) => {
                 let trait_def = ty::lookup_trait_def(self.tcx(), def_id);
                 self.add_constraints_from_substs(def_id, &trait_def.generics,
                                                  substs, variance);
@@ -705,7 +705,7 @@ impl<'a> ConstraintContext<'a> {
                 self.add_constraints_from_sig(sig, variance);
             }
 
-            ty::ty_closure(ty::ClosureTy { sig: ref sig, region, .. }) => {
+            ty::ty_closure(~ty::ClosureTy { sig: ref sig, region, .. }) => {
                 let contra = self.contravariant(variance);
                 self.add_constraints_from_region(region, contra);
                 self.add_constraints_from_sig(sig, variance);
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index fb417390905..03f73f9ae9e 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -16,7 +16,7 @@ use syntax::visit;
 use syntax::visit::Visitor;
 
 use std::local_data;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 use time;
 
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index b3d3e59ea6b..e43eed9f219 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -23,7 +23,7 @@ use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_unboxed_vec, ty_infer};
 use middle::ty;
 use middle::typeck;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::abi::AbiSet;
 use syntax::ast_map;
 use syntax::codemap::{Span, Pos};
@@ -453,7 +453,7 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str {
         ~"(" + strs.connect(",") + ")"
       }
       ty_closure(ref f) => {
-          closure_to_str(cx, f)
+          closure_to_str(cx, *f)
       }
       ty_bare_fn(ref f) => {
           bare_fn_to_str(cx, f.purity, f.abis, None, &f.sig)
@@ -484,7 +484,9 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> ~str {
                       did,
                       false)
       }
-      ty_trait(did, ref substs, s, mutbl, ref bounds) => {
+      ty_trait(~ty::TyTrait {
+          def_id: did, ref substs, store: s, mutability: mutbl, ref bounds
+      }) => {
         let base = ty::item_path_str(cx, did);
         let ty = parameterized(cx, base, &substs.regions,
                                substs.tps.as_slice(), did, true);
@@ -672,6 +674,7 @@ impl Repr for ty::ParamBounds {
                 ty::BoundFreeze => ~"Freeze",
                 ty::BoundSized => ~"Sized",
                 ty::BoundPod => ~"Pod",
+                ty::BoundShare => ~"Share",
             });
         }
         for t in self.trait_bounds.iter() {
@@ -959,6 +962,7 @@ impl UserString for ty::BuiltinBound {
             ty::BoundFreeze => ~"Freeze",
             ty::BoundSized => ~"Sized",
             ty::BoundPod => ~"Pod",
+            ty::BoundShare => ~"Share",
         }
     }
 }
diff --git a/src/librustc/util/sha2.rs b/src/librustc/util/sha2.rs
index 5dbebbb4db1..afc061ba813 100644
--- a/src/librustc/util/sha2.rs
+++ b/src/librustc/util/sha2.rs
@@ -14,8 +14,8 @@
 
 use std::iter::range_step;
 use std::num::Zero;
-use std::vec::bytes::{MutableByteVector, copy_memory};
-use std::vec_ng::Vec;
+use std::slice::bytes::{MutableByteVector, copy_memory};
+use std::vec::Vec;
 use serialize::hex::ToHex;
 
 /// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian
@@ -528,8 +528,8 @@ mod tests {
 
     use super::{Digest, Sha256, FixedBuffer};
     use std::num::Bounded;
-    use std::vec;
-    use std::vec_ng::Vec;
+    use std::slice;
+    use std::vec::Vec;
     use self::rand::isaac::IsaacRng;
     use self::rand::Rng;
     use serialize::hex::FromHex;
@@ -604,7 +604,7 @@ mod tests {
     /// correct.
     fn test_digest_1million_random<D: Digest>(digest: &mut D, blocksize: uint, expected: &str) {
         let total_size = 1000000;
-        let buffer = vec::from_elem(blocksize * 2, 'a' as u8);
+        let buffer = slice::from_elem(blocksize * 2, 'a' as u8);
         let mut rng = IsaacRng::new_unseeded();
         let mut count = 0;
 
diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs
index 2ac3834ea49..6402ed1c9f8 100644
--- a/src/librustdoc/clean.rs
+++ b/src/librustdoc/clean.rs
@@ -30,7 +30,7 @@ use core;
 use doctree;
 use visit_ast;
 use std::local_data;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub trait Clean<T> {
     fn clean(&self) -> T;
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 8780b16918b..a045d042dcd 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -33,7 +33,7 @@ use std::libc;
 use std::local_data;
 use std::mem;
 use std::str;
-use std::vec;
+use std::slice;
 use collections::HashMap;
 
 use html::toc::TocBuilder;
@@ -130,7 +130,7 @@ pub fn render(w: &mut io::Writer, s: &str, print_toc: bool) -> fmt::Result {
     extern fn block(ob: *buf, text: *buf, lang: *buf, opaque: *libc::c_void) {
         unsafe {
             let my_opaque: &my_opaque = cast::transmute(opaque);
-            vec::raw::buf_as_slice((*text).data, (*text).size as uint, |text| {
+            slice::raw::buf_as_slice((*text).data, (*text).size as uint, |text| {
                 let text = str::from_utf8(text).unwrap();
                 let mut lines = text.lines().filter(|l| stripped_filtered_line(*l).is_none());
                 let text = lines.to_owned_vec().connect("\n");
@@ -144,7 +144,7 @@ pub fn render(w: &mut io::Writer, s: &str, print_toc: bool) -> fmt::Result {
                 let rendered = if lang.is_null() {
                     false
                 } else {
-                    vec::raw::buf_as_slice((*lang).data,
+                    slice::raw::buf_as_slice((*lang).data,
                                            (*lang).size as uint, |rlang| {
                         let rlang = str::from_utf8(rlang).unwrap();
                         if rlang.contains("notrust") {
@@ -255,7 +255,7 @@ pub fn render(w: &mut io::Writer, s: &str, print_toc: bool) -> fmt::Result {
         };
 
         if ret.is_ok() {
-            ret = vec::raw::buf_as_slice((*ob).data, (*ob).size as uint, |buf| {
+            ret = slice::raw::buf_as_slice((*ob).data, (*ob).size as uint, |buf| {
                 w.write(buf)
             });
         }
@@ -271,7 +271,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
             let (should_fail, no_run, ignore) = if lang.is_null() {
                 (false, false, false)
             } else {
-                vec::raw::buf_as_slice((*lang).data,
+                slice::raw::buf_as_slice((*lang).data,
                                        (*lang).size as uint, |lang| {
                     let s = str::from_utf8(lang).unwrap();
                     (s.contains("should_fail"),
@@ -280,7 +280,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
                 })
             };
             if ignore { return }
-            vec::raw::buf_as_slice((*text).data, (*text).size as uint, |text| {
+            slice::raw::buf_as_slice((*text).data, (*text).size as uint, |text| {
                 let tests = &mut *(opaque as *mut ::test::Collector);
                 let text = str::from_utf8(text).unwrap();
                 let mut lines = text.lines().map(|l| stripped_filtered_line(l).unwrap_or(l));
@@ -295,7 +295,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
             if text.is_null() {
                 tests.register_header("", level as u32);
             } else {
-                vec::raw::buf_as_slice((*text).data, (*text).size as uint, |text| {
+                slice::raw::buf_as_slice((*text).data, (*text).size as uint, |text| {
                     let text = str::from_utf8(text).unwrap();
                     tests.register_header(text, level as u32);
                 })
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 26723482595..bfc3555f16a 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -38,8 +38,8 @@ use std::local_data;
 use std::io;
 use std::io::{fs, File, BufferedWriter, MemWriter, BufferedReader};
 use std::str;
-use std::vec;
-use std::vec_ng::Vec;
+use std::slice;
+use std::vec::Vec;
 use collections::{HashMap, HashSet};
 
 use sync::Arc;
@@ -1026,7 +1026,7 @@ fn item_module(w: &mut Writer, cx: &Context,
                item: &clean::Item, items: &[clean::Item]) -> fmt::Result {
     try!(document(w, item));
     debug!("{:?}", items);
-    let mut indices = vec::from_fn(items.len(), |i| i);
+    let mut indices = slice::from_fn(items.len(), |i| i);
 
     fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: uint, idx2: uint) -> Ordering {
         if shortty(i1) == shortty(i2) {
diff --git a/src/librustdoc/html/toc.rs b/src/librustdoc/html/toc.rs
index 61031c222e7..db694a26a56 100644
--- a/src/librustdoc/html/toc.rs
+++ b/src/librustdoc/html/toc.rs
@@ -11,7 +11,7 @@
 //! Table-of-contents creation.
 
 use std::fmt;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 /// A (recursive) table of contents
 #[deriving(Eq)]
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index bd15d1b1331..1ed0c57b854 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use std::{str, io};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 use collections::HashSet;
 
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index 3360e389c44..e167f0ad9ee 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -128,7 +128,8 @@ impl<'a> fold::DocFolder for Stripper<'a> {
                 }
             }
 
-            clean::ViewItemItem(..) => {
+            clean::ViewItemItem(..) |
+            clean::ModuleItem(..) => {
                 if i.visibility != Some(ast::Public) {
                     return None
                 }
@@ -140,9 +141,6 @@ impl<'a> fold::DocFolder for Stripper<'a> {
                 }
             }
 
-            // handled below
-            clean::ModuleItem(..) => {}
-
             // trait impls for private items should be stripped
             clean::ImplItem(clean::Impl{ for_: clean::ResolvedPath{ id: ref for_id, .. }, .. }) => {
                 if !self.exported_items.contains(for_id) {
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index c0a39112b69..1398926827d 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -11,7 +11,7 @@
 //! Rust AST Visitor. Extracts useful information and massages it into a form
 //! usable for clean
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use syntax::abi::AbiSet;
 use syntax::ast;
 use syntax::ast_util;
diff --git a/src/librustuv/file.rs b/src/librustuv/file.rs
index e66452041a5..45e7ba4d21f 100644
--- a/src/librustuv/file.rs
+++ b/src/librustuv/file.rs
@@ -448,7 +448,7 @@ mod test {
     use std::libc::{O_CREAT, O_RDWR, O_RDONLY, S_IWUSR, S_IRUSR};
     use std::io;
     use std::str;
-    use std::vec;
+    use std::slice;
     use super::FsRequest;
     use super::super::Loop;
     use super::super::local_loop;
@@ -484,7 +484,7 @@ mod test {
             let fd = result.fd;
 
             // read
-            let mut read_mem = vec::from_elem(1000, 0u8);
+            let mut read_mem = slice::from_elem(1000, 0u8);
             let result = FsRequest::read(l(), fd, read_mem, 0);
             assert!(result.is_ok());
 
diff --git a/src/librustuv/process.rs b/src/librustuv/process.rs
index 8a6b4d3150e..bd07bf18a72 100644
--- a/src/librustuv/process.rs
+++ b/src/librustuv/process.rs
@@ -15,7 +15,7 @@ use std::libc;
 use std::ptr;
 use std::rt::rtio::RtioProcess;
 use std::rt::task::BlockedTask;
-use std::vec;
+use std::slice;
 
 use homing::{HomingIO, HomeHandle};
 use pipe::PipeWatcher;
@@ -48,8 +48,8 @@ impl Process {
         for slot in config.extra_io.iter() {
             io.push(*slot);
         }
-        let mut stdio = vec::with_capacity::<uvll::uv_stdio_container_t>(io.len());
-        let mut ret_io = vec::with_capacity(io.len());
+        let mut stdio = slice::with_capacity::<uvll::uv_stdio_container_t>(io.len());
+        let mut ret_io = slice::with_capacity(io.len());
         unsafe {
             stdio.set_len(io.len());
             for (slot, other) in stdio.iter().zip(io.iter()) {
@@ -167,14 +167,14 @@ unsafe fn set_stdio(dst: *uvll::uv_stdio_container_t,
 fn with_argv<T>(prog: &str, args: &[~str], f: |**libc::c_char| -> T) -> T {
     // First, allocation space to put all the C-strings (we need to have
     // ownership of them somewhere
-    let mut c_strs = vec::with_capacity(args.len() + 1);
+    let mut c_strs = slice::with_capacity(args.len() + 1);
     c_strs.push(prog.to_c_str());
     for arg in args.iter() {
         c_strs.push(arg.to_c_str());
     }
 
     // Next, create the char** array
-    let mut c_args = vec::with_capacity(c_strs.len() + 1);
+    let mut c_args = slice::with_capacity(c_strs.len() + 1);
     for s in c_strs.iter() {
         c_args.push(s.with_ref(|p| p));
     }
@@ -189,11 +189,11 @@ fn with_env<T>(env: Option<&[(~str, ~str)]>, f: |**libc::c_char| -> T) -> T {
         None => { return f(ptr::null()); }
     };
     // As with argv, create some temporary storage and then the actual array
-    let mut envp = vec::with_capacity(env.len());
+    let mut envp = slice::with_capacity(env.len());
     for &(ref key, ref value) in env.iter() {
         envp.push(format!("{}={}", *key, *value).to_c_str());
     }
-    let mut c_envp = vec::with_capacity(envp.len() + 1);
+    let mut c_envp = slice::with_capacity(envp.len() + 1);
     for s in envp.iter() {
         c_envp.push(s.with_ref(|p| p));
     }
diff --git a/src/libsemver/lib.rs b/src/libsemver/lib.rs
index 6cbfeee6aa7..4ff19393790 100644
--- a/src/libsemver/lib.rs
+++ b/src/libsemver/lib.rs
@@ -41,7 +41,7 @@ use std::cmp;
 use std::fmt;
 use std::fmt::Show;
 use std::option::{Option, Some, None};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 /// An identifier in the pre-release or build metadata. If the identifier can
 /// be parsed as a decimal value, it will be represented with `Numeric`.
diff --git a/src/libserialize/base64.rs b/src/libserialize/base64.rs
index a09b03ec58a..62e078e26c1 100644
--- a/src/libserialize/base64.rs
+++ b/src/libserialize/base64.rs
@@ -337,11 +337,11 @@ mod tests {
     #[test]
     fn test_base64_random() {
         use self::rand::{task_rng, random, Rng};
-        use std::vec;
+        use std::slice;
 
         for _ in range(0, 1000) {
             let times = task_rng().gen_range(1u, 100);
-            let v = vec::from_fn(times, |_| random::<u8>());
+            let v = slice::from_fn(times, |_| random::<u8>());
             assert_eq!(v.to_base64(STANDARD).from_base64().unwrap(), v);
         }
     }
diff --git a/src/libserialize/ebml.rs b/src/libserialize/ebml.rs
index bc9eee51753..2b416f263c2 100644
--- a/src/libserialize/ebml.rs
+++ b/src/libserialize/ebml.rs
@@ -1041,8 +1041,8 @@ mod bench {
 
     #[bench]
     pub fn vuint_at_A_aligned(bh: &mut BenchHarness) {
-        use std::vec;
-        let data = vec::from_fn(4*100, |i| {
+        use std::slice;
+        let data = slice::from_fn(4*100, |i| {
             match i % 2 {
               0 => 0x80u8,
               _ => i as u8,
@@ -1060,8 +1060,8 @@ mod bench {
 
     #[bench]
     pub fn vuint_at_A_unaligned(bh: &mut BenchHarness) {
-        use std::vec;
-        let data = vec::from_fn(4*100+1, |i| {
+        use std::slice;
+        let data = slice::from_fn(4*100+1, |i| {
             match i % 2 {
               1 => 0x80u8,
               _ => i as u8
@@ -1079,8 +1079,8 @@ mod bench {
 
     #[bench]
     pub fn vuint_at_D_aligned(bh: &mut BenchHarness) {
-        use std::vec;
-        let data = vec::from_fn(4*100, |i| {
+        use std::slice;
+        let data = slice::from_fn(4*100, |i| {
             match i % 4 {
               0 => 0x10u8,
               3 => i as u8,
@@ -1099,8 +1099,8 @@ mod bench {
 
     #[bench]
     pub fn vuint_at_D_unaligned(bh: &mut BenchHarness) {
-        use std::vec;
-        let data = vec::from_fn(4*100+1, |i| {
+        use std::slice;
+        let data = slice::from_fn(4*100+1, |i| {
             match i % 4 {
               1 => 0x10u8,
               0 => i as u8,
diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs
index 5ec70773c3f..a95c77c7c13 100644
--- a/src/libserialize/hex.rs
+++ b/src/libserialize/hex.rs
@@ -10,7 +10,7 @@
 
 //! Hex binary-to-text encoding
 use std::str;
-use std::vec;
+use std::slice;
 use std::fmt;
 
 /// A trait for converting a value to hexadecimal encoding
@@ -39,7 +39,7 @@ impl<'a> ToHex for &'a [u8] {
      * ```
      */
     fn to_hex(&self) -> ~str {
-        let mut v = vec::with_capacity(self.len() * 2);
+        let mut v = slice::with_capacity(self.len() * 2);
         for &byte in self.iter() {
             v.push(CHARS[byte >> 4]);
             v.push(CHARS[byte & 0xf]);
@@ -106,7 +106,7 @@ impl<'a> FromHex for &'a str {
      */
     fn from_hex(&self) -> Result<~[u8], FromHexError> {
         // This may be an overestimate if there is any whitespace
-        let mut b = vec::with_capacity(self.len() / 2);
+        let mut b = slice::with_capacity(self.len() / 2);
         let mut modulus = 0;
         let mut buf = 0u8;
 
diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs
index fd57f47e881..18692de2cb4 100644
--- a/src/libserialize/serialize.rs
+++ b/src/libserialize/serialize.rs
@@ -16,8 +16,8 @@ Core encoding and decoding interfaces.
 
 use std::path;
 use std::rc::Rc;
-use std::vec;
-use std::vec_ng::Vec;
+use std::slice;
+use std::vec::Vec;
 
 pub trait Encoder {
     // Primitive types:
@@ -428,7 +428,7 @@ impl<S:Encoder,T:Encodable<S>> Encodable<S> for ~[T] {
 impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~[T] {
     fn decode(d: &mut D) -> ~[T] {
         d.read_seq(|d, len| {
-            vec::from_fn(len, |i| {
+            slice::from_fn(len, |i| {
                 d.read_seq_elt(i, |d| Decodable::decode(d))
             })
         })
@@ -680,7 +680,7 @@ pub trait DecoderHelpers {
 impl<D:Decoder> DecoderHelpers for D {
     fn read_to_vec<T>(&mut self, f: |&mut D| -> T) -> ~[T] {
         self.read_seq(|this, len| {
-            vec::from_fn(len, |i| {
+            slice::from_fn(len, |i| {
                 this.read_seq_elt(i, |this| f(this))
             })
         })
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index 3ca08797dd1..63632770230 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -19,8 +19,8 @@ use container::Container;
 use cast;
 use fmt;
 use iter::Iterator;
-use vec::{ImmutableVector, MutableVector, Vector};
-use vec_ng::Vec;
+use slice::{ImmutableVector, MutableVector, Vector};
+use vec::Vec;
 use option::{Option, Some, None};
 
 /// Datatype to hold one ascii character. It wraps a `u8`, with the highest bit always zero.
@@ -482,7 +482,7 @@ mod tests {
     use super::*;
     use str::from_char;
     use char::from_u32;
-    use vec_ng::Vec;
+    use vec::Vec;
 
     macro_rules! v2ascii (
         ( [$($e:expr),*]) => (&[$(Ascii{chr:$e}),*]);
diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs
index af5d9838186..96c7c218127 100644
--- a/src/libstd/c_str.rs
+++ b/src/libstd/c_str.rs
@@ -76,8 +76,8 @@ use ptr::RawPtr;
 use ptr;
 use str::StrSlice;
 use str;
-use vec::{ImmutableVector, MutableVector};
-use vec;
+use slice::{ImmutableVector, MutableVector};
+use slice;
 use rt::global_heap::malloc_raw;
 use raw::Slice;
 
@@ -343,7 +343,7 @@ impl<'a> ToCStr for &'a [u8] {
 unsafe fn with_c_str<T>(v: &[u8], checked: bool, f: |*libc::c_char| -> T) -> T {
     if v.len() < BUF_LEN {
         let mut buf: [u8, .. BUF_LEN] = mem::uninit();
-        vec::bytes::copy_memory(buf, v);
+        slice::bytes::copy_memory(buf, v);
         buf[v.len()] = 0;
 
         let buf = buf.as_mut_ptr();
diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs
index 398091b60ca..5733504c0d1 100644
--- a/src/libstd/cell.rs
+++ b/src/libstd/cell.rs
@@ -17,35 +17,38 @@ use fmt;
 use kinds::{marker, Pod};
 use ops::{Deref, DerefMut, Drop};
 use option::{None, Option, Some};
+use ty::Unsafe;
 
 /// A mutable memory location that admits only `Pod` data.
 pub struct Cell<T> {
-    priv value: T,
+    priv value: Unsafe<T>,
     priv marker1: marker::InvariantType<T>,
     priv marker2: marker::NoFreeze,
+    priv marker3: marker::NoShare,
 }
 
 impl<T:Pod> Cell<T> {
     /// Creates a new `Cell` containing the given value.
     pub fn new(value: T) -> Cell<T> {
         Cell {
-            value: value,
+            value: Unsafe{value: value, marker1: marker::InvariantType::<T>},
             marker1: marker::InvariantType::<T>,
             marker2: marker::NoFreeze,
+            marker3: marker::NoShare,
         }
     }
 
     /// Returns a copy of the contained value.
     #[inline]
     pub fn get(&self) -> T {
-        self.value
+        unsafe{ *self.value.get() }
     }
 
     /// Sets the contained value.
     #[inline]
     pub fn set(&self, value: T) {
         unsafe {
-            *cast::transmute_mut(&self.value) = value
+            *self.value.get() = value;
         }
     }
 }
@@ -64,17 +67,18 @@ impl<T:Eq + Pod> Eq for Cell<T> {
 
 impl<T: fmt::Show> fmt::Show for Cell<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f.buf, r"Cell \{ value: {} \}", self.value)
+        write!(f.buf, r"Cell \{ value: {} \}", unsafe{*&self.value.get()})
     }
 }
 
 /// A mutable memory location with dynamically checked borrow rules
 pub struct RefCell<T> {
-    priv value: T,
+    priv value: Unsafe<T>,
     priv borrow: BorrowFlag,
     priv marker1: marker::InvariantType<T>,
     priv marker2: marker::NoFreeze,
     priv marker3: marker::NoPod,
+    priv marker4: marker::NoShare,
 }
 
 // Values [1, MAX-1] represent the number of `Ref` active
@@ -90,7 +94,8 @@ impl<T> RefCell<T> {
             marker1: marker::InvariantType::<T>,
             marker2: marker::NoFreeze,
             marker3: marker::NoPod,
-            value: value,
+            marker4: marker::NoShare,
+            value: Unsafe{value: value, marker1: marker::InvariantType::<T>},
             borrow: UNUSED,
         }
     }
@@ -98,7 +103,7 @@ impl<T> RefCell<T> {
     /// Consumes the `RefCell`, returning the wrapped value.
     pub fn unwrap(self) -> T {
         assert!(self.borrow == UNUSED);
-        self.value
+        unsafe{self.value.unwrap()}
     }
 
     unsafe fn as_mut<'a>(&'a self) -> &'a mut RefCell<T> {
@@ -198,7 +203,7 @@ impl<T> RefCell<T> {
     #[inline]
     pub fn set(&self, value: T) {
         let mut reference = self.borrow_mut();
-        *reference.get() = value
+        *reference.get() = value;
     }
 }
 
@@ -247,14 +252,14 @@ impl<'b, T> Ref<'b, T> {
     /// Retrieve an immutable reference to the stored value.
     #[inline]
     pub fn get<'a>(&'a self) -> &'a T {
-        &self.parent.value
+        unsafe{ &*self.parent.value.get() }
     }
 }
 
 impl<'b, T> Deref<T> for Ref<'b, T> {
     #[inline]
     fn deref<'a>(&'a self) -> &'a T {
-        &self.parent.value
+        unsafe{ &*self.parent.value.get() }
     }
 }
 
@@ -275,21 +280,21 @@ impl<'b, T> RefMut<'b, T> {
     /// Retrieve a mutable reference to the stored value.
     #[inline]
     pub fn get<'a>(&'a mut self) -> &'a mut T {
-        &mut self.parent.value
+        unsafe{ &mut *self.parent.value.get() }
     }
 }
 
 impl<'b, T> Deref<T> for RefMut<'b, T> {
     #[inline]
     fn deref<'a>(&'a self) -> &'a T {
-        &self.parent.value
+        unsafe{ &*self.parent.value.get() }
     }
 }
 
 impl<'b, T> DerefMut<T> for RefMut<'b, T> {
     #[inline]
     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
-        &mut self.parent.value
+        unsafe{ &mut *self.parent.value.get() }
     }
 }
 
diff --git a/src/libstd/comm/shared.rs b/src/libstd/comm/shared.rs
index 328dd70223b..8c8ae85e4ea 100644
--- a/src/libstd/comm/shared.rs
+++ b/src/libstd/comm/shared.rs
@@ -30,7 +30,7 @@ use rt::task::{Task, BlockedTask};
 use rt::thread::Thread;
 use sync::atomics;
 use unstable::mutex::NativeMutex;
-use vec::OwnedVector;
+use slice::OwnedVector;
 
 use mpsc = sync::mpsc_queue;
 
diff --git a/src/libstd/comm/stream.rs b/src/libstd/comm/stream.rs
index d386e97d5bf..5820b13a35f 100644
--- a/src/libstd/comm/stream.rs
+++ b/src/libstd/comm/stream.rs
@@ -30,7 +30,7 @@ use rt::task::{Task, BlockedTask};
 use rt::thread::Thread;
 use spsc = sync::spsc_queue;
 use sync::atomics;
-use vec::OwnedVector;
+use slice::OwnedVector;
 
 static DISCONNECTED: int = int::MIN;
 #[cfg(test)]
diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs
index 67e2fc00b8b..d3ceba025ea 100644
--- a/src/libstd/fmt/mod.rs
+++ b/src/libstd/fmt/mod.rs
@@ -490,8 +490,8 @@ use repr;
 use result::{Ok, Err};
 use str::StrSlice;
 use str;
-use vec::ImmutableVector;
-use vec;
+use slice::ImmutableVector;
+use slice;
 
 pub use self::num::radix;
 pub use self::num::Radix;
@@ -520,7 +520,7 @@ pub struct Formatter<'a> {
 
     /// Output buffer.
     buf: &'a mut io::Writer,
-    priv curarg: vec::Items<'a, Argument<'a>>,
+    priv curarg: slice::Items<'a, Argument<'a>>,
     priv args: &'a [Argument<'a>],
 }
 
diff --git a/src/libstd/fmt/num.rs b/src/libstd/fmt/num.rs
index 681d0678ed4..4b35a7596c9 100644
--- a/src/libstd/fmt/num.rs
+++ b/src/libstd/fmt/num.rs
@@ -17,7 +17,7 @@ use fmt;
 use iter::{Iterator, DoubleEndedIterator};
 use num::{Int, cast, zero};
 use option::{Some, None};
-use vec::{ImmutableVector, MutableVector};
+use slice::{ImmutableVector, MutableVector};
 
 /// A type that represents a specific radix
 trait GenericRadix {
diff --git a/src/libstd/hash/mod.rs b/src/libstd/hash/mod.rs
index dd40f600873..3791aa38b82 100644
--- a/src/libstd/hash/mod.rs
+++ b/src/libstd/hash/mod.rs
@@ -70,8 +70,8 @@ use ops::Deref;
 use option::{Option, Some, None};
 use rc::Rc;
 use str::{Str, StrSlice};
-use vec::{Vector, ImmutableVector};
-use vec_ng::Vec;
+use slice::{Vector, ImmutableVector};
+use vec::Vec;
 
 /// Reexport the `sip::hash` function as our default hasher.
 pub use hash = self::sip::hash;
@@ -293,7 +293,7 @@ mod tests {
     use iter::{Iterator};
     use option::{Some, None};
     use result::Ok;
-    use vec::ImmutableVector;
+    use slice::ImmutableVector;
 
     use super::{Hash, Hasher};
 
diff --git a/src/libstd/hash/sip.rs b/src/libstd/hash/sip.rs
index d1d4d4c90f9..d448f4eeb37 100644
--- a/src/libstd/hash/sip.rs
+++ b/src/libstd/hash/sip.rs
@@ -30,7 +30,7 @@ use default::Default;
 use io::{IoResult, Writer};
 use iter::Iterator;
 use result::Ok;
-use vec::ImmutableVector;
+use slice::ImmutableVector;
 
 use super::{Hash, Hasher};
 
@@ -292,7 +292,7 @@ mod tests {
     use num::ToStrRadix;
     use option::{Some, None};
     use str::{Str, OwnedStr};
-    use vec::{Vector, ImmutableVector, OwnedVector};
+    use slice::{Vector, ImmutableVector, OwnedVector};
     use self::test::BenchHarness;
 
     use super::super::Hash;
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 3ae44e4a1b5..ab9a8377136 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -17,8 +17,8 @@ use iter::ExactSize;
 use ops::Drop;
 use option::{Some, None, Option};
 use result::{Ok, Err};
-use vec::{OwnedVector, ImmutableVector, MutableVector};
-use vec;
+use slice::{OwnedVector, ImmutableVector, MutableVector};
+use slice;
 
 /// Wraps a Reader and buffers input from it
 ///
@@ -58,7 +58,7 @@ impl<R: Reader> BufferedReader<R> {
         // everything up-front. This allows creation of BufferedReader instances
         // to be very cheap (large mallocs are not nearly as expensive as large
         // callocs).
-        let mut buf = vec::with_capacity(cap);
+        let mut buf = slice::with_capacity(cap);
         unsafe { buf.set_len(cap); }
         BufferedReader {
             inner: inner,
@@ -106,7 +106,7 @@ impl<R: Reader> Reader for BufferedReader<R> {
         let nread = {
             let available = try!(self.fill());
             let nread = cmp::min(available.len(), buf.len());
-            vec::bytes::copy_memory(buf, available.slice_to(nread));
+            slice::bytes::copy_memory(buf, available.slice_to(nread));
             nread
         };
         self.pos += nread;
@@ -140,7 +140,7 @@ impl<W: Writer> BufferedWriter<W> {
     /// Creates a new `BufferedWriter` with the specified buffer capacity
     pub fn with_capacity(cap: uint, inner: W) -> BufferedWriter<W> {
         // See comments in BufferedReader for why this uses unsafe code.
-        let mut buf = vec::with_capacity(cap);
+        let mut buf = slice::with_capacity(cap);
         unsafe { buf.set_len(cap); }
         BufferedWriter {
             inner: Some(inner),
@@ -190,7 +190,7 @@ impl<W: Writer> Writer for BufferedWriter<W> {
             self.inner.get_mut_ref().write(buf)
         } else {
             let dst = self.buf.mut_slice_from(self.pos);
-            vec::bytes::copy_memory(dst, buf);
+            slice::bytes::copy_memory(dst, buf);
             self.pos += buf.len();
             Ok(())
         }
diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs
index f09555e93a0..075c65e04be 100644
--- a/src/libstd/io/comm_adapters.rs
+++ b/src/libstd/io/comm_adapters.rs
@@ -16,7 +16,7 @@ use io;
 use option::{None, Option, Some};
 use result::{Ok, Err};
 use super::{Reader, Writer, IoResult};
-use vec::{bytes, CloneableVector, MutableVector, ImmutableVector};
+use slice::{bytes, CloneableVector, MutableVector, ImmutableVector};
 
 /// Allows reading from a rx.
 ///
diff --git a/src/libstd/io/extensions.rs b/src/libstd/io/extensions.rs
index f7cab755714..070cbd569e6 100644
--- a/src/libstd/io/extensions.rs
+++ b/src/libstd/io/extensions.rs
@@ -21,7 +21,7 @@ use option::{Option, Some, None};
 use result::{Ok, Err};
 use io;
 use io::{IoError, IoResult, Reader};
-use vec::{OwnedVector, ImmutableVector};
+use slice::{OwnedVector, ImmutableVector};
 use ptr::RawPtr;
 
 /// An iterator that reads a single byte on each iteration,
@@ -114,7 +114,7 @@ pub fn u64_from_be_bytes(data: &[u8],
                       -> u64 {
     use ptr::{copy_nonoverlapping_memory};
     use mem::from_be64;
-    use vec::MutableVector;
+    use slice::MutableVector;
 
     assert!(size <= 8u);
 
@@ -470,10 +470,10 @@ mod bench {
     macro_rules! u64_from_be_bytes_bench_impl(
         ($size:expr, $stride:expr, $start_index:expr) =>
         ({
-            use vec;
+            use slice;
             use super::u64_from_be_bytes;
 
-            let data = vec::from_fn($stride*100+$start_index, |i| i as u8);
+            let data = slice::from_fn($stride*100+$start_index, |i| i as u8);
             let mut sum = 0u64;
             bh.iter(|| {
                 let mut i = $start_index;
diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs
index 3435c9a07aa..870f33733f4 100644
--- a/src/libstd/io/fs.rs
+++ b/src/libstd/io/fs.rs
@@ -62,8 +62,8 @@ use option::{Some, None, Option};
 use result::{Ok, Err};
 use path;
 use path::{Path, GenericPath};
-use vec::{OwnedVector, ImmutableVector};
-use vec_ng::Vec;
+use slice::{OwnedVector, ImmutableVector};
+use vec::Vec;
 
 /// Unconstrained file access type that exposes read and write operations
 ///
diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs
index 3e79225f9ab..d0c4ef308b3 100644
--- a/src/libstd/io/mem.rs
+++ b/src/libstd/io/mem.rs
@@ -16,8 +16,8 @@ use option::None;
 use result::{Err, Ok};
 use io;
 use io::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, IoResult};
-use vec;
-use vec::{Vector, ImmutableVector, MutableVector, OwnedCloneableVector};
+use slice;
+use slice::{Vector, ImmutableVector, MutableVector, OwnedCloneableVector};
 
 fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult<u64> {
     // compute offset as signed and clamp to prevent overflow
@@ -64,7 +64,7 @@ impl MemWriter {
     /// Create a new `MemWriter`, allocating at least `n` bytes for
     /// the internal buffer.
     pub fn with_capacity(n: uint) -> MemWriter {
-        MemWriter { buf: vec::with_capacity(n), pos: 0 }
+        MemWriter { buf: slice::with_capacity(n), pos: 0 }
     }
 
     /// Acquires an immutable reference to the underlying buffer of this
@@ -98,7 +98,7 @@ impl Writer for MemWriter {
 
         // Do the necessary writes
         if left.len() > 0 {
-            vec::bytes::copy_memory(self.buf.mut_slice_from(self.pos), left);
+            slice::bytes::copy_memory(self.buf.mut_slice_from(self.pos), left);
         }
         if right.len() > 0 {
             self.buf.push_all(right);
@@ -171,7 +171,7 @@ impl Reader for MemReader {
             let input = self.buf.slice(self.pos, self.pos + write_len);
             let output = buf.mut_slice(0, write_len);
             assert_eq!(input.len(), output.len());
-            vec::bytes::copy_memory(output, input);
+            slice::bytes::copy_memory(output, input);
         }
         self.pos += write_len;
         assert!(self.pos <= self.buf.len());
@@ -246,7 +246,7 @@ impl<'a> Writer for BufWriter<'a> {
             })
         }
 
-        vec::bytes::copy_memory(self.buf.mut_slice_from(self.pos), buf);
+        slice::bytes::copy_memory(self.buf.mut_slice_from(self.pos), buf);
         self.pos += buf.len();
         Ok(())
     }
@@ -303,7 +303,7 @@ impl<'a> Reader for BufReader<'a> {
             let input = self.buf.slice(self.pos, self.pos + write_len);
             let output = buf.mut_slice(0, write_len);
             assert_eq!(input.len(), output.len());
-            vec::bytes::copy_memory(output, input);
+            slice::bytes::copy_memory(output, input);
         }
         self.pos += write_len;
         assert!(self.pos <= self.buf.len());
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index c18d4e273c4..cbced77d014 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -223,8 +223,8 @@ use str::{StrSlice, OwnedStr};
 use str;
 use uint;
 use unstable::finally::try_finally;
-use vec::{OwnedVector, MutableVector, ImmutableVector, OwnedCloneableVector};
-use vec;
+use slice::{OwnedVector, MutableVector, ImmutableVector, OwnedCloneableVector};
+use slice;
 
 // Reexports
 pub use self::stdio::stdin;
@@ -406,7 +406,7 @@ pub trait Reader {
     /// (not returned as part of the error). If this is unacceptable, then it is
     /// recommended to use the `push_bytes` or `read` methods.
     fn read_bytes(&mut self, len: uint) -> IoResult<~[u8]> {
-        let mut buf = vec::with_capacity(len);
+        let mut buf = slice::with_capacity(len);
         match self.push_bytes(&mut buf, len) {
             Ok(()) => Ok(buf),
             Err(e) => Err(e),
@@ -422,7 +422,7 @@ pub trait Reader {
     ///
     /// When EOF is encountered, all bytes read up to that point are returned.
     fn read_to_end(&mut self) -> IoResult<~[u8]> {
-        let mut buf = vec::with_capacity(DEFAULT_BUF_SIZE);
+        let mut buf = slice::with_capacity(DEFAULT_BUF_SIZE);
         loop {
             match self.push_bytes(&mut buf, DEFAULT_BUF_SIZE) {
                 Ok(()) => {}
diff --git a/src/libstd/io/net/addrinfo.rs b/src/libstd/io/net/addrinfo.rs
index 80ca353523f..6e0b766a587 100644
--- a/src/libstd/io/net/addrinfo.rs
+++ b/src/libstd/io/net/addrinfo.rs
@@ -23,7 +23,7 @@ use io::IoResult;
 use io::net::ip::{SocketAddr, IpAddr};
 use option::{Option, Some, None};
 use rt::rtio::{IoFactory, LocalIo};
-use vec::ImmutableVector;
+use slice::ImmutableVector;
 
 /// Hints to the types of sockets that are desired when looking up hosts
 pub enum SocketType {
diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs
index 7c9321d87d9..dc24ead6258 100644
--- a/src/libstd/io/net/ip.rs
+++ b/src/libstd/io/net/ip.rs
@@ -16,7 +16,7 @@ use from_str::FromStr;
 use iter::Iterator;
 use option::{Option, None, Some};
 use str::StrSlice;
-use vec::{MutableCloneableVector, ImmutableVector, MutableVector};
+use slice::{MutableCloneableVector, ImmutableVector, MutableVector};
 
 pub type Port = u16;
 
diff --git a/src/libstd/io/signal.rs b/src/libstd/io/signal.rs
index c66fcd13917..d6700fda23d 100644
--- a/src/libstd/io/signal.rs
+++ b/src/libstd/io/signal.rs
@@ -27,7 +27,7 @@ use mem::drop;
 use option::{Some, None};
 use result::{Ok, Err};
 use rt::rtio::{IoFactory, LocalIo, RtioSignal};
-use vec::{ImmutableVector, OwnedVector};
+use slice::{ImmutableVector, OwnedVector};
 
 /// Signals that can be sent and received
 #[repr(int)]
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 7c65e76ab47..2f6cdcb5825 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -40,7 +40,7 @@ use rt::local::Local;
 use rt::rtio::{DontClose, IoFactory, LocalIo, RtioFileStream, RtioTTY};
 use rt::task::Task;
 use str::StrSlice;
-use vec::ImmutableVector;
+use slice::ImmutableVector;
 
 // And so begins the tale of acquiring a uv handle to a stdio stream on all
 // platforms in all situations. Our story begins by splitting the world into two
@@ -296,7 +296,13 @@ pub struct StdReader {
 impl Reader for StdReader {
     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         let ret = match self.inner {
-            TTY(ref mut tty) => tty.read(buf),
+            TTY(ref mut tty) => {
+                // Flush the task-local stdout so that weird issues like a
+                // print!'d prompt not being shown until after the user hits
+                // enter.
+                flush();
+                tty.read(buf)
+            },
             File(ref mut file) => file.read(buf).map(|i| i as uint),
         };
         match ret {
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index d6d1de00d86..2df0dec2d13 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -13,7 +13,7 @@
 use prelude::*;
 use cmp;
 use io;
-use vec::bytes::MutableByteVector;
+use slice::bytes::MutableByteVector;
 
 /// Wraps a `Reader`, limiting the number of bytes that can be read from it.
 pub struct LimitReader<R> {
diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs
index 9e988eb4094..320383d4f81 100644
--- a/src/libstd/iter.rs
+++ b/src/libstd/iter.rs
@@ -2293,7 +2293,7 @@ pub mod order {
 
     #[test]
     fn test_lt() {
-        use vec::ImmutableVector;
+        use slice::ImmutableVector;
 
         let empty: [int, ..0] = [];
         let xs = [1,2,3];
diff --git a/src/libstd/kinds.rs b/src/libstd/kinds.rs
index da17119fd98..b44616421d1 100644
--- a/src/libstd/kinds.rs
+++ b/src/libstd/kinds.rs
@@ -46,6 +46,22 @@ pub trait Pod {
     // Empty.
 }
 
+/// Types that can be safely shared between threads, hence thread-safe.
+#[cfg(stage0)]
+pub trait Share {
+    // Empty
+}
+
+#[cfg(stage0)]
+impl<T> Share for T {}
+
+/// Types that can be safely shared between threads, hence thread-safe.
+#[cfg(not(stage0))]
+#[lang="share"]
+pub trait Share {
+    // Empty
+}
+
 /// Marker types are special types that are used with unsafe code to
 /// inform the compiler of special constraints. Marker types should
 /// only be needed when you are creating an abstraction that is
@@ -232,6 +248,13 @@ pub mod marker {
     #[deriving(Eq,Clone)]
     pub struct NoPod;
 
+    /// A type which is considered "not sharable", meaning that
+    /// its contents are not threadsafe, hence they cannot be
+    /// shared between tasks.
+    #[lang="no_share_bound"]
+    #[deriving(Eq,Clone)]
+    pub struct NoShare;
+
     /// A type which is considered managed by the GC. This is typically
     /// embedded in other types.
     #[lang="managed_bound"]
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 17c0e2235c0..0431a80d0c4 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -83,6 +83,10 @@
 #[cfg(test)] pub use kinds = realstd::kinds;
 #[cfg(test)] pub use ops = realstd::ops;
 #[cfg(test)] pub use cmp = realstd::cmp;
+#[cfg(test)] pub use ty = realstd::ty;
+
+#[cfg(stage0)]
+pub use vec_ng = vec;
 
 pub mod macros;
 
@@ -119,8 +123,8 @@ pub mod bool;
 pub mod char;
 pub mod tuple;
 
+pub mod slice;
 pub mod vec;
-pub mod vec_ng;
 pub mod str;
 
 pub mod ascii;
@@ -138,6 +142,7 @@ pub mod gc;
 #[cfg(not(test))] pub mod kinds;
 #[cfg(not(test))] pub mod ops;
 #[cfg(not(test))] pub mod cmp;
+#[cfg(not(test))] pub mod ty;
 
 
 /* Common traits */
@@ -226,5 +231,6 @@ mod std {
     pub use rt;
     pub use str;
     pub use to_str;
+    pub use ty;
     pub use unstable;
 }
diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs
index 9fc635647f3..f1f1977462f 100644
--- a/src/libstd/local_data.rs
+++ b/src/libstd/local_data.rs
@@ -42,7 +42,7 @@ local_data::get(key_vector, |opt| assert_eq!(*opt.unwrap(), ~[4]));
 
 use cast;
 use option::{None, Option, Some};
-use vec::{ImmutableVector, MutableVector, OwnedVector};
+use slice::{ImmutableVector, MutableVector, OwnedVector};
 use iter::{Iterator};
 use rt::task::{Task, LocalStorage};
 use mem::replace;
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 6d96ea94d31..d183fae3ac6 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -265,12 +265,12 @@ macro_rules! try(
     ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
 )
 
-/// Create a `std::vec_ng::Vec` containing the arguments.
+/// 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_ng::Vec::new();
+        let mut _temp = ::std::vec::Vec::new();
         $(_temp.push($e);)*
         _temp
     })
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index f53c95de414..98379b5e5fb 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -1727,12 +1727,12 @@ mod bench {
     extern crate test;
     use self::test::BenchHarness;
     use num;
-    use vec;
+    use slice;
     use prelude::*;
 
     #[bench]
     fn bench_pow_function(b: &mut BenchHarness) {
-        let v = vec::from_fn(1024, |n| n);
+        let v = slice::from_fn(1024, |n| n);
         b.iter(|| {v.iter().fold(0, |old, new| num::pow(old, *new));});
     }
 }
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index 00497b6f0ea..9d3d012bae7 100644
--- a/src/libstd/num/strconv.rs
+++ b/src/libstd/num/strconv.rs
@@ -18,8 +18,8 @@ use option::{None, Option, Some};
 use char;
 use str::{StrSlice};
 use str;
-use vec::{CloneableVector, ImmutableVector, MutableVector};
-use vec::OwnedVector;
+use slice::{CloneableVector, ImmutableVector, MutableVector};
+use slice::OwnedVector;
 use num;
 use num::{NumCast, Zero, One, cast, Int};
 use num::{Round, Float, FPNaN, FPInfinite, ToPrimitive};
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index 9327136c771..5f733302d6f 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -8,21 +8,86 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Optionally nullable values (`Option` type)
+//! Optional values
 //!
-//! Type `Option` represents an optional value.
+//! Type `Option` represents an optional value: every `Option`
+//! is either `Some` and contains a value, or `None`, and
+//! does not. `Option` types are very common in Rust code, as
+//! they have a number of uses:
 //!
-//! Every `Option<T>` value can either be `Some(T)` or `None`. Where in other
-//! languages you might use a nullable type, in Rust you would use an option
-//! type.
+//! * Initial values
+//! * Return values for functions that are not defined
+//!   over their entire input range (partial functions)
+//! * Return value for otherwise reporting simple errors, where `None` is
+//!   returned on error
+//! * Optional struct fields
+//! * Struct fields that can be loaned or "taken"
+//! * Optional function arguments
+//! * Nullable pointers
+//! * Swapping things out of difficult situations
 //!
-//! Options are most commonly used with pattern matching to query the presence
+//! Options are commonly paired with pattern matching to query the presence
 //! of a value and take action, always accounting for the `None` case.
 //!
-//! # Example
+//! ```
+//! # // FIXME This is not the greatest first example
+//! // cow_says contains the word "moo"
+//! let cow_says = Some("moo");
+//! // dog_says does not contain a value
+//! let dog_says: Option<&str> = None;
+//!
+//! // Pattern match to retrieve the value
+//! match (cow_says, dog_says) {
+//!     (Some(cow_words), Some(dog_words)) => {
+//!         println!("Cow says {} and dog says {}!", cow_words, dog_words);
+//!     }
+//!     (Some(cow_words), None) => println!("Cow says {}", cow_words),
+//!     (None, Some(dog_words)) => println!("Dog says {}", dog_words),
+//!     (None, None) => println!("Cow and dog are suspiciously silent")
+//! }
+//! ```
+//!
+//
+// FIXME: Show how `Option` is used in practice, with lots of methods
+//
+//! # Options and pointers ("nullable" pointers)
+//!
+//! Rust's pointer types must always point to a valid location; there are
+//! no "null" pointers. Instead, Rust has *optional* pointers, like
+//! the optional owned box, `Option<~T>`.
+//!
+//! The following example uses `Option` to create an optional box of
+//! `int`. Notice that in order to use the inner `int` value first the
+//! `check_optional` function needs to use pattern matching to
+//! determine whether the box has a value (i.e. it is `Some(...)`) or
+//! not (`None`).
+//!
+//! ```
+//! let optional: Option<~int> = None;
+//! check_optional(&optional);
 //!
+//! let optional: Option<~int> = Some(~9000);
+//! check_optional(&optional);
+//!
+//! fn check_optional(optional: &Option<~int>) {
+//!     match *optional {
+//!         Some(ref p) => println!("have value {}", p),
+//!         None => println!("have no value")
+//!     }
+//! }
 //! ```
-//! let msg = Some(~"howdy");
+//!
+//! This usage of `Option` to create safe nullable pointers is so
+//! common that Rust does special optimizations to make the
+//! representation of `Option<~T>` a single pointer. Optional pointers
+//! in Rust are stored as efficiently as any other pointer type.
+//!
+//! # Examples
+//!
+//! Basic pattern matching on `Option`:
+//!
+//! ```
+//! let msg = Some("howdy");
 //!
 //! // Take a reference to the contained string
 //! match msg {
@@ -33,9 +98,45 @@
 //! // Remove the contained string, destroying the Option
 //! let unwrapped_msg = match msg {
 //!     Some(m) => m,
-//!     None => ~"default message"
+//!     None => "default message"
 //! };
 //! ```
+//!
+//! Initialize a result to `None` before a loop:
+//!
+//! ```
+//! enum Kingdom { Plant(uint, &'static str), Animal(uint, &'static str) }
+//!
+//! // A list of data to search through.
+//! let all_the_big_things = [
+//!     Plant(250, "redwood"),
+//!     Plant(230, "noble fir"),
+//!     Plant(229, "sugar pine"),
+//!     Animal(25, "blue whale"),
+//!     Animal(19, "fin whale"),
+//!     Animal(15, "north pacific right whale"),
+//! ];
+//!
+//! // We're going to search for the name of the biggest animal,
+//! // but to start with we've just got `None`.
+//! let mut name_of_biggest_animal = None;
+//! let mut size_of_biggest_animal = 0;
+//! for big_thing in all_the_big_things.iter() {
+//!     match *big_thing {
+//!         Animal(size, name) if size > size_of_biggest_animal => {
+//!             // Now we've found the name of some big animal
+//!             size_of_biggest_animal = size;
+//!             name_of_biggest_animal = Some(name);
+//!         }
+//!         Animal(..) | Plant(..) => ()
+//!     }
+//! }
+//!
+//! match name_of_biggest_animal {
+//!     Some(name) => println!("the biggest animal is {}", name),
+//!     None => println!("there are no animals :(")
+//! }
+//! ```
 
 use any::Any;
 use clone::Clone;
@@ -44,9 +145,9 @@ use default::Default;
 use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSize};
 use kinds::Send;
 use mem;
-use vec;
+use slice;
 
-/// The option type
+/// The `Option`
 #[deriving(Clone, Eq, Ord, TotalEq, TotalOrd, Show)]
 pub enum Option<T> {
     /// No value
@@ -64,7 +165,7 @@ impl<T> Option<T> {
     // Querying the contained values
     /////////////////////////////////////////////////////////////////////////
 
-    /// Returns true if the option contains a `Some` value
+    /// Returns `true` if the option is a `Some` value
     #[inline]
     pub fn is_some(&self) -> bool {
         match *self {
@@ -73,7 +174,7 @@ impl<T> Option<T> {
         }
     }
 
-    /// Returns true if the option equals `None`
+    /// Returns `true` if the option is a `None` value
     #[inline]
     pub fn is_none(&self) -> bool {
         !self.is_some()
@@ -84,6 +185,21 @@ impl<T> Option<T> {
     /////////////////////////////////////////////////////////////////////////
 
     /// Convert from `Option<T>` to `Option<&T>`
+    ///
+    /// # Example
+    ///
+    /// Convert an `Option<~str>` into an `Option<int>`, preserving the original.
+    /// The `map` method takes the `self` argument by value, consuming the original,
+    /// so this technique uses `as_ref` to first take an `Option` to a reference
+    /// to the value inside the original.
+    ///
+    /// ```
+    /// let num_as_str: Option<~str> = Some(~"10");
+    /// // First, cast `Option<~str>` to `Option<&~str>` with `as_ref`,
+    /// // then consume *that* with `map`, leaving `num_as_str` on the stack.
+    /// let num_as_int: Option<uint> = num_as_str.as_ref().map(|n| n.len());
+    /// println!("still can print num_as_str: {}", num_as_str);
+    /// ```
     #[inline]
     pub fn as_ref<'r>(&'r self) -> Option<&'r T> {
         match *self { Some(ref x) => Some(x), None => None }
@@ -99,7 +215,7 @@ impl<T> Option<T> {
     #[inline]
     pub fn as_slice<'r>(&'r self) -> &'r [T] {
         match *self {
-            Some(ref x) => vec::ref_slice(x),
+            Some(ref x) => slice::ref_slice(x),
             None => &[]
         }
     }
@@ -108,7 +224,7 @@ impl<T> Option<T> {
     #[inline]
     pub fn as_mut_slice<'r>(&'r mut self) -> &'r mut [T] {
         match *self {
-            Some(ref mut x) => vec::mut_ref_slice(x),
+            Some(ref mut x) => slice::mut_ref_slice(x),
             None => &mut []
         }
     }
@@ -118,6 +234,9 @@ impl<T> Option<T> {
     /////////////////////////////////////////////////////////////////////////
 
     /// Unwraps an option, yielding the content of a `Some`
+    ///
+    /// # Failure
+    ///
     /// Fails if the value is a `None` with a custom failure message provided by `msg`.
     #[inline]
     pub fn expect<M: Any + Send>(self, msg: M) -> T {
@@ -127,14 +246,11 @@ impl<T> Option<T> {
         }
     }
 
-    /// Moves a value out of an option type and returns it.
-    ///
-    /// Useful primarily for getting strings, vectors and unique pointers out
-    /// of option types without copying them.
+    /// Moves a value out of an option type and returns it, consuming the `Option`.
     ///
     /// # Failure
     ///
-    /// Fails if the value equals `None`.
+    /// Fails if the self value equals `None`.
     ///
     /// # Safety note
     ///
@@ -171,7 +287,17 @@ impl<T> Option<T> {
     // Transforming contained values
     /////////////////////////////////////////////////////////////////////////
 
-    /// Maps an `Option<T>` to `Option<U>` by applying a function to a contained value.
+    /// Maps an `Option<T>` to `Option<U>` by applying a function to a contained value
+    ///
+    /// # Example
+    ///
+    /// Convert an `Option<~str>` into an `Option<uint>`, consuming the original:
+    ///
+    /// ```
+    /// let num_as_str: Option<~str> = Some(~"10");
+    /// // `Option::map` takes self *by value*, consuming `num_as_str`
+    /// let num_as_int: Option<uint> = num_as_str.map(|n| n.len());
+    /// ```
     #[inline]
     pub fn map<U>(self, f: |T| -> U) -> Option<U> {
         match self { Some(x) => Some(f(x)), None => None }
@@ -359,7 +485,28 @@ impl<T> Option<T> {
 }
 
 impl<T: Default> Option<T> {
-    /// Returns the contained value or default (for this type)
+    /// Returns the contained value or a default
+    ///
+    /// Consumes the `self` argument then, if `Some`, returns the contained
+    /// value, otherwise if `None`, returns the default value for that
+    /// type.
+    ///
+    /// # Example
+    ///
+    /// Convert a string to an integer, turning poorly-formed strings
+    /// into 0 (the default value for integers). `from_str` converts
+    /// a string to any other type that implements `FromStr`, returning
+    /// `None` on error.
+    ///
+    /// ```
+    /// let good_year_from_input = "1909";
+    /// let bad_year_from_input = "190blarg";
+    /// let good_year = from_str(good_year_from_input).unwrap_or_default();
+    /// let bad_year = from_str(bad_year_from_input).unwrap_or_default();
+    ///
+    /// assert_eq!(1909, good_year);
+    /// assert_eq!(0, bad_year);
+    /// ```
     #[inline]
     pub fn unwrap_or_default(self) -> T {
         match self {
@@ -382,7 +529,10 @@ impl<T> Default for Option<T> {
 // The Option Iterator
 /////////////////////////////////////////////////////////////////////////////
 
-/// An iterator that yields either one or zero elements
+/// An `Option` iterator that yields either one or zero elements
+///
+/// The `Item` iterator is returned by the `iter`, `mut_iter` and `move_iter`
+/// methods on `Option`.
 #[deriving(Clone)]
 pub struct Item<A> {
     priv opt: Option<A>
@@ -464,7 +614,7 @@ mod tests {
     use iter::range;
     use str::StrSlice;
     use kinds::marker;
-    use vec::ImmutableVector;
+    use slice::ImmutableVector;
 
     #[test]
     fn test_get_ptr() {
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 040d5c0e175..d03757c1e69 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -47,7 +47,7 @@ use fmt;
 use sync::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
 use path::{Path, GenericPath};
 use iter::Iterator;
-use vec::{Vector, CloneableVector, ImmutableVector, MutableVector, OwnedVector};
+use slice::{Vector, CloneableVector, ImmutableVector, MutableVector, OwnedVector};
 use ptr::RawPtr;
 
 #[cfg(unix)]
@@ -101,8 +101,8 @@ pub mod win32 {
     use os::TMPBUF_SZ;
     use str::StrSlice;
     use str;
-    use vec::{MutableVector, ImmutableVector, OwnedVector};
-    use vec;
+    use slice::{MutableVector, ImmutableVector, OwnedVector};
+    use slice;
 
     pub fn fill_utf16_buf_and_decode(f: |*mut u16, DWORD| -> DWORD)
         -> Option<~str> {
@@ -112,7 +112,7 @@ pub mod win32 {
             let mut res = None;
             let mut done = false;
             while !done {
-                let mut buf = vec::from_elem(n as uint, 0u16);
+                let mut buf = slice::from_elem(n as uint, 0u16);
                 let k = f(buf.as_mut_ptr(), n);
                 if k == (0 as DWORD) {
                     done = true;
@@ -412,7 +412,7 @@ pub fn self_exe_name() -> Option<Path> {
         unsafe {
             use libc::funcs::bsd44::*;
             use libc::consts::os::extra::*;
-            use vec;
+            use slice;
             let mib = ~[CTL_KERN as c_int,
                         KERN_PROC as c_int,
                         KERN_PROC_PATHNAME as c_int, -1 as c_int];
@@ -422,7 +422,7 @@ pub fn self_exe_name() -> Option<Path> {
                              0u as libc::size_t);
             if err != 0 { return None; }
             if sz == 0 { return None; }
-            let mut v: ~[u8] = vec::with_capacity(sz as uint);
+            let mut v: ~[u8] = slice::with_capacity(sz as uint);
             let err = sysctl(mib.as_ptr(), mib.len() as ::libc::c_uint,
                              v.as_mut_ptr() as *mut c_void, &mut sz, ptr::null(),
                              0u as libc::size_t);
@@ -448,11 +448,11 @@ pub fn self_exe_name() -> Option<Path> {
     fn load_self() -> Option<~[u8]> {
         unsafe {
             use libc::funcs::extra::_NSGetExecutablePath;
-            use vec;
+            use slice;
             let mut sz: u32 = 0;
             _NSGetExecutablePath(ptr::mut_null(), &mut sz);
             if sz == 0 { return None; }
-            let mut v: ~[u8] = vec::with_capacity(sz as uint);
+            let mut v: ~[u8] = slice::with_capacity(sz as uint);
             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
@@ -817,7 +817,7 @@ fn real_args() -> ~[~str] {
 
 #[cfg(windows)]
 fn real_args() -> ~[~str] {
-    use vec;
+    use slice;
 
     let mut nArgs: c_int = 0;
     let lpArgCount: *mut c_int = &mut nArgs;
@@ -833,7 +833,7 @@ fn real_args() -> ~[~str] {
             while *ptr.offset(len as int) != 0 { len += 1; }
 
             // Push it onto the list.
-            let opt_s = vec::raw::buf_as_slice(ptr, len, |buf| {
+            let opt_s = slice::raw::buf_as_slice(ptr, len, |buf| {
                     str::from_utf16(str::truncate_utf16_at_nul(buf))
                 });
             args.push(opt_s.expect("CommandLineToArgvW returned invalid UTF-16"));
diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs
index 09124f63361..c8465eb039f 100644
--- a/src/libstd/path/mod.rs
+++ b/src/libstd/path/mod.rs
@@ -71,9 +71,9 @@ use iter::Iterator;
 use option::{Option, None, Some};
 use str;
 use str::{MaybeOwned, OwnedStr, Str, StrSlice, from_utf8_lossy};
-use vec;
-use vec::{CloneableVector, OwnedCloneableVector, OwnedVector, Vector};
-use vec::{ImmutableEqVector, ImmutableVector};
+use slice;
+use slice::{CloneableVector, OwnedCloneableVector, OwnedVector, Vector};
+use slice::{ImmutableEqVector, ImmutableVector};
 
 /// Typedef for POSIX file paths.
 /// See `posix::Path` for more info.
@@ -300,7 +300,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
                             } else {
                                 let mut v;
                                 let extension = extension.container_as_bytes();
-                                v = vec::with_capacity(name.len() + extension.len() + 1);
+                                v = slice::with_capacity(name.len() + extension.len() + 1);
                                 v.push_all(name);
                                 v.push(dot);
                                 v.push_all(extension);
@@ -313,7 +313,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
                             } else {
                                 let mut v;
                                 let extension = extension.container_as_bytes();
-                                v = vec::with_capacity(idx + extension.len() + 1);
+                                v = slice::with_capacity(idx + extension.len() + 1);
                                 v.push_all(name.slice_to(idx+1));
                                 v.push_all(extension);
                                 Some(v)
diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs
index 8345a2d04d1..f654f59266a 100644
--- a/src/libstd/path/posix.rs
+++ b/src/libstd/path/posix.rs
@@ -20,9 +20,9 @@ use iter::{AdditiveIterator, Extendable, Iterator, Map};
 use option::{Option, None, Some};
 use str;
 use str::Str;
-use vec;
-use vec::{CloneableVector, RevSplits, Splits, Vector, VectorVector,
-          ImmutableEqVector, OwnedVector, ImmutableVector, OwnedCloneableVector};
+use slice;
+use slice::{CloneableVector, RevSplits, Splits, Vector, VectorVector,
+            ImmutableEqVector, OwnedVector, ImmutableVector, OwnedCloneableVector};
 use super::{BytesContainer, GenericPath, GenericPathUnsafe};
 
 /// Iterator that yields successive components of a Path as &[u8]
@@ -125,7 +125,7 @@ impl GenericPathUnsafe for Path {
         let filename = filename.container_as_bytes();
         match self.sepidx {
             None if bytes!("..") == self.repr => {
-                let mut v = vec::with_capacity(3 + filename.len());
+                let mut v = slice::with_capacity(3 + filename.len());
                 v.push_all(dot_dot_static);
                 v.push(SEP_BYTE);
                 v.push_all(filename);
@@ -135,14 +135,14 @@ impl GenericPathUnsafe for Path {
                 self.repr = Path::normalize(filename);
             }
             Some(idx) if self.repr.slice_from(idx+1) == bytes!("..") => {
-                let mut v = vec::with_capacity(self.repr.len() + 1 + filename.len());
+                let mut v = slice::with_capacity(self.repr.len() + 1 + filename.len());
                 v.push_all(self.repr);
                 v.push(SEP_BYTE);
                 v.push_all(filename);
                 self.repr = Path::normalize(v);
             }
             Some(idx) => {
-                let mut v = vec::with_capacity(idx + 1 + filename.len());
+                let mut v = slice::with_capacity(idx + 1 + filename.len());
                 v.push_all(self.repr.slice_to(idx+1));
                 v.push_all(filename);
                 self.repr = Path::normalize(v);
@@ -157,7 +157,7 @@ impl GenericPathUnsafe for Path {
             if path[0] == SEP_BYTE {
                 self.repr = Path::normalize(path);
             }  else {
-                let mut v = vec::with_capacity(self.repr.len() + path.len() + 1);
+                let mut v = slice::with_capacity(self.repr.len() + path.len() + 1);
                 v.push_all(self.repr);
                 v.push(SEP_BYTE);
                 v.push_all(path);
@@ -346,7 +346,7 @@ impl Path {
                     } else {
                         let n = if is_abs { comps.len() } else { comps.len() - 1} +
                                 comps.iter().map(|v| v.len()).sum();
-                        let mut v = vec::with_capacity(n);
+                        let mut v = slice::with_capacity(n);
                         let mut it = comps.move_iter();
                         if !is_abs {
                             match it.next() {
diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs
index 180078ae959..dba8af4128b 100644
--- a/src/libstd/path/windows.rs
+++ b/src/libstd/path/windows.rs
@@ -22,7 +22,7 @@ use iter::{AdditiveIterator, DoubleEndedIterator, Extendable, Rev, Iterator, Map
 use option::{Option, Some, None};
 use str;
 use str::{CharSplits, OwnedStr, Str, StrVector, StrSlice};
-use vec::{Vector, OwnedVector, ImmutableVector};
+use slice::{Vector, OwnedVector, ImmutableVector};
 use super::{contains_nul, BytesContainer, GenericPath, GenericPathUnsafe};
 
 /// Iterator that yields successive components of a Path as &str
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index a04b59ae601..f3a5bd3d3b5 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -20,7 +20,7 @@ generally useful to many Rust programs.
 */
 
 // Reexported core operators
-pub use kinds::{Freeze, Pod, Send, Sized};
+pub use kinds::{Freeze, Pod, Send, Sized, Share};
 pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
 pub use ops::{BitAnd, BitOr, BitXor};
 pub use ops::{Drop, Deref, DerefMut};
@@ -55,10 +55,10 @@ pub use to_str::{ToStr, IntoStr};
 pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4};
 pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8};
 pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12};
-pub use vec::{ImmutableEqVector, ImmutableTotalOrdVector, ImmutableCloneableVector};
-pub use vec::{OwnedVector, OwnedCloneableVector, OwnedEqVector};
-pub use vec::{MutableVector, MutableTotalOrdVector};
-pub use vec::{Vector, VectorVector, CloneableVector, ImmutableVector};
+pub use slice::{ImmutableEqVector, ImmutableTotalOrdVector, ImmutableCloneableVector};
+pub use slice::{OwnedVector, OwnedCloneableVector, OwnedEqVector};
+pub use slice::{MutableVector, MutableTotalOrdVector};
+pub use slice::{Vector, VectorVector, CloneableVector, ImmutableVector};
 
 // Reexported runtime types
 pub use comm::{channel, Sender, Receiver};
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs
index bf5ba6db5c3..179100255c4 100644
--- a/src/libstd/ptr.rs
+++ b/src/libstd/ptr.rs
@@ -388,7 +388,7 @@ pub mod ptr_tests {
     use cast;
     use libc;
     use str;
-    use vec::{ImmutableVector, MutableVector};
+    use slice::{ImmutableVector, MutableVector};
 
     #[test]
     fn test() {
diff --git a/src/libstd/rc.rs b/src/libstd/rc.rs
index 5c4b19b4e4b..605cbd3f28a 100644
--- a/src/libstd/rc.rs
+++ b/src/libstd/rc.rs
@@ -42,7 +42,8 @@ struct RcBox<T> {
 #[unsafe_no_drop_flag]
 pub struct Rc<T> {
     priv ptr: *mut RcBox<T>,
-    priv marker: marker::NoSend
+    priv nosend: marker::NoSend,
+    priv noshare: marker::NoShare
 }
 
 impl<T> Rc<T> {
@@ -56,7 +57,8 @@ impl<T> Rc<T> {
                 // strong destructor is running, even if the weak
                 // pointer is stored inside the strong one.
                 ptr: transmute(~RcBox { value: value, strong: 1, weak: 1 }),
-                marker: marker::NoSend,
+                nosend: marker::NoSend,
+                noshare: marker::NoShare
             }
         }
     }
@@ -67,7 +69,11 @@ impl<T> Rc<T> {
     pub fn downgrade(&self) -> Weak<T> {
         unsafe {
             (*self.ptr).weak += 1;
-            Weak { ptr: self.ptr, marker: marker::NoSend }
+            Weak {
+                ptr: self.ptr,
+                nosend: marker::NoSend,
+                noshare: marker::NoShare
+            }
         }
     }
 }
@@ -107,7 +113,7 @@ impl<T> Clone for Rc<T> {
     fn clone(&self) -> Rc<T> {
         unsafe {
             (*self.ptr).strong += 1;
-            Rc { ptr: self.ptr, marker: marker::NoSend }
+            Rc { ptr: self.ptr, nosend: marker::NoSend, noshare: marker::NoShare }
         }
     }
 }
@@ -138,7 +144,8 @@ impl<T: Ord> Ord for Rc<T> {
 #[unsafe_no_drop_flag]
 pub struct Weak<T> {
     priv ptr: *mut RcBox<T>,
-    priv marker: marker::NoSend
+    priv nosend: marker::NoSend,
+    priv noshare: marker::NoShare
 }
 
 impl<T> Weak<T> {
@@ -149,7 +156,7 @@ impl<T> Weak<T> {
                 None
             } else {
                 (*self.ptr).strong += 1;
-                Some(Rc { ptr: self.ptr, marker: marker::NoSend })
+                Some(Rc { ptr: self.ptr, nosend: marker::NoSend, noshare: marker::NoShare })
             }
         }
     }
@@ -176,7 +183,7 @@ impl<T> Clone for Weak<T> {
     fn clone(&self) -> Weak<T> {
         unsafe {
             (*self.ptr).weak += 1;
-            Weak { ptr: self.ptr, marker: marker::NoSend }
+            Weak { ptr: self.ptr, nosend: marker::NoSend, noshare: marker::NoShare }
         }
     }
 }
diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs
index c1b276899d5..f623dd472fd 100644
--- a/src/libstd/repr.rs
+++ b/src/libstd/repr.rs
@@ -28,7 +28,7 @@ use reflect::{MovePtr, align};
 use result::{Ok, Err};
 use str::StrSlice;
 use to_str::ToStr;
-use vec::OwnedVector;
+use slice::OwnedVector;
 use intrinsics::{Disr, Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
 use raw;
 
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs
index 6f73265978b..53b8db8499d 100644
--- a/src/libstd/rt/args.rs
+++ b/src/libstd/rt/args.rs
@@ -124,10 +124,10 @@ mod imp {
     #[cfg(not(test))]
     unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> ~[~[u8]] {
         use c_str::CString;
-        use {vec, libc};
-        use vec::CloneableVector;
+        use {slice, libc};
+        use slice::CloneableVector;
 
-        vec::from_fn(argc as uint, |i| {
+        slice::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()
         })
diff --git a/src/libstd/rt/at_exit_imp.rs b/src/libstd/rt/at_exit_imp.rs
index 185f4b4edd7..96dcc5244c0 100644
--- a/src/libstd/rt/at_exit_imp.rs
+++ b/src/libstd/rt/at_exit_imp.rs
@@ -18,7 +18,7 @@ use mem;
 use option::{Some, None};
 use ptr::RawPtr;
 use unstable::sync::Exclusive;
-use vec::OwnedVector;
+use slice::OwnedVector;
 
 type Queue = Exclusive<~[proc()]>;
 
diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs
index bc75a98e085..7ae2521c423 100644
--- a/src/libstd/rt/backtrace.rs
+++ b/src/libstd/rt/backtrace.rs
@@ -349,7 +349,7 @@ mod imp {
         use path::GenericPath;
         use ptr::RawPtr;
         use ptr;
-        use vec::{ImmutableVector, MutableVector};
+        use slice::{ImmutableVector, MutableVector};
 
         ////////////////////////////////////////////////////////////////////////
         // libbacktrace.h API
@@ -510,7 +510,7 @@ mod imp {
     use unstable::dynamic_lib::DynamicLibrary;
     use intrinsics;
     use unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
-    use vec::ImmutableVector;
+    use slice::ImmutableVector;
 
     extern "system" {
         fn GetCurrentProcess() -> libc::HANDLE;
diff --git a/src/libstd/rt/crate_map.rs b/src/libstd/rt/crate_map.rs
index c6d5a80208b..52cced26254 100644
--- a/src/libstd/rt/crate_map.rs
+++ b/src/libstd/rt/crate_map.rs
@@ -16,7 +16,7 @@ use rt::rtio::EventLoop;
 #[cfg(stage0)] use cmp::TotalOrd;
 #[cfg(stage0)] use container::MutableSet;
 #[cfg(stage0)] use iter::Iterator;
-#[cfg(stage0)] use vec::{ImmutableVector, OwnedVector};
+#[cfg(stage0)] use slice::{ImmutableVector, OwnedVector};
 
 // Need to tell the linker on OS X to not barf on undefined symbols
 // and instead look them up at runtime, which we need to resolve
diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs
index 29b3dcaa4f2..a682a6141b1 100644
--- a/src/libstd/rt/local_heap.rs
+++ b/src/libstd/rt/local_heap.rs
@@ -21,8 +21,8 @@ use rt::global_heap;
 use rt::local::Local;
 use rt::task::Task;
 use raw;
-use vec::ImmutableVector;
-use vec_ng::Vec;
+use slice::ImmutableVector;
+use vec::Vec;
 
 // This has no meaning with out rtdebug also turned on.
 #[cfg(rtdebug)]
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index 6fe4db54944..4c208a64ddf 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -20,7 +20,7 @@ use os;
 use result::Ok;
 use str::StrSlice;
 use unstable::running_on_valgrind;
-use vec::ImmutableVector;
+use slice::ImmutableVector;
 
 // Indicates whether we should perform expensive sanity checks, including rtassert!
 // FIXME: Once the runtime matures remove the `true` below to turn off rtassert, etc.
diff --git a/src/libstd/slice.rs b/src/libstd/slice.rs
new file mode 100644
index 00000000000..12718c55923
--- /dev/null
+++ b/src/libstd/slice.rs
@@ -0,0 +1,4652 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+/*!
+
+Utilities for vector manipulation
+
+The `vec` module contains useful code to help work with vector values.
+Vectors are Rust's list type. Vectors contain zero or more values of
+homogeneous types:
+
+```rust
+let int_vector = [1,2,3];
+let str_vector = ["one", "two", "three"];
+ ```
+
+This is a big module, but for a high-level overview:
+
+## Structs
+
+Several structs that are useful for vectors, such as `Items`, which
+represents iteration over a vector.
+
+## Traits
+
+A number of traits add methods that allow you to accomplish tasks with vectors.
+
+Traits defined for the `&[T]` type (a vector slice), have methods that can be
+called on either owned vectors, denoted `~[T]`, or on vector slices themselves.
+These traits include `ImmutableVector`, and `MutableVector` for the `&mut [T]`
+case.
+
+An example is the method `.slice(a, b)` that returns an immutable "view" into
+a vector or a vector slice from the index interval `[a, b)`:
+
+```rust
+let numbers = [0, 1, 2];
+let last_numbers = numbers.slice(1, 3);
+// last_numbers is now &[1, 2]
+ ```
+
+Traits defined for the `~[T]` type, like `OwnedVector`, can only be called
+on such vectors. These methods deal with adding elements or otherwise changing
+the allocation of the vector.
+
+An example is the method `.push(element)` that will add an element at the end
+of the vector:
+
+```rust
+let mut numbers = ~[0, 1, 2];
+numbers.push(7);
+// numbers is now ~[0, 1, 2, 7];
+ ```
+
+## Implementations of other traits
+
+Vectors are a very useful type, and so there's several implementations of
+traits from other modules. Some notable examples:
+
+* `Clone`
+* `Eq`, `Ord`, `TotalEq`, `TotalOrd` -- vectors can be compared,
+  if the element type defines the corresponding trait.
+
+## Iteration
+
+The method `iter()` returns an iteration value for a vector or a vector slice.
+The iterator yields references to the vector's elements, so if the element
+type of the vector is `int`, the element type of the iterator is `&int`.
+
+```rust
+let numbers = [0, 1, 2];
+for &x in numbers.iter() {
+    println!("{} is a number!", x);
+}
+ ```
+
+* `.rev_iter()` returns an iterator with the same values as `.iter()`,
+  but going in the reverse order, starting with the back element.
+* `.mut_iter()` returns an iterator that allows modifying each value.
+* `.move_iter()` converts an owned vector into an iterator that
+  moves out a value from the vector each iteration.
+* Further iterators exist that split, chunk or permute the vector.
+
+## Function definitions
+
+There are a number of free functions that create or take vectors, for example:
+
+* Creating a vector, like `from_elem` and `from_fn`
+* Creating a vector with a given size: `with_capacity`
+* Modifying a vector and returning it, like `append`
+* Operations on paired elements, like `unzip`.
+
+*/
+
+#[warn(non_camel_case_types)];
+
+use cast;
+use cast::transmute;
+use ops::Drop;
+use clone::Clone;
+use container::{Container, Mutable};
+use cmp::{Eq, TotalOrd, Ordering, Less, Equal, Greater};
+use cmp;
+use default::Default;
+use fmt;
+use iter::*;
+use num::{CheckedAdd, Saturating, checked_next_power_of_two, div_rem};
+use option::{None, Option, Some};
+use ptr;
+use ptr::RawPtr;
+use rt::global_heap::{malloc_raw, realloc_raw, exchange_free};
+use result::{Ok, Err};
+use mem;
+use mem::size_of;
+use kinds::marker;
+use uint;
+use unstable::finally::try_finally;
+use raw::{Repr, Slice, Vec};
+
+/**
+ * Creates and initializes an owned vector.
+ *
+ * Creates an owned vector of size `n_elts` and initializes the elements
+ * to the value returned by the function `op`.
+ */
+pub fn from_fn<T>(n_elts: uint, op: |uint| -> T) -> ~[T] {
+    unsafe {
+        let mut v = with_capacity(n_elts);
+        let p = v.as_mut_ptr();
+        let mut i = 0;
+        try_finally(
+            &mut i, (),
+            |i, ()| while *i < n_elts {
+                mem::move_val_init(
+                    &mut(*p.offset(*i as int)),
+                    op(*i));
+                *i += 1u;
+            },
+            |i| v.set_len(*i));
+        v
+    }
+}
+
+/**
+ * Creates and initializes an owned vector.
+ *
+ * Creates an owned vector of size `n_elts` and initializes the elements
+ * to the value `t`.
+ */
+pub fn from_elem<T:Clone>(n_elts: uint, t: T) -> ~[T] {
+    // FIXME (#7136): manually inline from_fn for 2x plus speedup (sadly very
+    // important, from_elem is a bottleneck in borrowck!). Unfortunately it
+    // still is substantially slower than using the unsafe
+    // slice::with_capacity/ptr::set_memory for primitive types.
+    unsafe {
+        let mut v = with_capacity(n_elts);
+        let p = v.as_mut_ptr();
+        let mut i = 0u;
+        try_finally(
+            &mut i, (),
+            |i, ()| while *i < n_elts {
+                mem::move_val_init(
+                    &mut(*p.offset(*i as int)),
+                    t.clone());
+                *i += 1u;
+            },
+            |i| v.set_len(*i));
+        v
+    }
+}
+
+/// Creates a new vector with a capacity of `capacity`
+#[inline]
+pub fn with_capacity<T>(capacity: uint) -> ~[T] {
+    unsafe {
+        let alloc = capacity * mem::nonzero_size_of::<T>();
+        let size = alloc + mem::size_of::<Vec<()>>();
+        if alloc / mem::nonzero_size_of::<T>() != capacity || size < alloc {
+            fail!("vector size is too large: {}", capacity);
+        }
+        let ptr = malloc_raw(size) as *mut Vec<()>;
+        (*ptr).alloc = alloc;
+        (*ptr).fill = 0;
+        transmute(ptr)
+    }
+}
+
+/**
+ * Builds a vector by calling a provided function with an argument
+ * function that pushes an element to the back of a vector.
+ * The initial capacity for the vector may optionally be specified.
+ *
+ * # Arguments
+ *
+ * * size - An option, maybe containing initial size of the vector to reserve
+ * * builder - A function that will construct the vector. It receives
+ *             as an argument a function that will push an element
+ *             onto the vector being constructed.
+ */
+#[inline]
+pub fn build<A>(size: Option<uint>, builder: |push: |v: A||) -> ~[A] {
+    let mut vec = with_capacity(size.unwrap_or(4));
+    builder(|x| vec.push(x));
+    vec
+}
+
+/**
+ * Converts a pointer to A into a slice of length 1 (without copying).
+ */
+pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] {
+    unsafe {
+        transmute(Slice { data: s, len: 1 })
+    }
+}
+
+/**
+ * Converts a pointer to A into a slice of length 1 (without copying).
+ */
+pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
+    unsafe {
+        let ptr: *A = transmute(s);
+        transmute(Slice { data: ptr, len: 1 })
+    }
+}
+
+/// An iterator over the slices of a vector separated by elements that
+/// match a predicate function.
+pub struct Splits<'a, T> {
+    priv v: &'a [T],
+    priv n: uint,
+    priv pred: 'a |t: &T| -> bool,
+    priv finished: bool
+}
+
+impl<'a, T> Iterator<&'a [T]> for Splits<'a, T> {
+    #[inline]
+    fn next(&mut self) -> Option<&'a [T]> {
+        if self.finished { return None; }
+
+        if self.n == 0 {
+            self.finished = true;
+            return Some(self.v);
+        }
+
+        match self.v.iter().position(|x| (self.pred)(x)) {
+            None => {
+                self.finished = true;
+                Some(self.v)
+            }
+            Some(idx) => {
+                let ret = Some(self.v.slice(0, idx));
+                self.v = self.v.slice(idx + 1, self.v.len());
+                self.n -= 1;
+                ret
+            }
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        if self.finished {
+            return (0, Some(0))
+        }
+        // if the predicate doesn't match anything, we yield one slice
+        // if it matches every element, we yield N+1 empty slices where
+        // N is either the number of elements or the number of splits.
+        match (self.v.len(), self.n) {
+            (0,_) => (1, Some(1)),
+            (_,0) => (1, Some(1)),
+            (l,n) => (1, cmp::min(l,n).checked_add(&1u))
+        }
+    }
+}
+
+/// An iterator over the slices of a vector separated by elements that
+/// match a predicate function, from back to front.
+pub struct RevSplits<'a, T> {
+    priv v: &'a [T],
+    priv n: uint,
+    priv pred: 'a |t: &T| -> bool,
+    priv finished: bool
+}
+
+impl<'a, T> Iterator<&'a [T]> for RevSplits<'a, T> {
+    #[inline]
+    fn next(&mut self) -> Option<&'a [T]> {
+        if self.finished { return None; }
+
+        if self.n == 0 {
+            self.finished = true;
+            return Some(self.v);
+        }
+
+        let pred = &mut self.pred;
+        match self.v.iter().rposition(|x| (*pred)(x)) {
+            None => {
+                self.finished = true;
+                Some(self.v)
+            }
+            Some(idx) => {
+                let ret = Some(self.v.slice(idx + 1, self.v.len()));
+                self.v = self.v.slice(0, idx);
+                self.n -= 1;
+                ret
+            }
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        if self.finished {
+            return (0, Some(0))
+        }
+        match (self.v.len(), self.n) {
+            (0,_) => (1, Some(1)),
+            (_,0) => (1, Some(1)),
+            (l,n) => (1, cmp::min(l,n).checked_add(&1u))
+        }
+    }
+}
+
+// Appending
+
+/// Iterates over the `rhs` vector, copying each element and appending it to the
+/// `lhs`. Afterwards, the `lhs` is then returned for use again.
+#[inline]
+pub fn append<T:Clone>(lhs: ~[T], rhs: &[T]) -> ~[T] {
+    let mut v = lhs;
+    v.push_all(rhs);
+    v
+}
+
+/// Appends one element to the vector provided. The vector itself is then
+/// returned for use again.
+#[inline]
+pub fn append_one<T>(lhs: ~[T], x: T) -> ~[T] {
+    let mut v = lhs;
+    v.push(x);
+    v
+}
+
+// Functional utilities
+
+/**
+ * Apply a function to each element of a vector and return a concatenation
+ * of each result vector
+ */
+pub fn flat_map<T, U>(v: &[T], f: |t: &T| -> ~[U]) -> ~[U] {
+    let mut result = ~[];
+    for elem in v.iter() { result.push_all_move(f(elem)); }
+    result
+}
+
+#[allow(missing_doc)]
+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];
+
+    /// Concatenate a vector of vectors, placing a given separator between each.
+    fn connect_vec(&self, sep: &T) -> ~[T];
+}
+
+impl<'a, T: Clone, V: Vector<T>> VectorVector<T> for &'a [V] {
+    fn concat_vec(&self) -> ~[T] {
+        let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
+        let mut result = with_capacity(size);
+        for v in self.iter() {
+            result.push_all(v.as_slice())
+        }
+        result
+    }
+
+    fn connect_vec(&self, sep: &T) -> ~[T] {
+        let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
+        let mut result = with_capacity(size + self.len());
+        let mut first = true;
+        for v in self.iter() {
+            if first { first = false } else { result.push(sep.clone()) }
+            result.push_all(v.as_slice())
+        }
+        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 = with_capacity(lo);
+    let mut us = with_capacity(lo);
+    for (t, u) in iter {
+        ts.push(t);
+        us.push(u);
+    }
+    (ts, us)
+}
+
+/// 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.
+///
+/// The Steinhaus–Johnson–Trotter algorithm is used.
+///
+/// Generates even and odd permutations alternately.
+///
+/// The last generated swap is always (0, 1), and it returns the
+/// sequence to its initial order.
+pub struct ElementSwaps {
+    priv sdir: ~[SizeDirection],
+    /// If true, emit the last swap that returns the sequence to initial state
+    priv emit_reset: bool,
+}
+
+impl ElementSwaps {
+    /// Create an `ElementSwaps` iterator for a sequence of `length` elements
+    pub fn new(length: uint) -> ElementSwaps {
+        // Initialize `sdir` with a direction that position should move in
+        // (all negative at the beginning) and the `size` of the
+        // element (equal to the original index).
+        ElementSwaps{
+            emit_reset: true,
+            sdir: range(0, length)
+                    .map(|i| SizeDirection{ size: i, dir: Neg })
+                    .to_owned_vec()
+        }
+    }
+}
+
+enum Direction { Pos, Neg }
+
+/// An Index and Direction together
+struct SizeDirection {
+    size: uint,
+    dir: Direction,
+}
+
+impl Iterator<(uint, uint)> for ElementSwaps {
+    #[inline]
+    fn next(&mut self) -> Option<(uint, uint)> {
+        fn new_pos(i: uint, s: Direction) -> uint {
+            i + match s { Pos => 1, Neg => -1 }
+        }
+
+        // Find the index of the largest mobile element:
+        // The direction should point into the vector, and the
+        // swap should be with a smaller `size` element.
+        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)
+                           .max_by(|&(_, sd)| sd.size);
+        match max {
+            Some((i, sd)) => {
+                let j = new_pos(i, sd.dir);
+                self.sdir.swap(i, j);
+
+                // Swap the direction of each larger SizeDirection
+                for x in self.sdir.mut_iter() {
+                    if x.size > sd.size {
+                        x.dir = match x.dir { Pos => Neg, Neg => Pos };
+                    }
+                }
+                Some((i, j))
+            },
+            None => if self.emit_reset && self.sdir.len() > 1 {
+                self.emit_reset = false;
+                Some((0, 1))
+            } else {
+                None
+            }
+        }
+    }
+}
+
+/// An Iterator that uses `ElementSwaps` to iterate through
+/// all possible permutations of a vector.
+///
+/// The first iteration yields a clone of the vector as it is,
+/// then each successive element is the vector with one
+/// swap applied.
+///
+/// Generates even and odd permutations alternately.
+pub struct Permutations<T> {
+    priv swaps: ElementSwaps,
+    priv v: ~[T],
+}
+
+impl<T: Clone> Iterator<~[T]> for Permutations<T> {
+    #[inline]
+    fn next(&mut self) -> Option<~[T]> {
+        match self.swaps.next() {
+            None => None,
+            Some((a, b)) => {
+                let elt = self.v.clone();
+                self.v.swap(a, b);
+                Some(elt)
+            }
+        }
+    }
+}
+
+/// An iterator over the (overlapping) slices of length `size` within
+/// a vector.
+#[deriving(Clone)]
+pub struct Windows<'a, T> {
+    priv v: &'a [T],
+    priv size: uint
+}
+
+impl<'a, T> Iterator<&'a [T]> for Windows<'a, T> {
+    #[inline]
+    fn next(&mut self) -> Option<&'a [T]> {
+        if self.size > self.v.len() {
+            None
+        } else {
+            let ret = Some(self.v.slice(0, self.size));
+            self.v = self.v.slice(1, self.v.len());
+            ret
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        if self.size > self.v.len() {
+            (0, Some(0))
+        } else {
+            let x = self.v.len() - self.size;
+            (x.saturating_add(1), x.checked_add(&1u))
+        }
+    }
+}
+
+/// An iterator over a vector in (non-overlapping) chunks (`size`
+/// elements at a time).
+///
+/// When the vector len is not evenly divided by the chunk size,
+/// the last slice of the iteration will be the remainder.
+#[deriving(Clone)]
+pub struct Chunks<'a, T> {
+    priv v: &'a [T],
+    priv size: uint
+}
+
+impl<'a, T> Iterator<&'a [T]> for Chunks<'a, T> {
+    #[inline]
+    fn next(&mut self) -> Option<&'a [T]> {
+        if self.v.len() == 0 {
+            None
+        } else {
+            let chunksz = cmp::min(self.v.len(), self.size);
+            let (fst, snd) = (self.v.slice_to(chunksz),
+                              self.v.slice_from(chunksz));
+            self.v = snd;
+            Some(fst)
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        if self.v.len() == 0 {
+            (0, Some(0))
+        } else {
+            let (n, rem) = div_rem(self.v.len(), self.size);
+            let n = if rem > 0 { n+1 } else { n };
+            (n, Some(n))
+        }
+    }
+}
+
+impl<'a, T> DoubleEndedIterator<&'a [T]> for Chunks<'a, T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<&'a [T]> {
+        if self.v.len() == 0 {
+            None
+        } else {
+            let remainder = self.v.len() % self.size;
+            let chunksz = if remainder != 0 { remainder } else { self.size };
+            let (fst, snd) = (self.v.slice_to(self.v.len() - chunksz),
+                              self.v.slice_from(self.v.len() - chunksz));
+            self.v = fst;
+            Some(snd)
+        }
+    }
+}
+
+impl<'a, T> RandomAccessIterator<&'a [T]> for Chunks<'a, T> {
+    #[inline]
+    fn indexable(&self) -> uint {
+        self.v.len()/self.size + if self.v.len() % self.size != 0 { 1 } else { 0 }
+    }
+
+    #[inline]
+    fn idx(&self, index: uint) -> Option<&'a [T]> {
+        if index < self.indexable() {
+            let lo = index * self.size;
+            let mut hi = lo + self.size;
+            if hi < lo || hi > self.v.len() { hi = self.v.len(); }
+
+            Some(self.v.slice(lo, hi))
+        } else {
+            None
+        }
+    }
+}
+
+// Equality
+
+#[cfg(not(test))]
+#[allow(missing_doc)]
+pub mod traits {
+    use super::*;
+
+    use container::Container;
+    use clone::Clone;
+    use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Equiv};
+    use iter::order;
+    use ops::Add;
+
+    impl<'a,T:Eq> Eq for &'a [T] {
+        fn eq(&self, other: & &'a [T]) -> bool {
+            self.len() == other.len() &&
+                order::eq(self.iter(), other.iter())
+        }
+        fn ne(&self, other: & &'a [T]) -> bool {
+            self.len() != other.len() ||
+                order::ne(self.iter(), other.iter())
+        }
+    }
+
+    impl<T:Eq> Eq for ~[T] {
+        #[inline]
+        fn eq(&self, other: &~[T]) -> bool { self.as_slice() == *other }
+        #[inline]
+        fn ne(&self, other: &~[T]) -> bool { !self.eq(other) }
+    }
+
+    impl<'a,T:TotalEq> TotalEq for &'a [T] {
+        fn equals(&self, other: & &'a [T]) -> bool {
+            self.len() == other.len() &&
+                order::equals(self.iter(), other.iter())
+        }
+    }
+
+    impl<T:TotalEq> TotalEq for ~[T] {
+        #[inline]
+        fn equals(&self, other: &~[T]) -> bool { self.as_slice().equals(&other.as_slice()) }
+    }
+
+    impl<'a,T:Eq, V: Vector<T>> Equiv<V> for &'a [T] {
+        #[inline]
+        fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
+    }
+
+    impl<'a,T:Eq, V: Vector<T>> Equiv<V> for ~[T] {
+        #[inline]
+        fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
+    }
+
+    impl<'a,T:TotalOrd> TotalOrd for &'a [T] {
+        fn cmp(&self, other: & &'a [T]) -> Ordering {
+            order::cmp(self.iter(), other.iter())
+        }
+    }
+
+    impl<T: TotalOrd> TotalOrd for ~[T] {
+        #[inline]
+        fn cmp(&self, other: &~[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
+    }
+
+    impl<'a, T: Ord> Ord for &'a [T] {
+        fn lt(&self, other: & &'a [T]) -> bool {
+            order::lt(self.iter(), other.iter())
+        }
+        #[inline]
+        fn le(&self, other: & &'a [T]) -> bool {
+            order::le(self.iter(), other.iter())
+        }
+        #[inline]
+        fn ge(&self, other: & &'a [T]) -> bool {
+            order::ge(self.iter(), other.iter())
+        }
+        #[inline]
+        fn gt(&self, other: & &'a [T]) -> bool {
+            order::gt(self.iter(), other.iter())
+        }
+    }
+
+    impl<T: Ord> Ord for ~[T] {
+        #[inline]
+        fn lt(&self, other: &~[T]) -> bool { self.as_slice() < other.as_slice() }
+        #[inline]
+        fn le(&self, other: &~[T]) -> bool { self.as_slice() <= other.as_slice() }
+        #[inline]
+        fn ge(&self, other: &~[T]) -> bool { self.as_slice() >= other.as_slice() }
+        #[inline]
+        fn gt(&self, other: &~[T]) -> bool { self.as_slice() > other.as_slice() }
+    }
+
+    impl<'a,T:Clone, V: Vector<T>> Add<V, ~[T]> for &'a [T] {
+        #[inline]
+        fn add(&self, rhs: &V) -> ~[T] {
+            let mut res = with_capacity(self.len() + rhs.as_slice().len());
+            res.push_all(*self);
+            res.push_all(rhs.as_slice());
+            res
+        }
+    }
+
+    impl<T:Clone, V: Vector<T>> Add<V, ~[T]> for ~[T] {
+        #[inline]
+        fn add(&self, rhs: &V) -> ~[T] {
+            self.as_slice() + rhs.as_slice()
+        }
+    }
+}
+
+#[cfg(test)]
+pub mod traits {}
+
+/// Any vector that can be represented as a slice.
+pub trait Vector<T> {
+    /// Work with `self` as a slice.
+    fn as_slice<'a>(&'a self) -> &'a [T];
+}
+
+impl<'a,T> Vector<T> for &'a [T] {
+    #[inline(always)]
+    fn as_slice<'a>(&'a self) -> &'a [T] { *self }
+}
+
+impl<T> Vector<T> for ~[T] {
+    #[inline(always)]
+    fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v }
+}
+
+impl<'a, T> Container for &'a [T] {
+    /// Returns the length of a vector
+    #[inline]
+    fn len(&self) -> uint {
+        self.repr().len
+    }
+}
+
+impl<T> Container for ~[T] {
+    /// Returns the length of a vector
+    #[inline]
+    fn len(&self) -> uint {
+        self.as_slice().len()
+    }
+}
+
+/// Extension methods for vector slices with cloneable elements
+pub trait CloneableVector<T> {
+    /// Copy `self` into a new owned vector
+    fn to_owned(&self) -> ~[T];
+
+    /// Convert `self` into an owned vector, not making a copy if possible.
+    fn into_owned(self) -> ~[T];
+}
+
+/// Extension methods for vector slices
+impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
+    /// Returns a copy of `v`.
+    #[inline]
+    fn to_owned(&self) -> ~[T] {
+        let mut result = with_capacity(self.len());
+        for e in self.iter() {
+            result.push((*e).clone());
+        }
+        result
+    }
+
+    #[inline(always)]
+    fn into_owned(self) -> ~[T] { self.to_owned() }
+}
+
+/// Extension methods for owned vectors
+impl<T: Clone> CloneableVector<T> for ~[T] {
+    #[inline]
+    fn to_owned(&self) -> ~[T] { self.clone() }
+
+    #[inline(always)]
+    fn into_owned(self) -> ~[T] { self }
+}
+
+/// Extension methods for vectors
+pub trait ImmutableVector<'a, T> {
+    /**
+     * Returns a slice of self between `start` and `end`.
+     *
+     * Fails when `start` or `end` point outside the bounds of self,
+     * or when `start` > `end`.
+     */
+    fn slice(&self, start: uint, end: uint) -> &'a [T];
+
+    /**
+     * Returns a slice of self from `start` to the end of the vec.
+     *
+     * Fails when `start` points outside the bounds of self.
+     */
+    fn slice_from(&self, start: uint) -> &'a [T];
+
+    /**
+     * Returns a slice of self from the start of the vec to `end`.
+     *
+     * Fails when `end` points outside the bounds of self.
+     */
+    fn slice_to(&self, end: uint) -> &'a [T];
+    /// Returns an iterator over the vector
+    fn iter(self) -> Items<'a, T>;
+    /// Returns a reversed iterator over a vector
+    fn rev_iter(self) -> RevItems<'a, T>;
+    /// Returns an iterator over the subslices of the vector which are
+    /// separated by elements that match `pred`.  The matched element
+    /// is not contained in the subslices.
+    fn split(self, pred: 'a |&T| -> bool) -> Splits<'a, T>;
+    /// Returns an iterator over the subslices of the vector which are
+    /// separated by elements that match `pred`, limited to splitting
+    /// at most `n` times.  The matched element is not contained in
+    /// the subslices.
+    fn splitn(self, n: uint, pred: 'a |&T| -> bool) -> Splits<'a, T>;
+    /// Returns an iterator over the subslices of the vector which are
+    /// separated by elements that match `pred`. This starts at the
+    /// end of the vector and works backwards.  The matched element is
+    /// not contained in the subslices.
+    fn rsplit(self, pred: 'a |&T| -> bool) -> RevSplits<'a, T>;
+    /// Returns an iterator over the subslices of the vector which are
+    /// separated by elements that match `pred` limited to splitting
+    /// at most `n` times. This starts at the end of the vector and
+    /// works backwards.  The matched element is not contained in the
+    /// subslices.
+    fn rsplitn(self,  n: uint, pred: 'a |&T| -> bool) -> RevSplits<'a, T>;
+
+    /**
+     * Returns an iterator over all contiguous windows of length
+     * `size`. The windows overlap. If the vector is shorter than
+     * `size`, the iterator returns no values.
+     *
+     * # Failure
+     *
+     * Fails if `size` is 0.
+     *
+     * # Example
+     *
+     * Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`,
+     * `[3,4]`):
+     *
+     * ```rust
+     * let v = &[1,2,3,4];
+     * for win in v.windows(2) {
+     *     println!("{:?}", win);
+     * }
+     * ```
+     *
+     */
+    fn windows(self, size: uint) -> Windows<'a, T>;
+    /**
+     *
+     * Returns an iterator over `size` elements of the vector at a
+     * time. The chunks do not overlap. If `size` does not divide the
+     * length of the vector, then the last chunk will not have length
+     * `size`.
+     *
+     * # Failure
+     *
+     * Fails if `size` is 0.
+     *
+     * # Example
+     *
+     * Print the vector two elements at a time (i.e. `[1,2]`,
+     * `[3,4]`, `[5]`):
+     *
+     * ```rust
+     * let v = &[1,2,3,4,5];
+     * for win in v.chunks(2) {
+     *     println!("{:?}", win);
+     * }
+     * ```
+     *
+     */
+    fn chunks(self, size: uint) -> Chunks<'a, T>;
+
+    /// Returns the element of a vector at the given index, or `None` if the
+    /// index is out of bounds
+    fn get(&self, index: uint) -> Option<&'a T>;
+    /// Returns the first element of a vector, or `None` if it is empty
+    fn head(&self) -> Option<&'a T>;
+    /// Returns all but the first element of a vector
+    fn tail(&self) -> &'a [T];
+    /// Returns all but the first `n' elements of a vector
+    fn tailn(&self, n: uint) -> &'a [T];
+    /// Returns all but the last element of a vector
+    fn init(&self) -> &'a [T];
+    /// Returns all but the last `n' elements of a vector
+    fn initn(&self, n: uint) -> &'a [T];
+    /// Returns the last element of a vector, or `None` if it is empty.
+    fn last(&self) -> Option<&'a T>;
+    /**
+     * Apply a function to each element of a vector and return a concatenation
+     * of each result vector
+     */
+    fn flat_map<U>(&self, f: |t: &T| -> ~[U]) -> ~[U];
+    /// Returns a pointer to the element at the given index, without doing
+    /// bounds checking.
+    unsafe fn unsafe_ref(self, index: uint) -> &'a T;
+
+    /**
+     * Returns an unsafe pointer to the vector's buffer
+     *
+     * The caller must ensure that the vector outlives the pointer this
+     * function returns, or else it will end up pointing to garbage.
+     *
+     * Modifying the vector may cause its buffer to be reallocated, which
+     * would also make any pointers to it invalid.
+     */
+    fn as_ptr(&self) -> *T;
+
+    /**
+     * Binary search a sorted vector with a comparator function.
+     *
+     * The comparator function should implement an order consistent
+     * with the sort order of the underlying vector, returning an
+     * order code that indicates whether its argument is `Less`,
+     * `Equal` or `Greater` the desired target.
+     *
+     * Returns the index where the comparator returned `Equal`, or `None` if
+     * not found.
+     */
+    fn bsearch(&self, f: |&T| -> Ordering) -> Option<uint>;
+
+    /// Deprecated, use iterators where possible
+    /// (`self.iter().map(f)`). Apply a function to each element
+    /// of a vector and return the results.
+    fn map<U>(&self, |t: &T| -> U) -> ~[U];
+
+    /**
+     * Returns a mutable reference to the first element in this slice
+     * and adjusts the slice in place so that it no longer contains
+     * that element. O(1).
+     *
+     * Equivalent to:
+     *
+     * ```ignore
+     *     if self.len() == 0 { return None }
+     *     let head = &self[0];
+     *     *self = self.slice_from(1);
+     *     Some(head)
+     * ```
+     *
+     * Returns `None` if vector is empty
+     */
+    fn shift_ref(&mut self) -> Option<&'a T>;
+
+    /**
+     * Returns a mutable reference to the last element in this slice
+     * and adjusts the slice in place so that it no longer contains
+     * that element. O(1).
+     *
+     * Equivalent to:
+     *
+     * ```ignore
+     *     if self.len() == 0 { return None; }
+     *     let tail = &self[self.len() - 1];
+     *     *self = self.slice_to(self.len() - 1);
+     *     Some(tail)
+     * ```
+     *
+     * Returns `None` if slice is empty.
+     */
+    fn pop_ref(&mut self) -> Option<&'a T>;
+}
+
+impl<'a,T> ImmutableVector<'a, T> for &'a [T] {
+    #[inline]
+    fn slice(&self, start: uint, end: uint) -> &'a [T] {
+        assert!(start <= end);
+        assert!(end <= self.len());
+        unsafe {
+            transmute(Slice {
+                    data: self.as_ptr().offset(start as int),
+                    len: (end - start)
+                })
+        }
+    }
+
+    #[inline]
+    fn slice_from(&self, start: uint) -> &'a [T] {
+        self.slice(start, self.len())
+    }
+
+    #[inline]
+    fn slice_to(&self, end: uint) -> &'a [T] {
+        self.slice(0, end)
+    }
+
+    #[inline]
+    fn iter(self) -> Items<'a, T> {
+        unsafe {
+            let p = self.as_ptr();
+            if mem::size_of::<T>() == 0 {
+                Items{ptr: p,
+                      end: (p as uint + self.len()) as *T,
+                      marker: marker::ContravariantLifetime::<'a>}
+            } else {
+                Items{ptr: p,
+                      end: p.offset(self.len() as int),
+                      marker: marker::ContravariantLifetime::<'a>}
+            }
+        }
+    }
+
+    #[inline]
+    fn rev_iter(self) -> RevItems<'a, T> {
+        self.iter().rev()
+    }
+
+    #[inline]
+    fn split(self, pred: 'a |&T| -> bool) -> Splits<'a, T> {
+        self.splitn(uint::MAX, pred)
+    }
+
+    #[inline]
+    fn splitn(self, n: uint, pred: 'a |&T| -> bool) -> Splits<'a, T> {
+        Splits {
+            v: self,
+            n: n,
+            pred: pred,
+            finished: false
+        }
+    }
+
+    #[inline]
+    fn rsplit(self, pred: 'a |&T| -> bool) -> RevSplits<'a, T> {
+        self.rsplitn(uint::MAX, pred)
+    }
+
+    #[inline]
+    fn rsplitn(self, n: uint, pred: 'a |&T| -> bool) -> RevSplits<'a, T> {
+        RevSplits {
+            v: self,
+            n: n,
+            pred: pred,
+            finished: false
+        }
+    }
+
+    #[inline]
+    fn windows(self, size: uint) -> Windows<'a, T> {
+        assert!(size != 0);
+        Windows { v: self, size: size }
+    }
+
+    #[inline]
+    fn chunks(self, size: uint) -> Chunks<'a, T> {
+        assert!(size != 0);
+        Chunks { v: self, size: size }
+    }
+
+    #[inline]
+    fn get(&self, index: uint) -> Option<&'a T> {
+        if index < self.len() { Some(&self[index]) } else { None }
+    }
+
+    #[inline]
+    fn head(&self) -> Option<&'a T> {
+        if self.len() == 0 { None } else { Some(&self[0]) }
+    }
+
+    #[inline]
+    fn tail(&self) -> &'a [T] { self.slice(1, self.len()) }
+
+    #[inline]
+    fn tailn(&self, n: uint) -> &'a [T] { self.slice(n, self.len()) }
+
+    #[inline]
+    fn init(&self) -> &'a [T] {
+        self.slice(0, self.len() - 1)
+    }
+
+    #[inline]
+    fn initn(&self, n: uint) -> &'a [T] {
+        self.slice(0, self.len() - n)
+    }
+
+    #[inline]
+    fn last(&self) -> Option<&'a T> {
+            if self.len() == 0 { None } else { Some(&self[self.len() - 1]) }
+    }
+
+    #[inline]
+    fn flat_map<U>(&self, f: |t: &T| -> ~[U]) -> ~[U] {
+        flat_map(*self, f)
+    }
+
+    #[inline]
+    unsafe fn unsafe_ref(self, index: uint) -> &'a T {
+        transmute(self.repr().data.offset(index as int))
+    }
+
+    #[inline]
+    fn as_ptr(&self) -> *T {
+        self.repr().data
+    }
+
+
+    fn bsearch(&self, f: |&T| -> Ordering) -> Option<uint> {
+        let mut base : uint = 0;
+        let mut lim : uint = self.len();
+
+        while lim != 0 {
+            let ix = base + (lim >> 1);
+            match f(&self[ix]) {
+                Equal => return Some(ix),
+                Less => {
+                    base = ix + 1;
+                    lim -= 1;
+                }
+                Greater => ()
+            }
+            lim >>= 1;
+        }
+        return None;
+    }
+
+    fn map<U>(&self, f: |t: &T| -> U) -> ~[U] {
+        self.iter().map(f).collect()
+    }
+
+    fn shift_ref(&mut self) -> Option<&'a T> {
+        if self.len() == 0 { return None; }
+        unsafe {
+            let s: &mut Slice<T> = transmute(self);
+            Some(&*raw::shift_ptr(s))
+        }
+    }
+
+    fn pop_ref(&mut self) -> Option<&'a T> {
+        if self.len() == 0 { return None; }
+        unsafe {
+            let s: &mut Slice<T> = transmute(self);
+            Some(&*raw::pop_ptr(s))
+        }
+    }
+}
+
+/// Extension methods for vectors contain `Eq` elements.
+pub trait ImmutableEqVector<T:Eq> {
+    /// Find the first index containing a matching value
+    fn position_elem(&self, t: &T) -> Option<uint>;
+
+    /// Find the last index containing a matching value
+    fn rposition_elem(&self, t: &T) -> Option<uint>;
+
+    /// Return true if a vector contains an element with the given value
+    fn contains(&self, x: &T) -> bool;
+
+    /// Returns true if `needle` is a prefix of the vector.
+    fn starts_with(&self, needle: &[T]) -> bool;
+
+    /// Returns true if `needle` is a suffix of the vector.
+    fn ends_with(&self, needle: &[T]) -> bool;
+}
+
+impl<'a,T:Eq> ImmutableEqVector<T> for &'a [T] {
+    #[inline]
+    fn position_elem(&self, x: &T) -> Option<uint> {
+        self.iter().position(|y| *x == *y)
+    }
+
+    #[inline]
+    fn rposition_elem(&self, t: &T) -> Option<uint> {
+        self.iter().rposition(|x| *x == *t)
+    }
+
+    #[inline]
+    fn contains(&self, x: &T) -> bool {
+        self.iter().any(|elt| *x == *elt)
+    }
+
+    #[inline]
+    fn starts_with(&self, needle: &[T]) -> bool {
+        let n = needle.len();
+        self.len() >= n && needle == self.slice_to(n)
+    }
+
+    #[inline]
+    fn ends_with(&self, needle: &[T]) -> bool {
+        let (m, n) = (self.len(), needle.len());
+        m >= n && needle == self.slice_from(m - n)
+    }
+}
+
+/// Extension methods for vectors containing `TotalOrd` elements.
+pub trait ImmutableTotalOrdVector<T: TotalOrd> {
+    /**
+     * Binary search a sorted vector for a given element.
+     *
+     * Returns the index of the element or None if not found.
+     */
+    fn bsearch_elem(&self, x: &T) -> Option<uint>;
+}
+
+impl<'a, T: TotalOrd> ImmutableTotalOrdVector<T> for &'a [T] {
+    fn bsearch_elem(&self, x: &T) -> Option<uint> {
+        self.bsearch(|p| p.cmp(x))
+    }
+}
+
+/// Extension methods for vectors containing `Clone` elements.
+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]);
+
+    /// Create an iterator that yields every possible permutation of the
+    /// vector in succession.
+    fn permutations(self) -> Permutations<T>;
+}
+
+impl<'a,T:Clone> ImmutableCloneableVector<T> for &'a [T] {
+    #[inline]
+    fn partitioned(&self, f: |&T| -> bool) -> (~[T], ~[T]) {
+        let mut lefts  = ~[];
+        let mut rights = ~[];
+
+        for elt in self.iter() {
+            if f(elt) {
+                lefts.push((*elt).clone());
+            } else {
+                rights.push((*elt).clone());
+            }
+        }
+
+        (lefts, rights)
+    }
+
+    fn permutations(self) -> Permutations<T> {
+        Permutations{
+            swaps: ElementSwaps::new(self.len()),
+            v: self.to_owned(),
+        }
+    }
+
+}
+
+/// Extension methods for owned vectors.
+pub trait OwnedVector<T> {
+    /// Creates a consuming iterator, that is, one that moves each
+    /// value out of the vector (from start to end). The vector cannot
+    /// be used after calling this.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// let v = ~[~"a", ~"b"];
+    /// for s in v.move_iter() {
+    ///   // s has type ~str, not &~str
+    ///   println!("{}", s);
+    /// }
+    /// ```
+    fn move_iter(self) -> MoveItems<T>;
+    /// Creates a consuming iterator that moves out of the vector in
+    /// reverse order.
+    fn move_rev_iter(self) -> RevMoveItems<T>;
+
+    /**
+     * Reserves capacity for exactly `n` elements in the given vector.
+     *
+     * If the capacity for `self` is already equal to or greater than the requested
+     * capacity, then no action is taken.
+     *
+     * # Arguments
+     *
+     * * n - The number of elements to reserve space for
+     *
+     * # Failure
+     *
+     * This method always succeeds in reserving space for `n` elements, or it does
+     * not return.
+     */
+    fn reserve_exact(&mut self, n: uint);
+    /**
+     * Reserves capacity for at least `n` elements in the given vector.
+     *
+     * This function will over-allocate in order to amortize the allocation costs
+     * in scenarios where the caller may need to repeatedly reserve additional
+     * space.
+     *
+     * If the capacity for `self` is already equal to or greater than the requested
+     * capacity, then no action is taken.
+     *
+     * # Arguments
+     *
+     * * n - The number of elements to reserve space for
+     */
+    fn reserve(&mut self, n: uint);
+    /**
+     * Reserves capacity for at least `n` additional elements in the given vector.
+     *
+     * # Failure
+     *
+     * Fails if the new required capacity overflows uint.
+     *
+     * May also fail if `reserve` fails.
+     */
+    fn reserve_additional(&mut self, n: uint);
+    /// Returns the number of elements the vector can hold without reallocating.
+    fn capacity(&self) -> uint;
+    /// Shrink the capacity of the vector to match the length
+    fn shrink_to_fit(&mut self);
+
+    /// Append an element to a vector
+    fn push(&mut self, t: T);
+    /// Takes ownership of the vector `rhs`, moving all elements into
+    /// the current vector. This does not copy any elements, and it is
+    /// illegal to use the `rhs` vector after calling this method
+    /// (because it is moved here).
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut a = ~[~1];
+    /// a.push_all_move(~[~2, ~3, ~4]);
+    /// assert!(a == ~[~1, ~2, ~3, ~4]);
+    /// ```
+    fn push_all_move(&mut self, rhs: ~[T]);
+    /// Remove the last element from a vector and return it, or `None` if it is empty
+    fn pop(&mut self) -> Option<T>;
+    /// Removes the first element from a vector and return it, or `None` if it is empty
+    fn shift(&mut self) -> Option<T>;
+    /// Prepend an element to the vector
+    fn unshift(&mut self, x: T);
+
+    /// Insert an element at position i within v, shifting all
+    /// elements after position i one position to the right.
+    fn insert(&mut self, i: uint, x:T);
+
+    /// Remove and return the element at position `i` within `v`,
+    /// shifting all elements after position `i` one position to the
+    /// left. Returns `None` if `i` is out of bounds.
+    ///
+    /// # Example
+    /// ```rust
+    /// let mut v = ~[1, 2, 3];
+    /// assert_eq!(v.remove(1), Some(2));
+    /// assert_eq!(v, ~[1, 3]);
+    ///
+    /// assert_eq!(v.remove(4), None);
+    /// // v is unchanged:
+    /// assert_eq!(v, ~[1, 3]);
+    /// ```
+    fn remove(&mut self, i: uint) -> Option<T>;
+
+    /// Remove an element from anywhere in the vector and return it, replacing it
+    /// with the last element. This does not preserve ordering, but is O(1).
+    ///
+    /// Returns `None` if `index` is out of bounds.
+    ///
+    /// # Example
+    /// ```rust
+    /// let mut v = ~[~"foo", ~"bar", ~"baz", ~"qux"];
+    ///
+    /// assert_eq!(v.swap_remove(1), Some(~"bar"));
+    /// assert_eq!(v, ~[~"foo", ~"qux", ~"baz"]);
+    ///
+    /// assert_eq!(v.swap_remove(0), Some(~"foo"));
+    /// assert_eq!(v, ~[~"baz", ~"qux"]);
+    ///
+    /// assert_eq!(v.swap_remove(2), None);
+    /// ```
+    fn swap_remove(&mut self, index: uint) -> Option<T>;
+
+    /// Shorten a vector, dropping excess elements.
+    fn truncate(&mut self, newlen: uint);
+
+    /**
+     * Like `filter()`, but in place.  Preserves order of `v`.  Linear time.
+     */
+    fn retain(&mut self, f: |t: &T| -> bool);
+
+    /**
+     * 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]);
+
+    /**
+     * Expands a vector in place, initializing the new elements to the result of
+     * a function.
+     *
+     * Function `init_op` is called `n` times with the values [0..`n`)
+     *
+     * # Arguments
+     *
+     * * n - The number of elements to add
+     * * init_op - A function to call to retrieve each appended element's
+     *             value
+     */
+    fn grow_fn(&mut self, n: uint, op: |uint| -> T);
+
+    /**
+     * Sets the length of a vector
+     *
+     * This will explicitly set the size of the vector, without actually
+     * modifying its buffers, so it is up to the caller to ensure that
+     * the vector is actually the specified size.
+     */
+    unsafe fn set_len(&mut self, new_len: uint);
+}
+
+impl<T> OwnedVector<T> for ~[T] {
+    #[inline]
+    fn move_iter(self) -> MoveItems<T> {
+        unsafe {
+            let iter = transmute(self.iter());
+            let ptr = transmute(self);
+            MoveItems { allocation: ptr, iter: iter }
+        }
+    }
+
+    #[inline]
+    fn move_rev_iter(self) -> RevMoveItems<T> {
+        self.move_iter().rev()
+    }
+
+    fn reserve_exact(&mut self, n: uint) {
+        // Only make the (slow) call into the runtime if we have to
+        if self.capacity() < n {
+            unsafe {
+                let ptr: *mut *mut Vec<()> = transmute(self);
+                let alloc = n * mem::nonzero_size_of::<T>();
+                let size = alloc + mem::size_of::<Vec<()>>();
+                if alloc / mem::nonzero_size_of::<T>() != n || size < alloc {
+                    fail!("vector size is too large: {}", n);
+                }
+                *ptr = realloc_raw(*ptr as *mut u8, size)
+                                   as *mut Vec<()>;
+                (**ptr).alloc = alloc;
+            }
+        }
+    }
+
+    #[inline]
+    fn reserve(&mut self, n: uint) {
+        self.reserve_exact(checked_next_power_of_two(n).unwrap_or(n));
+    }
+
+    #[inline]
+    fn reserve_additional(&mut self, n: uint) {
+        if self.capacity() - self.len() < n {
+            match self.len().checked_add(&n) {
+                None => fail!("slice::reserve_additional: `uint` overflow"),
+                Some(new_cap) => self.reserve(new_cap)
+            }
+        }
+    }
+
+    #[inline]
+    fn capacity(&self) -> uint {
+        unsafe {
+            let repr: **Vec<()> = transmute(self);
+            (**repr).alloc / mem::nonzero_size_of::<T>()
+        }
+    }
+
+    fn shrink_to_fit(&mut self) {
+        unsafe {
+            let ptr: *mut *mut Vec<()> = transmute(self);
+            let alloc = (**ptr).fill;
+            let size = alloc + mem::size_of::<Vec<()>>();
+            *ptr = realloc_raw(*ptr as *mut u8, size) as *mut Vec<()>;
+            (**ptr).alloc = alloc;
+        }
+    }
+
+    #[inline]
+    fn push(&mut self, t: T) {
+        unsafe {
+            let repr: **Vec<()> = transmute(&mut *self);
+            let fill = (**repr).fill;
+            if (**repr).alloc <= fill {
+                self.reserve_additional(1);
+            }
+
+            push_fast(self, t);
+        }
+
+        // This doesn't bother to make sure we have space.
+        #[inline] // really pretty please
+        unsafe fn push_fast<T>(this: &mut ~[T], t: T) {
+            let repr: **mut Vec<u8> = transmute(this);
+            let fill = (**repr).fill;
+            (**repr).fill += mem::nonzero_size_of::<T>();
+            let p = &((**repr).data) as *u8;
+            let p = p.offset(fill as int) as *mut T;
+            mem::move_val_init(&mut(*p), t);
+        }
+    }
+
+    #[inline]
+    fn push_all_move(&mut self, mut rhs: ~[T]) {
+        let self_len = self.len();
+        let rhs_len = rhs.len();
+        let new_len = self_len + rhs_len;
+        self.reserve_additional(rhs.len());
+        unsafe { // Note: infallible.
+            let self_p = self.as_mut_ptr();
+            let rhs_p = rhs.as_ptr();
+            ptr::copy_memory(self_p.offset(self_len as int), rhs_p, rhs_len);
+            self.set_len(new_len);
+            rhs.set_len(0);
+        }
+    }
+
+    fn pop(&mut self) -> Option<T> {
+        match self.len() {
+            0  => None,
+            ln => {
+                let valptr = &mut self[ln - 1u] as *mut T;
+                unsafe {
+                    self.set_len(ln - 1u);
+                    Some(ptr::read(&*valptr))
+                }
+            }
+        }
+    }
+
+
+    #[inline]
+    fn shift(&mut self) -> Option<T> {
+        self.remove(0)
+    }
+
+    #[inline]
+    fn unshift(&mut self, x: T) {
+        self.insert(0, x)
+    }
+
+    fn insert(&mut self, i: uint, x: T) {
+        let len = self.len();
+        assert!(i <= len);
+        // space for the new element
+        self.reserve_additional(1);
+
+        unsafe { // infallible
+            // The spot to put the new value
+            let p = self.as_mut_ptr().offset(i as int);
+            // Shift everything over to make space. (Duplicating the
+            // `i`th element into two consecutive places.)
+            ptr::copy_memory(p.offset(1), &*p, len - i);
+            // Write it in, overwriting the first copy of the `i`th
+            // element.
+            mem::move_val_init(&mut *p, x);
+            self.set_len(len + 1);
+        }
+    }
+
+    fn remove(&mut self, i: uint) -> Option<T> {
+        let len = self.len();
+        if i < len {
+            unsafe { // infallible
+                // the place we are taking from.
+                let ptr = self.as_mut_ptr().offset(i as int);
+                // copy it out, unsafely having a copy of the value on
+                // the stack and in the vector at the same time.
+                let ret = Some(ptr::read(ptr as *T));
+
+                // Shift everything down to fill in that spot.
+                ptr::copy_memory(ptr, &*ptr.offset(1), len - i - 1);
+                self.set_len(len - 1);
+
+                ret
+            }
+        } else {
+            None
+        }
+    }
+    fn swap_remove(&mut self, index: uint) -> Option<T> {
+        let ln = self.len();
+        if index < ln - 1 {
+            self.swap(index, ln - 1);
+        } else if index >= ln {
+            return None
+        }
+        self.pop()
+    }
+    fn truncate(&mut self, newlen: uint) {
+        let oldlen = self.len();
+        assert!(newlen <= oldlen);
+
+        unsafe {
+            let p = self.as_mut_ptr();
+            // This loop is optimized out for non-drop types.
+            for i in range(newlen, oldlen) {
+                ptr::read_and_zero(p.offset(i as int));
+            }
+        }
+        unsafe { self.set_len(newlen); }
+    }
+
+    fn retain(&mut self, f: |t: &T| -> bool) {
+        let len = self.len();
+        let mut deleted: uint = 0;
+
+        for i in range(0u, len) {
+            if !f(&self[i]) {
+                deleted += 1;
+            } else if deleted > 0 {
+                self.swap(i - deleted, i);
+            }
+        }
+
+        if deleted > 0 {
+            self.truncate(len - deleted);
+        }
+    }
+
+    #[inline]
+    fn partition(self, f: |&T| -> bool) -> (~[T], ~[T]) {
+        let mut lefts  = ~[];
+        let mut rights = ~[];
+
+        for elt in self.move_iter() {
+            if f(&elt) {
+                lefts.push(elt);
+            } else {
+                rights.push(elt);
+            }
+        }
+
+        (lefts, rights)
+    }
+    fn grow_fn(&mut self, n: uint, op: |uint| -> T) {
+        let new_len = self.len() + n;
+        self.reserve(new_len);
+        let mut i: uint = 0u;
+        while i < n {
+            self.push(op(i));
+            i += 1u;
+        }
+    }
+
+    #[inline]
+    unsafe fn set_len(&mut self, new_len: uint) {
+        let repr: **mut Vec<()> = transmute(self);
+        (**repr).fill = new_len * mem::nonzero_size_of::<T>();
+    }
+}
+
+impl<T> Mutable for ~[T] {
+    /// Clear the vector, removing all values.
+    fn clear(&mut self) { self.truncate(0) }
+}
+
+/// Extension methods for owned vectors containing `Clone` elements.
+pub trait OwnedCloneableVector<T:Clone> {
+    /// Iterates over the slice `rhs`, copies each element, and then appends it to
+    /// the vector provided `v`. The `rhs` vector is traversed in-order.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut a = ~[1];
+    /// a.push_all([2, 3, 4]);
+    /// assert!(a == ~[1, 2, 3, 4]);
+    /// ```
+    fn push_all(&mut self, rhs: &[T]);
+
+    /**
+     * Expands a vector in place, initializing the new elements to a given value
+     *
+     * # Arguments
+     *
+     * * n - The number of elements to add
+     * * initval - The value for the new elements
+     */
+    fn grow(&mut self, n: uint, initval: &T);
+
+    /**
+     * Sets the value of a vector element at a given index, growing the vector as
+     * needed
+     *
+     * Sets the element at position `index` to `val`. If `index` is past the end
+     * of the vector, expands the vector by replicating `initval` to fill the
+     * intervening space.
+     */
+    fn grow_set(&mut self, index: uint, initval: &T, val: T);
+}
+
+impl<T:Clone> OwnedCloneableVector<T> for ~[T] {
+    #[inline]
+    fn push_all(&mut self, rhs: &[T]) {
+        let new_len = self.len() + rhs.len();
+        self.reserve_exact(new_len);
+
+        for elt in rhs.iter() {
+            self.push((*elt).clone())
+        }
+    }
+    fn grow(&mut self, n: uint, initval: &T) {
+        let new_len = self.len() + n;
+        self.reserve(new_len);
+        let mut i: uint = 0u;
+
+        while i < n {
+            self.push((*initval).clone());
+            i += 1u;
+        }
+    }
+    fn grow_set(&mut self, index: uint, initval: &T, val: T) {
+        let l = self.len();
+        if index >= l { self.grow(index - l + 1u, initval); }
+        self[index] = val;
+    }
+}
+
+/// Extension methods for owned vectors containing `Eq` elements.
+pub trait OwnedEqVector<T:Eq> {
+    /**
+    * Remove consecutive repeated elements from a vector; if the vector is
+    * sorted, this removes all duplicates.
+    */
+    fn dedup(&mut self);
+}
+
+impl<T:Eq> OwnedEqVector<T> for ~[T] {
+    fn dedup(&mut self) {
+        unsafe {
+            // Although we have a mutable reference to `self`, we cannot make
+            // *arbitrary* changes. The `Eq` comparisons could fail, so we
+            // must ensure that the vector is in a valid state at all time.
+            //
+            // The way that we handle this is by using swaps; we iterate
+            // over all the elements, swapping as we go so that at the end
+            // the elements we wish to keep are in the front, and those we
+            // wish to reject are at the back. We can then truncate the
+            // vector. This operation is still O(n).
+            //
+            // Example: We start in this state, where `r` represents "next
+            // read" and `w` represents "next_write`.
+            //
+            //           r
+            //     +---+---+---+---+---+---+
+            //     | 0 | 1 | 1 | 2 | 3 | 3 |
+            //     +---+---+---+---+---+---+
+            //           w
+            //
+            // Comparing self[r] against self[w-1], tis is not a duplicate, so
+            // we swap self[r] and self[w] (no effect as r==w) and then increment both
+            // r and w, leaving us with:
+            //
+            //               r
+            //     +---+---+---+---+---+---+
+            //     | 0 | 1 | 1 | 2 | 3 | 3 |
+            //     +---+---+---+---+---+---+
+            //               w
+            //
+            // Comparing self[r] against self[w-1], this value is a duplicate,
+            // so we increment `r` but leave everything else unchanged:
+            //
+            //                   r
+            //     +---+---+---+---+---+---+
+            //     | 0 | 1 | 1 | 2 | 3 | 3 |
+            //     +---+---+---+---+---+---+
+            //               w
+            //
+            // Comparing self[r] against self[w-1], this is not a duplicate,
+            // so swap self[r] and self[w] and advance r and w:
+            //
+            //                       r
+            //     +---+---+---+---+---+---+
+            //     | 0 | 1 | 2 | 1 | 3 | 3 |
+            //     +---+---+---+---+---+---+
+            //                   w
+            //
+            // Not a duplicate, repeat:
+            //
+            //                           r
+            //     +---+---+---+---+---+---+
+            //     | 0 | 1 | 2 | 3 | 1 | 3 |
+            //     +---+---+---+---+---+---+
+            //                       w
+            //
+            // Duplicate, advance r. End of vec. Truncate to w.
+
+            let ln = self.len();
+            if ln < 1 { return; }
+
+            // Avoid bounds checks by using unsafe pointers.
+            let p = self.as_mut_ptr();
+            let mut r = 1;
+            let mut w = 1;
+
+            while r < ln {
+                let p_r = p.offset(r as int);
+                let p_wm1 = p.offset((w - 1) as int);
+                if *p_r != *p_wm1 {
+                    if r != w {
+                        let p_w = p_wm1.offset(1);
+                        mem::swap(&mut *p_r, &mut *p_w);
+                    }
+                    w += 1;
+                }
+                r += 1;
+            }
+
+            self.truncate(w);
+        }
+    }
+}
+
+fn insertion_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
+    let len = v.len() as int;
+    let buf_v = v.as_mut_ptr();
+
+    // 1 <= i < len;
+    for i in range(1, len) {
+        // j satisfies: 0 <= j <= i;
+        let mut j = i;
+        unsafe {
+            // `i` is in bounds.
+            let read_ptr = buf_v.offset(i) as *T;
+
+            // find where to insert, we need to do strict <,
+            // rather than <=, to maintain stability.
+
+            // 0 <= j - 1 < len, so .offset(j - 1) is in bounds.
+            while j > 0 &&
+                    compare(&*read_ptr, &*buf_v.offset(j - 1)) == Less {
+                j -= 1;
+            }
+
+            // shift everything to the right, to make space to
+            // insert this value.
+
+            // j + 1 could be `len` (for the last `i`), but in
+            // that case, `i == j` so we don't copy. The
+            // `.offset(j)` is always in bounds.
+
+            if i != j {
+                let tmp = ptr::read(read_ptr);
+                ptr::copy_memory(buf_v.offset(j + 1),
+                                 &*buf_v.offset(j),
+                                 (i - j) as uint);
+                ptr::copy_nonoverlapping_memory(buf_v.offset(j),
+                                                &tmp as *T,
+                                                1);
+                cast::forget(tmp);
+            }
+        }
+    }
+}
+
+fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
+    // warning: this wildly uses unsafe.
+    static BASE_INSERTION: uint = 32;
+    static LARGE_INSERTION: uint = 16;
+
+    // FIXME #12092: smaller insertion runs seems to make sorting
+    // vectors of large elements a little faster on some platforms,
+    // but hasn't been tested/tuned extensively
+    let insertion = if size_of::<T>() <= 16 {
+        BASE_INSERTION
+    } else {
+        LARGE_INSERTION
+    };
+
+    let len = v.len();
+
+    // short vectors get sorted in-place via insertion sort to avoid allocations
+    if len <= insertion {
+        insertion_sort(v, compare);
+        return;
+    }
+
+    // allocate some memory to use as scratch memory, we keep the
+    // length 0 so we can keep shallow copies of the contents of `v`
+    // without risking the dtors running on an object twice if
+    // `compare` fails.
+    let mut working_space = with_capacity(2 * len);
+    // these both are buffers of length `len`.
+    let mut buf_dat = working_space.as_mut_ptr();
+    let mut buf_tmp = unsafe {buf_dat.offset(len as int)};
+
+    // length `len`.
+    let buf_v = v.as_ptr();
+
+    // step 1. sort short runs with insertion sort. This takes the
+    // values from `v` and sorts them into `buf_dat`, leaving that
+    // with sorted runs of length INSERTION.
+
+    // We could hardcode the sorting comparisons here, and we could
+    // manipulate/step the pointers themselves, rather than repeatedly
+    // .offset-ing.
+    for start in range_step(0, len, insertion) {
+        // start <= i < len;
+        for i in range(start, cmp::min(start + insertion, len)) {
+            // j satisfies: start <= j <= i;
+            let mut j = i as int;
+            unsafe {
+                // `i` is in bounds.
+                let read_ptr = buf_v.offset(i as int);
+
+                // find where to insert, we need to do strict <,
+                // rather than <=, to maintain stability.
+
+                // start <= j - 1 < len, so .offset(j - 1) is in
+                // bounds.
+                while j > start as int &&
+                        compare(&*read_ptr, &*buf_dat.offset(j - 1)) == Less {
+                    j -= 1;
+                }
+
+                // shift everything to the right, to make space to
+                // insert this value.
+
+                // j + 1 could be `len` (for the last `i`), but in
+                // that case, `i == j` so we don't copy. The
+                // `.offset(j)` is always in bounds.
+                ptr::copy_memory(buf_dat.offset(j + 1),
+                                 &*buf_dat.offset(j),
+                                 i - j as uint);
+                ptr::copy_nonoverlapping_memory(buf_dat.offset(j), read_ptr, 1);
+            }
+        }
+    }
+
+    // step 2. merge the sorted runs.
+    let mut width = insertion;
+    while width < len {
+        // merge the sorted runs of length `width` in `buf_dat` two at
+        // a time, placing the result in `buf_tmp`.
+
+        // 0 <= start <= len.
+        for start in range_step(0, len, 2 * width) {
+            // manipulate pointers directly for speed (rather than
+            // using a `for` loop with `range` and `.offset` inside
+            // that loop).
+            unsafe {
+                // the end of the first run & start of the
+                // second. Offset of `len` is defined, since this is
+                // precisely one byte past the end of the object.
+                let right_start = buf_dat.offset(cmp::min(start + width, len) as int);
+                // end of the second. Similar reasoning to the above re safety.
+                let right_end_idx = cmp::min(start + 2 * width, len);
+                let right_end = buf_dat.offset(right_end_idx as int);
+
+                // the pointers to the elements under consideration
+                // from the two runs.
+
+                // both of these are in bounds.
+                let mut left = buf_dat.offset(start as int);
+                let mut right = right_start;
+
+                // where we're putting the results, it is a run of
+                // length `2*width`, so we step it once for each step
+                // of either `left` or `right`.  `buf_tmp` has length
+                // `len`, so these are in bounds.
+                let mut out = buf_tmp.offset(start as int);
+                let out_end = buf_tmp.offset(right_end_idx as int);
+
+                while out < out_end {
+                    // Either the left or the right run are exhausted,
+                    // so just copy the remainder from the other run
+                    // and move on; this gives a huge speed-up (order
+                    // of 25%) for mostly sorted vectors (the best
+                    // case).
+                    if left == right_start {
+                        // the number remaining in this run.
+                        let elems = (right_end as uint - right as uint) / mem::size_of::<T>();
+                        ptr::copy_nonoverlapping_memory(out, &*right, elems);
+                        break;
+                    } else if right == right_end {
+                        let elems = (right_start as uint - left as uint) / mem::size_of::<T>();
+                        ptr::copy_nonoverlapping_memory(out, &*left, elems);
+                        break;
+                    }
+
+                    // check which side is smaller, and that's the
+                    // next element for the new run.
+
+                    // `left < right_start` and `right < right_end`,
+                    // so these are valid.
+                    let to_copy = if compare(&*left, &*right) == Greater {
+                        step(&mut right)
+                    } else {
+                        step(&mut left)
+                    };
+                    ptr::copy_nonoverlapping_memory(out, &*to_copy, 1);
+                    step(&mut out);
+                }
+            }
+        }
+
+        mem::swap(&mut buf_dat, &mut buf_tmp);
+
+        width *= 2;
+    }
+
+    // write the result to `v` in one go, so that there are never two copies
+    // of the same object in `v`.
+    unsafe {
+        ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), &*buf_dat, len);
+    }
+
+    // increment the pointer, returning the old pointer.
+    #[inline(always)]
+    unsafe fn step<T>(ptr: &mut *mut T) -> *mut T {
+        let old = *ptr;
+        *ptr = ptr.offset(1);
+        old
+    }
+}
+
+/// Extension methods for vectors such that their elements are
+/// mutable.
+pub trait MutableVector<'a, T> {
+    /// Work with `self` as a mut slice.
+    /// Primarily intended for getting a &mut [T] from a [T, ..N].
+    fn as_mut_slice(self) -> &'a mut [T];
+
+    /// Return a slice that points into another slice.
+    fn mut_slice(self, start: uint, end: uint) -> &'a mut [T];
+
+    /**
+     * Returns a slice of self from `start` to the end of the vec.
+     *
+     * Fails when `start` points outside the bounds of self.
+     */
+    fn mut_slice_from(self, start: uint) -> &'a mut [T];
+
+    /**
+     * Returns a slice of self from the start of the vec to `end`.
+     *
+     * Fails when `end` points outside the bounds of self.
+     */
+    fn mut_slice_to(self, end: uint) -> &'a mut [T];
+
+    /// Returns an iterator that allows modifying each value
+    fn mut_iter(self) -> MutItems<'a, T>;
+
+    /// Returns a mutable pointer to the last item in the vector.
+    fn mut_last(self) -> Option<&'a mut T>;
+
+    /// Returns a reversed iterator that allows modifying each value
+    fn mut_rev_iter(self) -> RevMutItems<'a, T>;
+
+    /// Returns an iterator over the mutable subslices of the vector
+    /// which are separated by elements that match `pred`.  The
+    /// matched element is not contained in the subslices.
+    fn mut_split(self, pred: 'a |&T| -> bool) -> MutSplits<'a, T>;
+
+    /**
+     * Returns an iterator over `size` elements of the vector at a time.
+     * The chunks are mutable and do not overlap. If `size` does not divide the
+     * length of the vector, then the last chunk will not have length
+     * `size`.
+     *
+     * # Failure
+     *
+     * Fails if `size` is 0.
+     */
+    fn mut_chunks(self, chunk_size: uint) -> MutChunks<'a, T>;
+
+    /**
+     * Returns a mutable reference to the first element in this slice
+     * and adjusts the slice in place so that it no longer contains
+     * that element. O(1).
+     *
+     * Equivalent to:
+     *
+     * ```ignore
+     *     if self.len() == 0 { return None; }
+     *     let head = &mut self[0];
+     *     *self = self.mut_slice_from(1);
+     *     Some(head)
+     * ```
+     *
+     * Returns `None` if slice is empty
+     */
+    fn mut_shift_ref(&mut self) -> Option<&'a mut T>;
+
+    /**
+     * Returns a mutable reference to the last element in this slice
+     * and adjusts the slice in place so that it no longer contains
+     * that element. O(1).
+     *
+     * Equivalent to:
+     *
+     * ```ignore
+     *     if self.len() == 0 { return None; }
+     *     let tail = &mut self[self.len() - 1];
+     *     *self = self.mut_slice_to(self.len() - 1);
+     *     Some(tail)
+     * ```
+     *
+     * Returns `None` if slice is empty.
+     */
+    fn mut_pop_ref(&mut self) -> Option<&'a mut T>;
+
+    /// Swaps two elements in a vector.
+    ///
+    /// Fails if `a` or `b` are out of bounds.
+    ///
+    /// # Arguments
+    ///
+    /// * a - The index of the first element
+    /// * b - The index of the second element
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = ["a", "b", "c", "d"];
+    /// v.swap(1, 3);
+    /// assert!(v == ["a", "d", "c", "b"]);
+    /// ```
+    fn swap(self, a: uint, b: uint);
+
+
+    /// Divides one `&mut` into two at an index.
+    ///
+    /// The first will contain all indices from `[0, mid)` (excluding
+    /// the index `mid` itself) and the second will contain all
+    /// indices from `[mid, len)` (excluding the index `len` itself).
+    ///
+    /// Fails if `mid > len`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = [1, 2, 3, 4, 5, 6];
+    ///
+    /// // scoped to restrict the lifetime of the borrows
+    /// {
+    ///    let (left, right) = v.mut_split_at(0);
+    ///    assert!(left == &mut []);
+    ///    assert!(right == &mut [1, 2, 3, 4, 5, 6]);
+    /// }
+    ///
+    /// {
+    ///     let (left, right) = v.mut_split_at(2);
+    ///     assert!(left == &mut [1, 2]);
+    ///     assert!(right == &mut [3, 4, 5, 6]);
+    /// }
+    ///
+    /// {
+    ///     let (left, right) = v.mut_split_at(6);
+    ///     assert!(left == &mut [1, 2, 3, 4, 5, 6]);
+    ///     assert!(right == &mut []);
+    /// }
+    /// ```
+    fn mut_split_at(self, mid: uint) -> (&'a mut [T], &'a mut [T]);
+
+    /// Reverse the order of elements in a vector, in place.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = [1, 2, 3];
+    /// v.reverse();
+    /// assert!(v == [3, 2, 1]);
+    /// ```
+    fn reverse(self);
+
+    /// Sort the vector, in place, using `compare` to compare
+    /// elements.
+    ///
+    /// This sort is `O(n log n)` worst-case and stable, but allocates
+    /// approximately `2 * n`, where `n` is the length of `self`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = [5i, 4, 1, 3, 2];
+    /// v.sort_by(|a, b| a.cmp(b));
+    /// assert!(v == [1, 2, 3, 4, 5]);
+    ///
+    /// // reverse sorting
+    /// v.sort_by(|a, b| b.cmp(a));
+    /// assert!(v == [5, 4, 3, 2, 1]);
+    /// ```
+    fn sort_by(self, compare: |&T, &T| -> Ordering);
+
+    /**
+     * Consumes `src` and moves as many elements as it can into `self`
+     * from the range [start,end).
+     *
+     * Returns the number of elements copied (the shorter of self.len()
+     * and end - start).
+     *
+     * # Arguments
+     *
+     * * src - A mutable vector of `T`
+     * * start - The index into `src` to start copying from
+     * * end - The index into `str` to stop copying from
+     */
+    fn move_from(self, src: ~[T], start: uint, end: uint) -> uint;
+
+    /// Returns an unsafe mutable pointer to the element in index
+    unsafe fn unsafe_mut_ref(self, index: uint) -> &'a mut T;
+
+    /// Return an unsafe mutable pointer to the vector's buffer.
+    ///
+    /// The caller must ensure that the vector outlives the pointer this
+    /// function returns, or else it will end up pointing to garbage.
+    ///
+    /// Modifying the vector may cause its buffer to be reallocated, which
+    /// would also make any pointers to it invalid.
+    #[inline]
+    fn as_mut_ptr(self) -> *mut T;
+
+    /// Unsafely sets the element in index to the value.
+    ///
+    /// This performs no bounds checks, and it is undefined behaviour
+    /// if `index` is larger than the length of `self`. However, it
+    /// does run the destructor at `index`. It is equivalent to
+    /// `self[index] = val`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = ~[~"foo", ~"bar", ~"baz"];
+    ///
+    /// unsafe {
+    ///     // `~"baz"` is deallocated.
+    ///     v.unsafe_set(2, ~"qux");
+    ///
+    ///     // Out of bounds: could cause a crash, or overwriting
+    ///     // other data, or something else.
+    ///     // v.unsafe_set(10, ~"oops");
+    /// }
+    /// ```
+    unsafe fn unsafe_set(self, index: uint, val: T);
+
+    /// Unchecked vector index assignment.  Does not drop the
+    /// old value and hence is only suitable when the vector
+    /// is newly allocated.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = [~"foo", ~"bar"];
+    ///
+    /// // memory leak! `~"bar"` is not deallocated.
+    /// unsafe { v.init_elem(1, ~"baz"); }
+    /// ```
+    unsafe fn init_elem(self, i: uint, val: T);
+
+    /// Copies raw bytes from `src` to `self`.
+    ///
+    /// This does not run destructors on the overwritten elements, and
+    /// ignores move semantics. `self` and `src` must not
+    /// overlap. Fails if `self` is shorter than `src`.
+    unsafe fn copy_memory(self, src: &[T]);
+}
+
+impl<'a,T> MutableVector<'a, T> for &'a mut [T] {
+    #[inline]
+    fn as_mut_slice(self) -> &'a mut [T] { self }
+
+    fn mut_slice(self, start: uint, end: uint) -> &'a mut [T] {
+        assert!(start <= end);
+        assert!(end <= self.len());
+        unsafe {
+            transmute(Slice {
+                    data: self.as_mut_ptr().offset(start as int) as *T,
+                    len: (end - start)
+                })
+        }
+    }
+
+    #[inline]
+    fn mut_slice_from(self, start: uint) -> &'a mut [T] {
+        let len = self.len();
+        self.mut_slice(start, len)
+    }
+
+    #[inline]
+    fn mut_slice_to(self, end: uint) -> &'a mut [T] {
+        self.mut_slice(0, end)
+    }
+
+    #[inline]
+    fn mut_split_at(self, mid: uint) -> (&'a mut [T], &'a mut [T]) {
+        unsafe {
+            let len = self.len();
+            let self2: &'a mut [T] = cast::transmute_copy(&self);
+            (self.mut_slice(0, mid), self2.mut_slice(mid, len))
+        }
+    }
+
+    #[inline]
+    fn mut_iter(self) -> MutItems<'a, T> {
+        unsafe {
+            let p = self.as_mut_ptr();
+            if mem::size_of::<T>() == 0 {
+                MutItems{ptr: p,
+                         end: (p as uint + self.len()) as *mut T,
+                         marker: marker::ContravariantLifetime::<'a>,
+                         marker2: marker::NoPod}
+            } else {
+                MutItems{ptr: p,
+                         end: p.offset(self.len() as int),
+                         marker: marker::ContravariantLifetime::<'a>,
+                         marker2: marker::NoPod}
+            }
+        }
+    }
+
+    #[inline]
+    fn mut_last(self) -> Option<&'a mut T> {
+        let len = self.len();
+        if len == 0 { return None; }
+        Some(&mut self[len - 1])
+    }
+
+    #[inline]
+    fn mut_rev_iter(self) -> RevMutItems<'a, T> {
+        self.mut_iter().rev()
+    }
+
+    #[inline]
+    fn mut_split(self, pred: 'a |&T| -> bool) -> MutSplits<'a, T> {
+        MutSplits { v: self, pred: pred, finished: false }
+    }
+
+    #[inline]
+    fn mut_chunks(self, chunk_size: uint) -> MutChunks<'a, T> {
+        assert!(chunk_size > 0);
+        MutChunks { v: self, chunk_size: chunk_size }
+    }
+
+    fn mut_shift_ref(&mut self) -> Option<&'a mut T> {
+        if self.len() == 0 { return None; }
+        unsafe {
+            let s: &mut Slice<T> = transmute(self);
+            Some(cast::transmute_mut(&*raw::shift_ptr(s)))
+        }
+    }
+
+    fn mut_pop_ref(&mut self) -> Option<&'a mut T> {
+        if self.len() == 0 { return None; }
+        unsafe {
+            let s: &mut Slice<T> = transmute(self);
+            Some(cast::transmute_mut(&*raw::pop_ptr(s)))
+        }
+    }
+
+    fn swap(self, a: uint, b: uint) {
+        unsafe {
+            // Can't take two mutable loans from one vector, so instead just cast
+            // them to their raw pointers to do the swap
+            let pa: *mut T = &mut self[a];
+            let pb: *mut T = &mut self[b];
+            ptr::swap(pa, pb);
+        }
+    }
+
+    fn reverse(self) {
+        let mut i: uint = 0;
+        let ln = self.len();
+        while i < ln / 2 {
+            self.swap(i, ln - i - 1);
+            i += 1;
+        }
+    }
+
+    #[inline]
+    fn sort_by(self, compare: |&T, &T| -> Ordering) {
+        merge_sort(self, compare)
+    }
+
+    #[inline]
+    fn move_from(self, mut src: ~[T], start: uint, end: uint) -> uint {
+        for (a, b) in self.mut_iter().zip(src.mut_slice(start, end).mut_iter()) {
+            mem::swap(a, b);
+        }
+        cmp::min(self.len(), end-start)
+    }
+
+    #[inline]
+    unsafe fn unsafe_mut_ref(self, index: uint) -> &'a mut T {
+        transmute((self.repr().data as *mut T).offset(index as int))
+    }
+
+    #[inline]
+    fn as_mut_ptr(self) -> *mut T {
+        self.repr().data as *mut T
+    }
+
+    #[inline]
+    unsafe fn unsafe_set(self, index: uint, val: T) {
+        *self.unsafe_mut_ref(index) = val;
+    }
+
+    #[inline]
+    unsafe fn init_elem(self, i: uint, val: T) {
+        mem::move_val_init(&mut (*self.as_mut_ptr().offset(i as int)), val);
+    }
+
+    #[inline]
+    unsafe fn copy_memory(self, src: &[T]) {
+        let len_src = src.len();
+        assert!(self.len() >= len_src);
+        ptr::copy_nonoverlapping_memory(self.as_mut_ptr(), src.as_ptr(), len_src)
+    }
+}
+
+/// Trait for &[T] where T is Cloneable
+pub trait MutableCloneableVector<T> {
+    /// Copies as many elements from `src` as it can into `self` (the
+    /// shorter of `self.len()` and `src.len()`). Returns the number
+    /// of elements copied.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use std::slice::MutableCloneableVector;
+    ///
+    /// let mut dst = [0, 0, 0];
+    /// let src = [1, 2];
+    ///
+    /// assert!(dst.copy_from(src) == 2);
+    /// assert!(dst == [1, 2, 0]);
+    ///
+    /// let src2 = [3, 4, 5, 6];
+    /// assert!(dst.copy_from(src2) == 3);
+    /// assert!(dst == [3, 4, 5]);
+    /// ```
+    fn copy_from(self, &[T]) -> uint;
+}
+
+impl<'a, T:Clone> MutableCloneableVector<T> for &'a mut [T] {
+    #[inline]
+    fn copy_from(self, src: &[T]) -> uint {
+        for (a, b) in self.mut_iter().zip(src.iter()) {
+            a.clone_from(b);
+        }
+        cmp::min(self.len(), src.len())
+    }
+}
+
+/// Methods for mutable vectors with orderable elements, such as
+/// in-place sorting.
+pub trait MutableTotalOrdVector<T> {
+    /// Sort the vector, in place.
+    ///
+    /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = [-5, 4, 1, -3, 2];
+    ///
+    /// v.sort();
+    /// assert!(v == [-5, -3, 1, 2, 4]);
+    /// ```
+    fn sort(self);
+}
+impl<'a, T: TotalOrd> MutableTotalOrdVector<T> for &'a mut [T] {
+    #[inline]
+    fn sort(self) {
+        self.sort_by(|a,b| a.cmp(b))
+    }
+}
+
+/**
+* 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 cast::transmute;
+    use ptr;
+    use ptr::RawPtr;
+    use slice::{with_capacity, MutableVector, OwnedVector};
+    use raw::Slice;
+
+    /**
+     * Form a slice from a pointer and length (as a number of units,
+     * not bytes).
+     */
+    #[inline]
+    pub unsafe fn buf_as_slice<T,U>(p: *T, len: uint, f: |v: &[T]| -> U)
+                               -> U {
+        f(transmute(Slice {
+            data: p,
+            len: len
+        }))
+    }
+
+    /**
+     * Form a slice from a pointer and length (as a number of units,
+     * not bytes).
+     */
+    #[inline]
+    pub unsafe fn mut_buf_as_slice<T,
+                                   U>(
+                                   p: *mut T,
+                                   len: uint,
+                                   f: |v: &mut [T]| -> U)
+                                   -> U {
+        f(transmute(Slice {
+            data: p as *T,
+            len: len
+        }))
+    }
+
+    /**
+    * 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 = with_capacity(elts);
+        dst.set_len(elts);
+        ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
+        dst
+    }
+
+    /**
+     * Returns a pointer to first element in slice and adjusts
+     * slice so it no longer contains that element. Fails if
+     * slice is empty. O(1).
+     */
+    pub unsafe fn shift_ptr<T>(slice: &mut Slice<T>) -> *T {
+        if slice.len == 0 { fail!("shift on empty slice"); }
+        let head: *T = slice.data;
+        slice.data = slice.data.offset(1);
+        slice.len -= 1;
+        head
+    }
+
+    /**
+     * Returns a pointer to last element in slice and adjusts
+     * slice so it no longer contains that element. Fails if
+     * slice is empty. O(1).
+     */
+    pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> *T {
+        if slice.len == 0 { fail!("pop on empty slice"); }
+        let tail: *T = slice.data.offset((slice.len - 1) as int);
+        slice.len -= 1;
+        tail
+    }
+}
+
+/// Operations on `[u8]`.
+pub mod bytes {
+    use container::Container;
+    use slice::{MutableVector, OwnedVector, ImmutableVector};
+    use ptr;
+    use ptr::RawPtr;
+
+    /// A trait for operations on mutable `[u8]`s.
+    pub trait MutableByteVector {
+        /// Sets all bytes of the receiver to the given value.
+        fn set_memory(self, value: u8);
+    }
+
+    impl<'a> MutableByteVector for &'a mut [u8] {
+        #[inline]
+        fn set_memory(self, value: u8) {
+            unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
+        }
+    }
+
+    /// Copies data from `src` to `dst`
+    ///
+    /// `src` and `dst` must not overlap. Fails if the length of `dst`
+    /// is less than the length of `src`.
+    #[inline]
+    pub fn copy_memory(dst: &mut [u8], src: &[u8]) {
+        // Bound checks are done at .copy_memory.
+        unsafe { dst.copy_memory(src) }
+    }
+
+    /**
+     * Allocate space in `dst` and append the data to `src`.
+     */
+    #[inline]
+    pub fn push_bytes(dst: &mut ~[u8], src: &[u8]) {
+        let old_len = dst.len();
+        dst.reserve_additional(src.len());
+        unsafe {
+            ptr::copy_memory(dst.as_mut_ptr().offset(old_len as int), src.as_ptr(), src.len());
+            dst.set_len(old_len + src.len());
+        }
+    }
+}
+
+impl<A: Clone> Clone for ~[A] {
+    #[inline]
+    fn clone(&self) -> ~[A] {
+        self.iter().map(|item| item.clone()).collect()
+    }
+
+    fn clone_from(&mut self, source: &~[A]) {
+        if self.len() < source.len() {
+            *self = source.clone()
+        } else {
+            self.truncate(source.len());
+            for (x, y) in self.mut_iter().zip(source.iter()) {
+                x.clone_from(y);
+            }
+        }
+    }
+}
+
+impl<'a, T: fmt::Show> fmt::Show for &'a [T] {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        try!(write!(f.buf, "["));
+        let mut is_first = true;
+        for x in self.iter() {
+            if is_first {
+                is_first = false;
+            } else {
+                try!(write!(f.buf, ", "));
+            }
+            try!(write!(f.buf, "{}", *x))
+        }
+        write!(f.buf, "]")
+    }
+}
+
+impl<T: fmt::Show> fmt::Show for ~[T] {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.as_slice().fmt(f)
+    }
+}
+
+// This works because every lifetime is a sub-lifetime of 'static
+impl<'a, A> Default for &'a [A] {
+    fn default() -> &'a [A] { &'a [] }
+}
+
+impl<A> Default for ~[A] {
+    fn default() -> ~[A] { ~[] }
+}
+
+/// Immutable slice iterator
+pub struct Items<'a, T> {
+    priv ptr: *T,
+    priv end: *T,
+    priv marker: marker::ContravariantLifetime<'a>
+}
+
+/// Mutable slice iterator
+pub struct MutItems<'a, T> {
+    priv ptr: *mut T,
+    priv end: *mut T,
+    priv marker: marker::ContravariantLifetime<'a>,
+    priv marker2: marker::NoPod
+}
+
+macro_rules! iterator {
+    (struct $name:ident -> $ptr:ty, $elem:ty) => {
+        impl<'a, T> Iterator<$elem> for $name<'a, T> {
+            #[inline]
+            fn next(&mut self) -> Option<$elem> {
+                // could be implemented with slices, but this avoids bounds checks
+                unsafe {
+                    if self.ptr == self.end {
+                        None
+                    } else {
+                        let old = self.ptr;
+                        self.ptr = if mem::size_of::<T>() == 0 {
+                            // purposefully don't use 'ptr.offset' because for
+                            // vectors with 0-size elements this would return the
+                            // same pointer.
+                            transmute(self.ptr as uint + 1)
+                        } else {
+                            self.ptr.offset(1)
+                        };
+
+                        Some(transmute(old))
+                    }
+                }
+            }
+
+            #[inline]
+            fn size_hint(&self) -> (uint, Option<uint>) {
+                let diff = (self.end as uint) - (self.ptr as uint);
+                let exact = diff / mem::nonzero_size_of::<T>();
+                (exact, Some(exact))
+            }
+        }
+
+        impl<'a, T> DoubleEndedIterator<$elem> for $name<'a, T> {
+            #[inline]
+            fn next_back(&mut self) -> Option<$elem> {
+                // could be implemented with slices, but this avoids bounds checks
+                unsafe {
+                    if self.end == self.ptr {
+                        None
+                    } else {
+                        self.end = if mem::size_of::<T>() == 0 {
+                            // See above for why 'ptr.offset' isn't used
+                            transmute(self.end as uint - 1)
+                        } else {
+                            self.end.offset(-1)
+                        };
+                        Some(transmute(self.end))
+                    }
+                }
+            }
+        }
+    }
+}
+
+impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> {
+    #[inline]
+    fn indexable(&self) -> uint {
+        let (exact, _) = self.size_hint();
+        exact
+    }
+
+    #[inline]
+    fn idx(&self, index: uint) -> Option<&'a T> {
+        unsafe {
+            if index < self.indexable() {
+                transmute(self.ptr.offset(index as int))
+            } else {
+                None
+            }
+        }
+    }
+}
+
+iterator!{struct Items -> *T, &'a T}
+pub type RevItems<'a, T> = Rev<Items<'a, T>>;
+
+impl<'a, T> ExactSize<&'a T> for Items<'a, T> {}
+impl<'a, T> ExactSize<&'a mut T> for MutItems<'a, T> {}
+
+impl<'a, T> Clone for Items<'a, T> {
+    fn clone(&self) -> Items<'a, T> { *self }
+}
+
+iterator!{struct MutItems -> *mut T, &'a mut T}
+pub type RevMutItems<'a, T> = Rev<MutItems<'a, T>>;
+
+/// An iterator over the subslices of the vector which are separated
+/// by elements that match `pred`.
+pub struct MutSplits<'a, T> {
+    priv v: &'a mut [T],
+    priv pred: 'a |t: &T| -> bool,
+    priv finished: bool
+}
+
+impl<'a, T> Iterator<&'a mut [T]> for MutSplits<'a, T> {
+    #[inline]
+    fn next(&mut self) -> Option<&'a mut [T]> {
+        if self.finished { return None; }
+
+        match self.v.iter().position(|x| (self.pred)(x)) {
+            None => {
+                self.finished = true;
+                let tmp = mem::replace(&mut self.v, &mut []);
+                let len = tmp.len();
+                let (head, tail) = tmp.mut_split_at(len);
+                self.v = tail;
+                Some(head)
+            }
+            Some(idx) => {
+                let tmp = mem::replace(&mut self.v, &mut []);
+                let (head, tail) = tmp.mut_split_at(idx);
+                self.v = tail.mut_slice_from(1);
+                Some(head)
+            }
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        if self.finished {
+            (0, Some(0))
+        } else {
+            // if the predicate doesn't match anything, we yield one slice
+            // if it matches every element, we yield len+1 empty slices.
+            (1, Some(self.v.len() + 1))
+        }
+    }
+}
+
+impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<&'a mut [T]> {
+        if self.finished { return None; }
+
+        match self.v.iter().rposition(|x| (self.pred)(x)) {
+            None => {
+                self.finished = true;
+                let tmp = mem::replace(&mut self.v, &mut []);
+                Some(tmp)
+            }
+            Some(idx) => {
+                let tmp = mem::replace(&mut self.v, &mut []);
+                let (head, tail) = tmp.mut_split_at(idx);
+                self.v = head;
+                Some(tail.mut_slice_from(1))
+            }
+        }
+    }
+}
+
+/// An iterator over a vector in (non-overlapping) mutable chunks (`size`  elements at a time). When
+/// the vector len is not evenly divided by the chunk size, the last slice of the iteration will be
+/// the remainder.
+pub struct MutChunks<'a, T> {
+    priv v: &'a mut [T],
+    priv chunk_size: uint
+}
+
+impl<'a, T> Iterator<&'a mut [T]> for MutChunks<'a, T> {
+    #[inline]
+    fn next(&mut self) -> Option<&'a mut [T]> {
+        if self.v.len() == 0 {
+            None
+        } else {
+            let sz = cmp::min(self.v.len(), self.chunk_size);
+            let tmp = mem::replace(&mut self.v, &mut []);
+            let (head, tail) = tmp.mut_split_at(sz);
+            self.v = tail;
+            Some(head)
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        if self.v.len() == 0 {
+            (0, Some(0))
+        } else {
+            let (n, rem) = div_rem(self.v.len(), self.chunk_size);
+            let n = if rem > 0 { n + 1 } else { n };
+            (n, Some(n))
+        }
+    }
+}
+
+impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutChunks<'a, T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<&'a mut [T]> {
+        if self.v.len() == 0 {
+            None
+        } else {
+            let remainder = self.v.len() % self.chunk_size;
+            let sz = if remainder != 0 { remainder } else { self.chunk_size };
+            let tmp = mem::replace(&mut self.v, &mut []);
+            let tmp_len = tmp.len();
+            let (head, tail) = tmp.mut_split_at(tmp_len - sz);
+            self.v = head;
+            Some(tail)
+        }
+    }
+}
+
+/// An iterator that moves out of a vector.
+pub struct MoveItems<T> {
+    priv allocation: *mut u8, // the block of memory allocated for the vector
+    priv iter: Items<'static, T>
+}
+
+impl<T> Iterator<T> for MoveItems<T> {
+    #[inline]
+    fn next(&mut self) -> Option<T> {
+        unsafe {
+            self.iter.next().map(|x| ptr::read(x))
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        self.iter.size_hint()
+    }
+}
+
+impl<T> DoubleEndedIterator<T> for MoveItems<T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<T> {
+        unsafe {
+            self.iter.next_back().map(|x| ptr::read(x))
+        }
+    }
+}
+
+#[unsafe_destructor]
+impl<T> Drop for MoveItems<T> {
+    fn drop(&mut self) {
+        // destroy the remaining elements
+        for _x in *self {}
+        unsafe {
+            exchange_free(self.allocation as *u8)
+        }
+    }
+}
+
+/// An iterator that moves out of a vector in reverse order.
+pub type RevMoveItems<T> = Rev<MoveItems<T>>;
+
+impl<A> FromIterator<A> for ~[A] {
+    fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> ~[A] {
+        let (lower, _) = iterator.size_hint();
+        let mut xs = with_capacity(lower);
+        for x in *iterator {
+            xs.push(x);
+        }
+        xs
+    }
+}
+
+impl<A> Extendable<A> for ~[A] {
+    fn extend<T: Iterator<A>>(&mut self, iterator: &mut T) {
+        let (lower, _) = iterator.size_hint();
+        let len = self.len();
+        self.reserve_exact(len + lower);
+        for x in *iterator {
+            self.push(x);
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use prelude::*;
+    use mem;
+    use slice::*;
+    use cmp::*;
+    use rand::{Rng, task_rng};
+
+    fn square(n: uint) -> uint { n * n }
+
+    fn square_ref(n: &uint) -> uint { square(*n) }
+
+    fn is_odd(n: &uint) -> bool { *n % 2u == 1u }
+
+    #[test]
+    fn test_unsafe_ptrs() {
+        unsafe {
+            // Test on-stack copy-from-buf.
+            let a = ~[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 = ~[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 = from_fn(3u, square);
+        assert_eq!(v.len(), 3u);
+        assert_eq!(v[0], 0u);
+        assert_eq!(v[1], 1u);
+        assert_eq!(v[2], 4u);
+
+        // Test on-heap from_fn.
+        v = from_fn(5u, square);
+        assert_eq!(v.len(), 5u);
+        assert_eq!(v[0], 0u);
+        assert_eq!(v[1], 1u);
+        assert_eq!(v[2], 4u);
+        assert_eq!(v[3], 9u);
+        assert_eq!(v[4], 16u);
+    }
+
+    #[test]
+    fn test_from_elem() {
+        // Test on-stack from_elem.
+        let mut v = from_elem(2u, 10u);
+        assert_eq!(v.len(), 2u);
+        assert_eq!(v[0], 10u);
+        assert_eq!(v[1], 10u);
+
+        // Test on-heap from_elem.
+        v = from_elem(6u, 20u);
+        assert_eq!(v[0], 20u);
+        assert_eq!(v[1], 20u);
+        assert_eq!(v[2], 20u);
+        assert_eq!(v[3], 20u);
+        assert_eq!(v[4], 20u);
+        assert_eq!(v[5], 20u);
+    }
+
+    #[test]
+    fn test_is_empty() {
+        let xs: [int, ..0] = [];
+        assert!(xs.is_empty());
+        assert!(![0].is_empty());
+    }
+
+    #[test]
+    fn test_len_divzero() {
+        type Z = [i8, ..0];
+        let v0 : &[Z] = &[];
+        let v1 : &[Z] = &[[]];
+        let v2 : &[Z] = &[[], []];
+        assert_eq!(mem::size_of::<Z>(), 0);
+        assert_eq!(v0.len(), 0);
+        assert_eq!(v1.len(), 1);
+        assert_eq!(v2.len(), 2);
+    }
+
+    #[test]
+    fn test_get() {
+        let mut a = ~[11];
+        assert_eq!(a.get(1), None);
+        a = ~[11, 12];
+        assert_eq!(a.get(1).unwrap(), &12);
+        a = ~[11, 12, 13];
+        assert_eq!(a.get(1).unwrap(), &12);
+    }
+
+    #[test]
+    fn test_head() {
+        let mut a = ~[];
+        assert_eq!(a.head(), None);
+        a = ~[11];
+        assert_eq!(a.head().unwrap(), &11);
+        a = ~[11, 12];
+        assert_eq!(a.head().unwrap(), &11);
+    }
+
+    #[test]
+    fn test_tail() {
+        let mut a = ~[11];
+        assert_eq!(a.tail(), &[]);
+        a = ~[11, 12];
+        assert_eq!(a.tail(), &[12]);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_tail_empty() {
+        let a: ~[int] = ~[];
+        a.tail();
+    }
+
+    #[test]
+    fn test_tailn() {
+        let mut a = ~[11, 12, 13];
+        assert_eq!(a.tailn(0), &[11, 12, 13]);
+        a = ~[11, 12, 13];
+        assert_eq!(a.tailn(2), &[13]);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_tailn_empty() {
+        let a: ~[int] = ~[];
+        a.tailn(2);
+    }
+
+    #[test]
+    fn test_init() {
+        let mut a = ~[11];
+        assert_eq!(a.init(), &[]);
+        a = ~[11, 12];
+        assert_eq!(a.init(), &[11]);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_init_empty() {
+        let a: ~[int] = ~[];
+        a.init();
+    }
+
+    #[test]
+    fn test_initn() {
+        let mut a = ~[11, 12, 13];
+        assert_eq!(a.initn(0), &[11, 12, 13]);
+        a = ~[11, 12, 13];
+        assert_eq!(a.initn(2), &[11]);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_initn_empty() {
+        let a: ~[int] = ~[];
+        a.initn(2);
+    }
+
+    #[test]
+    fn test_last() {
+        let mut a = ~[];
+        assert_eq!(a.last(), None);
+        a = ~[11];
+        assert_eq!(a.last().unwrap(), &11);
+        a = ~[11, 12];
+        assert_eq!(a.last().unwrap(), &12);
+    }
+
+    #[test]
+    fn test_slice() {
+        // Test fixed length vector.
+        let vec_fixed = [1, 2, 3, 4];
+        let v_a = vec_fixed.slice(1u, vec_fixed.len()).to_owned();
+        assert_eq!(v_a.len(), 3u);
+        assert_eq!(v_a[0], 2);
+        assert_eq!(v_a[1], 3);
+        assert_eq!(v_a[2], 4);
+
+        // Test on stack.
+        let vec_stack = &[1, 2, 3];
+        let v_b = vec_stack.slice(1u, 3u).to_owned();
+        assert_eq!(v_b.len(), 2u);
+        assert_eq!(v_b[0], 2);
+        assert_eq!(v_b[1], 3);
+
+        // Test on exchange heap.
+        let vec_unique = ~[1, 2, 3, 4, 5, 6];
+        let v_d = vec_unique.slice(1u, 6u).to_owned();
+        assert_eq!(v_d.len(), 5u);
+        assert_eq!(v_d[0], 2);
+        assert_eq!(v_d[1], 3);
+        assert_eq!(v_d[2], 4);
+        assert_eq!(v_d[3], 5);
+        assert_eq!(v_d[4], 6);
+    }
+
+    #[test]
+    fn test_slice_from() {
+        let vec = &[1, 2, 3, 4];
+        assert_eq!(vec.slice_from(0), vec);
+        assert_eq!(vec.slice_from(2), &[3, 4]);
+        assert_eq!(vec.slice_from(4), &[]);
+    }
+
+    #[test]
+    fn test_slice_to() {
+        let vec = &[1, 2, 3, 4];
+        assert_eq!(vec.slice_to(4), vec);
+        assert_eq!(vec.slice_to(2), &[1, 2]);
+        assert_eq!(vec.slice_to(0), &[]);
+    }
+
+
+    #[test]
+    fn test_pop() {
+        let mut v = ~[5];
+        let e = v.pop();
+        assert_eq!(v.len(), 0);
+        assert_eq!(e, Some(5));
+        let f = v.pop();
+        assert_eq!(f, None);
+        let g = v.pop();
+        assert_eq!(g, None);
+    }
+
+    #[test]
+    fn test_swap_remove() {
+        let mut v = ~[1, 2, 3, 4, 5];
+        let mut e = v.swap_remove(0);
+        assert_eq!(e, Some(1));
+        assert_eq!(v, ~[5, 2, 3, 4]);
+        e = v.swap_remove(3);
+        assert_eq!(e, Some(4));
+        assert_eq!(v, ~[5, 2, 3]);
+
+        e = v.swap_remove(3);
+        assert_eq!(e, None);
+        assert_eq!(v, ~[5, 2, 3]);
+    }
+
+    #[test]
+    fn test_swap_remove_noncopyable() {
+        // Tests that we don't accidentally run destructors twice.
+        let mut v = ~[::unstable::sync::Exclusive::new(()),
+                      ::unstable::sync::Exclusive::new(()),
+                      ::unstable::sync::Exclusive::new(())];
+        let mut _e = v.swap_remove(0);
+        assert_eq!(v.len(), 2);
+        _e = v.swap_remove(1);
+        assert_eq!(v.len(), 1);
+        _e = v.swap_remove(0);
+        assert_eq!(v.len(), 0);
+    }
+
+    #[test]
+    fn test_push() {
+        // Test on-stack push().
+        let mut v = ~[];
+        v.push(1);
+        assert_eq!(v.len(), 1u);
+        assert_eq!(v[0], 1);
+
+        // Test on-heap push().
+        v.push(2);
+        assert_eq!(v.len(), 2u);
+        assert_eq!(v[0], 1);
+        assert_eq!(v[1], 2);
+    }
+
+    #[test]
+    fn test_grow() {
+        // Test on-stack grow().
+        let mut v = ~[];
+        v.grow(2u, &1);
+        assert_eq!(v.len(), 2u);
+        assert_eq!(v[0], 1);
+        assert_eq!(v[1], 1);
+
+        // Test on-heap grow().
+        v.grow(3u, &2);
+        assert_eq!(v.len(), 5u);
+        assert_eq!(v[0], 1);
+        assert_eq!(v[1], 1);
+        assert_eq!(v[2], 2);
+        assert_eq!(v[3], 2);
+        assert_eq!(v[4], 2);
+    }
+
+    #[test]
+    fn test_grow_fn() {
+        let mut v = ~[];
+        v.grow_fn(3u, square);
+        assert_eq!(v.len(), 3u);
+        assert_eq!(v[0], 0u);
+        assert_eq!(v[1], 1u);
+        assert_eq!(v[2], 4u);
+    }
+
+    #[test]
+    fn test_grow_set() {
+        let mut v = ~[1, 2, 3];
+        v.grow_set(4u, &4, 5);
+        assert_eq!(v.len(), 5u);
+        assert_eq!(v[0], 1);
+        assert_eq!(v[1], 2);
+        assert_eq!(v[2], 3);
+        assert_eq!(v[3], 4);
+        assert_eq!(v[4], 5);
+    }
+
+    #[test]
+    fn test_truncate() {
+        let mut v = ~[~6,~5,~4];
+        v.truncate(1);
+        assert_eq!(v.len(), 1);
+        assert_eq!(*(v[0]), 6);
+        // If the unsafe block didn't drop things properly, we blow up here.
+    }
+
+    #[test]
+    fn test_clear() {
+        let mut v = ~[~6,~5,~4];
+        v.clear();
+        assert_eq!(v.len(), 0);
+        // If the unsafe block didn't drop things properly, we blow up here.
+    }
+
+    #[test]
+    fn test_dedup() {
+        fn case(a: ~[uint], b: ~[uint]) {
+            let mut v = a;
+            v.dedup();
+            assert_eq!(v, b);
+        }
+        case(~[], ~[]);
+        case(~[1], ~[1]);
+        case(~[1,1], ~[1]);
+        case(~[1,2,3], ~[1,2,3]);
+        case(~[1,1,2,3], ~[1,2,3]);
+        case(~[1,2,2,3], ~[1,2,3]);
+        case(~[1,2,3,3], ~[1,2,3]);
+        case(~[1,1,2,2,2,3,3], ~[1,2,3]);
+    }
+
+    #[test]
+    fn test_dedup_unique() {
+        let mut v0 = ~[~1, ~1, ~2, ~3];
+        v0.dedup();
+        let mut v1 = ~[~1, ~2, ~2, ~3];
+        v1.dedup();
+        let mut v2 = ~[~1, ~2, ~3, ~3];
+        v2.dedup();
+        /*
+         * If the ~pointers were leaked or otherwise misused, valgrind and/or
+         * rustrt should raise errors.
+         */
+    }
+
+    #[test]
+    fn test_dedup_shared() {
+        let mut v0 = ~[~1, ~1, ~2, ~3];
+        v0.dedup();
+        let mut v1 = ~[~1, ~2, ~2, ~3];
+        v1.dedup();
+        let mut v2 = ~[~1, ~2, ~3, ~3];
+        v2.dedup();
+        /*
+         * If the pointers were leaked or otherwise misused, valgrind and/or
+         * rustrt should raise errors.
+         */
+    }
+
+    #[test]
+    fn test_map() {
+        // Test on-stack map.
+        let v = &[1u, 2u, 3u];
+        let mut w = v.map(square_ref);
+        assert_eq!(w.len(), 3u);
+        assert_eq!(w[0], 1u);
+        assert_eq!(w[1], 4u);
+        assert_eq!(w[2], 9u);
+
+        // Test on-heap map.
+        let v = ~[1u, 2u, 3u, 4u, 5u];
+        w = v.map(square_ref);
+        assert_eq!(w.len(), 5u);
+        assert_eq!(w[0], 1u);
+        assert_eq!(w[1], 4u);
+        assert_eq!(w[2], 9u);
+        assert_eq!(w[3], 16u);
+        assert_eq!(w[4], 25u);
+    }
+
+    #[test]
+    fn test_retain() {
+        let mut v = ~[1, 2, 3, 4, 5];
+        v.retain(is_odd);
+        assert_eq!(v, ~[1, 3, 5]);
+    }
+
+    #[test]
+    fn test_zip_unzip() {
+        let z1 = ~[(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() {
+            v.swap(a, b);
+            match i {
+                0 => assert!(v == [1, 3, 2]),
+                1 => assert!(v == [3, 1, 2]),
+                2 => assert!(v == [3, 2, 1]),
+                3 => assert!(v == [2, 3, 1]),
+                4 => assert!(v == [2, 1, 3]),
+                5 => assert!(v == [1, 2, 3]),
+                _ => fail!(),
+            }
+        }
+    }
+
+    #[test]
+    fn test_permutations() {
+        {
+            let v: [int, ..0] = [];
+            let mut it = v.permutations();
+            assert_eq!(it.next(), None);
+        }
+        {
+            let v = [~"Hello"];
+            let mut it = v.permutations();
+            assert_eq!(it.next(), None);
+        }
+        {
+            let v = [1, 2, 3];
+            let mut it = v.permutations();
+            assert_eq!(it.next(), Some(~[1,2,3]));
+            assert_eq!(it.next(), Some(~[1,3,2]));
+            assert_eq!(it.next(), Some(~[3,1,2]));
+            assert_eq!(it.next(), Some(~[3,2,1]));
+            assert_eq!(it.next(), Some(~[2,3,1]));
+            assert_eq!(it.next(), Some(~[2,1,3]));
+            assert_eq!(it.next(), None);
+        }
+        {
+            // check that we have N! permutations
+            let v = ['A', 'B', 'C', 'D', 'E', 'F'];
+            let mut amt = 0;
+            for _perm in v.permutations() {
+                amt += 1;
+            }
+            assert_eq!(amt, 2 * 3 * 4 * 5 * 6);
+        }
+    }
+
+    #[test]
+    fn test_position_elem() {
+        assert!([].position_elem(&1).is_none());
+
+        let v1 = ~[1, 2, 3, 3, 2, 5];
+        assert_eq!(v1.position_elem(&1), Some(0u));
+        assert_eq!(v1.position_elem(&2), Some(1u));
+        assert_eq!(v1.position_elem(&5), Some(5u));
+        assert!(v1.position_elem(&4).is_none());
+    }
+
+    #[test]
+    fn test_bsearch_elem() {
+        assert_eq!([1,2,3,4,5].bsearch_elem(&5), Some(4));
+        assert_eq!([1,2,3,4,5].bsearch_elem(&4), Some(3));
+        assert_eq!([1,2,3,4,5].bsearch_elem(&3), Some(2));
+        assert_eq!([1,2,3,4,5].bsearch_elem(&2), Some(1));
+        assert_eq!([1,2,3,4,5].bsearch_elem(&1), Some(0));
+
+        assert_eq!([2,4,6,8,10].bsearch_elem(&1), None);
+        assert_eq!([2,4,6,8,10].bsearch_elem(&5), None);
+        assert_eq!([2,4,6,8,10].bsearch_elem(&4), Some(1));
+        assert_eq!([2,4,6,8,10].bsearch_elem(&10), Some(4));
+
+        assert_eq!([2,4,6,8].bsearch_elem(&1), None);
+        assert_eq!([2,4,6,8].bsearch_elem(&5), None);
+        assert_eq!([2,4,6,8].bsearch_elem(&4), Some(1));
+        assert_eq!([2,4,6,8].bsearch_elem(&8), Some(3));
+
+        assert_eq!([2,4,6].bsearch_elem(&1), None);
+        assert_eq!([2,4,6].bsearch_elem(&5), None);
+        assert_eq!([2,4,6].bsearch_elem(&4), Some(1));
+        assert_eq!([2,4,6].bsearch_elem(&6), Some(2));
+
+        assert_eq!([2,4].bsearch_elem(&1), None);
+        assert_eq!([2,4].bsearch_elem(&5), None);
+        assert_eq!([2,4].bsearch_elem(&2), Some(0));
+        assert_eq!([2,4].bsearch_elem(&4), Some(1));
+
+        assert_eq!([2].bsearch_elem(&1), None);
+        assert_eq!([2].bsearch_elem(&5), None);
+        assert_eq!([2].bsearch_elem(&2), Some(0));
+
+        assert_eq!([].bsearch_elem(&1), None);
+        assert_eq!([].bsearch_elem(&5), None);
+
+        assert!([1,1,1,1,1].bsearch_elem(&1) != None);
+        assert!([1,1,1,1,2].bsearch_elem(&1) != None);
+        assert!([1,1,1,2,2].bsearch_elem(&1) != None);
+        assert!([1,1,2,2,2].bsearch_elem(&1) != None);
+        assert_eq!([1,2,2,2,2].bsearch_elem(&1), Some(0));
+
+        assert_eq!([1,2,3,4,5].bsearch_elem(&6), None);
+        assert_eq!([1,2,3,4,5].bsearch_elem(&0), None);
+    }
+
+    #[test]
+    fn test_reverse() {
+        let mut v: ~[int] = ~[10, 20];
+        assert_eq!(v[0], 10);
+        assert_eq!(v[1], 20);
+        v.reverse();
+        assert_eq!(v[0], 20);
+        assert_eq!(v[1], 10);
+
+        let mut v3: ~[int] = ~[];
+        v3.reverse();
+        assert!(v3.is_empty());
+    }
+
+    #[test]
+    fn test_sort() {
+        for len in range(4u, 25) {
+            for _ in range(0, 100) {
+                let mut v = task_rng().gen_vec::<uint>(len);
+                let mut v1 = v.clone();
+
+                v.sort();
+                assert!(v.windows(2).all(|w| w[0] <= w[1]));
+
+                v1.sort_by(|a, b| a.cmp(b));
+                assert!(v1.windows(2).all(|w| w[0] <= w[1]));
+
+                v1.sort_by(|a, b| b.cmp(a));
+                assert!(v1.windows(2).all(|w| w[0] >= w[1]));
+            }
+        }
+
+        // shouldn't fail/crash
+        let mut v: [uint, .. 0] = [];
+        v.sort();
+
+        let mut v = [0xDEADBEEFu];
+        v.sort();
+        assert!(v == [0xDEADBEEF]);
+    }
+
+    #[test]
+    fn test_sort_stability() {
+        for len in range(4, 25) {
+            for _ in range(0 , 10) {
+                let mut counts = [0, .. 10];
+
+                // create a vector like [(6, 1), (5, 1), (6, 2), ...],
+                // where the first item of each tuple is random, but
+                // the second item represents which occurrence of that
+                // number this element is, i.e. the second elements
+                // will occur in sorted order.
+                let mut v = range(0, len).map(|_| {
+                        let n = task_rng().gen::<uint>() % 10;
+                        counts[n] += 1;
+                        (n, counts[n])
+                    }).to_owned_vec();
+
+                // only sort on the first element, so an unstable sort
+                // may mix up the counts.
+                v.sort_by(|&(a,_), &(b,_)| a.cmp(&b));
+
+                // this comparison includes the count (the second item
+                // of the tuple), so elements with equal first items
+                // 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]));
+            }
+        }
+    }
+
+    #[test]
+    fn test_partition() {
+        assert_eq!((~[]).partition(|x: &int| *x < 3), (~[], ~[]));
+        assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 4), (~[1, 2, 3], ~[]));
+        assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 2), (~[1], ~[2, 3]));
+        assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 0), (~[], ~[1, 2, 3]));
+    }
+
+    #[test]
+    fn test_partitioned() {
+        assert_eq!(([]).partitioned(|x: &int| *x < 3), (~[], ~[]))
+        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 4), (~[1, 2, 3], ~[]));
+        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 2), (~[1], ~[2, 3]));
+        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 0), (~[], ~[1, 2, 3]));
+    }
+
+    #[test]
+    fn test_concat() {
+        let v: [~[int], ..0] = [];
+        assert_eq!(v.concat_vec(), ~[]);
+        assert_eq!([~[1], ~[2,3]].concat_vec(), ~[1, 2, 3]);
+
+        assert_eq!([&[1], &[2,3]].concat_vec(), ~[1, 2, 3]);
+    }
+
+    #[test]
+    fn test_connect() {
+        let v: [~[int], ..0] = [];
+        assert_eq!(v.connect_vec(&0), ~[]);
+        assert_eq!([~[1], ~[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
+        assert_eq!([~[1], ~[2], ~[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
+
+        assert_eq!(v.connect_vec(&0), ~[]);
+        assert_eq!([&[1], &[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
+        assert_eq!([&[1], &[2], &[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
+    }
+
+    #[test]
+    fn test_shift() {
+        let mut x = ~[1, 2, 3];
+        assert_eq!(x.shift(), Some(1));
+        assert_eq!(&x, &~[2, 3]);
+        assert_eq!(x.shift(), Some(2));
+        assert_eq!(x.shift(), Some(3));
+        assert_eq!(x.shift(), None);
+        assert_eq!(x.len(), 0);
+    }
+
+    #[test]
+    fn test_unshift() {
+        let mut x = ~[1, 2, 3];
+        x.unshift(0);
+        assert_eq!(x, ~[0, 1, 2, 3]);
+    }
+
+    #[test]
+    fn test_insert() {
+        let mut a = ~[1, 2, 4];
+        a.insert(2, 3);
+        assert_eq!(a, ~[1, 2, 3, 4]);
+
+        let mut a = ~[1, 2, 3];
+        a.insert(0, 0);
+        assert_eq!(a, ~[0, 1, 2, 3]);
+
+        let mut a = ~[1, 2, 3];
+        a.insert(3, 4);
+        assert_eq!(a, ~[1, 2, 3, 4]);
+
+        let mut a = ~[];
+        a.insert(0, 1);
+        assert_eq!(a, ~[1]);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_insert_oob() {
+        let mut a = ~[1, 2, 3];
+        a.insert(4, 5);
+    }
+
+    #[test]
+    fn test_remove() {
+        let mut a = ~[1,2,3,4];
+
+        assert_eq!(a.remove(2), Some(3));
+        assert_eq!(a, ~[1,2,4]);
+
+        assert_eq!(a.remove(2), Some(4));
+        assert_eq!(a, ~[1,2]);
+
+        assert_eq!(a.remove(2), None);
+        assert_eq!(a, ~[1,2]);
+
+        assert_eq!(a.remove(0), Some(1));
+        assert_eq!(a, ~[2]);
+
+        assert_eq!(a.remove(0), Some(2));
+        assert_eq!(a, ~[]);
+
+        assert_eq!(a.remove(0), None);
+        assert_eq!(a.remove(10), None);
+    }
+
+    #[test]
+    fn test_capacity() {
+        let mut v = ~[0u64];
+        v.reserve_exact(10u);
+        assert_eq!(v.capacity(), 10u);
+        let mut v = ~[0u32];
+        v.reserve_exact(10u);
+        assert_eq!(v.capacity(), 10u);
+    }
+
+    #[test]
+    fn test_slice_2() {
+        let v = ~[1, 2, 3, 4, 5];
+        let v = v.slice(1u, 3u);
+        assert_eq!(v.len(), 2u);
+        assert_eq!(v[0], 2);
+        assert_eq!(v[1], 3);
+    }
+
+
+    #[test]
+    #[should_fail]
+    fn test_from_fn_fail() {
+        from_fn(100, |v| {
+            if v == 50 { fail!() }
+            ~0
+        });
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_from_elem_fail() {
+        use cast;
+        use rc::Rc;
+
+        struct S {
+            f: int,
+            boxes: (~int, Rc<int>)
+        }
+
+        impl Clone for S {
+            fn clone(&self) -> S {
+                let s = unsafe { cast::transmute_mut(self) };
+                s.f += 1;
+                if s.f == 10 { fail!() }
+                S { f: s.f, boxes: s.boxes.clone() }
+            }
+        }
+
+        let s = S { f: 0, boxes: (~0, Rc::new(0)) };
+        let _ = from_elem(100, s);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_build_fail() {
+        use rc::Rc;
+        build(None, |push| {
+            push((~0, Rc::new(0)));
+            push((~0, Rc::new(0)));
+            push((~0, Rc::new(0)));
+            push((~0, Rc::new(0)));
+            fail!();
+        });
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_grow_fn_fail() {
+        use rc::Rc;
+        let mut v = ~[];
+        v.grow_fn(100, |i| {
+            if i == 50 {
+                fail!()
+            }
+            (~0, Rc::new(0))
+        })
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_map_fail() {
+        use rc::Rc;
+        let v = [(~0, Rc::new(0)), (~0, Rc::new(0)), (~0, Rc::new(0)), (~0, Rc::new(0))];
+        let mut i = 0;
+        v.map(|_elt| {
+            if i == 2 {
+                fail!()
+            }
+            i += 1;
+            ~[(~0, Rc::new(0))]
+        });
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_flat_map_fail() {
+        use rc::Rc;
+        let v = [(~0, Rc::new(0)), (~0, Rc::new(0)), (~0, Rc::new(0)), (~0, Rc::new(0))];
+        let mut i = 0;
+        flat_map(v, |_elt| {
+            if i == 2 {
+                fail!()
+            }
+            i += 1;
+            ~[(~0, Rc::new(0))]
+        });
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_permute_fail() {
+        use rc::Rc;
+        let v = [(~0, Rc::new(0)), (~0, Rc::new(0)), (~0, Rc::new(0)), (~0, Rc::new(0))];
+        let mut i = 0;
+        for _ in v.permutations() {
+            if i == 2 {
+                fail!()
+            }
+            i += 1;
+        }
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_copy_memory_oob() {
+        unsafe {
+            let mut a = [1, 2, 3, 4];
+            let b = [1, 2, 3, 4, 5];
+            a.copy_memory(b);
+        }
+    }
+
+    #[test]
+    fn test_total_ord() {
+        [1, 2, 3, 4].cmp(& &[1, 2, 3]) == Greater;
+        [1, 2, 3].cmp(& &[1, 2, 3, 4]) == Less;
+        [1, 2, 3, 4].cmp(& &[1, 2, 3, 4]) == Equal;
+        [1, 2, 3, 4, 5, 5, 5, 5].cmp(& &[1, 2, 3, 4, 5, 6]) == Less;
+        [2, 2].cmp(& &[1, 2, 3, 4]) == Greater;
+    }
+
+    #[test]
+    fn test_iterator() {
+        use iter::*;
+        let xs = [1, 2, 5, 10, 11];
+        let mut it = xs.iter();
+        assert_eq!(it.size_hint(), (5, Some(5)));
+        assert_eq!(it.next().unwrap(), &1);
+        assert_eq!(it.size_hint(), (4, Some(4)));
+        assert_eq!(it.next().unwrap(), &2);
+        assert_eq!(it.size_hint(), (3, Some(3)));
+        assert_eq!(it.next().unwrap(), &5);
+        assert_eq!(it.size_hint(), (2, Some(2)));
+        assert_eq!(it.next().unwrap(), &10);
+        assert_eq!(it.size_hint(), (1, Some(1)));
+        assert_eq!(it.next().unwrap(), &11);
+        assert_eq!(it.size_hint(), (0, Some(0)));
+        assert!(it.next().is_none());
+    }
+
+    #[test]
+    fn test_random_access_iterator() {
+        use iter::*;
+        let xs = [1, 2, 5, 10, 11];
+        let mut it = xs.iter();
+
+        assert_eq!(it.indexable(), 5);
+        assert_eq!(it.idx(0).unwrap(), &1);
+        assert_eq!(it.idx(2).unwrap(), &5);
+        assert_eq!(it.idx(4).unwrap(), &11);
+        assert!(it.idx(5).is_none());
+
+        assert_eq!(it.next().unwrap(), &1);
+        assert_eq!(it.indexable(), 4);
+        assert_eq!(it.idx(0).unwrap(), &2);
+        assert_eq!(it.idx(3).unwrap(), &11);
+        assert!(it.idx(4).is_none());
+
+        assert_eq!(it.next().unwrap(), &2);
+        assert_eq!(it.indexable(), 3);
+        assert_eq!(it.idx(1).unwrap(), &10);
+        assert!(it.idx(3).is_none());
+
+        assert_eq!(it.next().unwrap(), &5);
+        assert_eq!(it.indexable(), 2);
+        assert_eq!(it.idx(1).unwrap(), &11);
+
+        assert_eq!(it.next().unwrap(), &10);
+        assert_eq!(it.indexable(), 1);
+        assert_eq!(it.idx(0).unwrap(), &11);
+        assert!(it.idx(1).is_none());
+
+        assert_eq!(it.next().unwrap(), &11);
+        assert_eq!(it.indexable(), 0);
+        assert!(it.idx(0).is_none());
+
+        assert!(it.next().is_none());
+    }
+
+    #[test]
+    fn test_iter_size_hints() {
+        use iter::*;
+        let mut xs = [1, 2, 5, 10, 11];
+        assert_eq!(xs.iter().size_hint(), (5, Some(5)));
+        assert_eq!(xs.rev_iter().size_hint(), (5, Some(5)));
+        assert_eq!(xs.mut_iter().size_hint(), (5, Some(5)));
+        assert_eq!(xs.mut_rev_iter().size_hint(), (5, Some(5)));
+    }
+
+    #[test]
+    fn test_iter_clone() {
+        let xs = [1, 2, 5];
+        let mut it = xs.iter();
+        it.next();
+        let mut jt = it.clone();
+        assert_eq!(it.next(), jt.next());
+        assert_eq!(it.next(), jt.next());
+        assert_eq!(it.next(), jt.next());
+    }
+
+    #[test]
+    fn test_mut_iterator() {
+        use iter::*;
+        let mut xs = [1, 2, 3, 4, 5];
+        for x in xs.mut_iter() {
+            *x += 1;
+        }
+        assert!(xs == [2, 3, 4, 5, 6])
+    }
+
+    #[test]
+    fn test_rev_iterator() {
+        use iter::*;
+
+        let xs = [1, 2, 5, 10, 11];
+        let ys = [11, 10, 5, 2, 1];
+        let mut i = 0;
+        for &x in xs.rev_iter() {
+            assert_eq!(x, ys[i]);
+            i += 1;
+        }
+        assert_eq!(i, 5);
+    }
+
+    #[test]
+    fn test_mut_rev_iterator() {
+        use iter::*;
+        let mut xs = [1u, 2, 3, 4, 5];
+        for (i,x) in xs.mut_rev_iter().enumerate() {
+            *x += i;
+        }
+        assert!(xs == [5, 5, 5, 5, 5])
+    }
+
+    #[test]
+    fn test_move_iterator() {
+        use iter::*;
+        let xs = ~[1u,2,3,4,5];
+        assert_eq!(xs.move_iter().fold(0, |a: uint, b: uint| 10*a + b), 12345);
+    }
+
+    #[test]
+    fn test_move_rev_iterator() {
+        use iter::*;
+        let xs = ~[1u,2,3,4,5];
+        assert_eq!(xs.move_rev_iter().fold(0, |a: uint, b: uint| 10*a + b), 54321);
+    }
+
+    #[test]
+    fn test_splitator() {
+        let xs = &[1i,2,3,4,5];
+
+        assert_eq!(xs.split(|x| *x % 2 == 0).collect::<~[&[int]]>(),
+                   ~[&[1], &[3], &[5]]);
+        assert_eq!(xs.split(|x| *x == 1).collect::<~[&[int]]>(),
+                   ~[&[], &[2,3,4,5]]);
+        assert_eq!(xs.split(|x| *x == 5).collect::<~[&[int]]>(),
+                   ~[&[1,2,3,4], &[]]);
+        assert_eq!(xs.split(|x| *x == 10).collect::<~[&[int]]>(),
+                   ~[&[1,2,3,4,5]]);
+        assert_eq!(xs.split(|_| true).collect::<~[&[int]]>(),
+                   ~[&[], &[], &[], &[], &[], &[]]);
+
+        let xs: &[int] = &[];
+        assert_eq!(xs.split(|x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
+    }
+
+    #[test]
+    fn test_splitnator() {
+        let xs = &[1i,2,3,4,5];
+
+        assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<~[&[int]]>(),
+                   ~[&[1,2,3,4,5]]);
+        assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<~[&[int]]>(),
+                   ~[&[1], &[3,4,5]]);
+        assert_eq!(xs.splitn(3, |_| true).collect::<~[&[int]]>(),
+                   ~[&[], &[], &[], &[4,5]]);
+
+        let xs: &[int] = &[];
+        assert_eq!(xs.splitn(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
+    }
+
+    #[test]
+    fn test_rsplitator() {
+        let xs = &[1i,2,3,4,5];
+
+        assert_eq!(xs.rsplit(|x| *x % 2 == 0).collect::<~[&[int]]>(),
+                   ~[&[5], &[3], &[1]]);
+        assert_eq!(xs.rsplit(|x| *x == 1).collect::<~[&[int]]>(),
+                   ~[&[2,3,4,5], &[]]);
+        assert_eq!(xs.rsplit(|x| *x == 5).collect::<~[&[int]]>(),
+                   ~[&[], &[1,2,3,4]]);
+        assert_eq!(xs.rsplit(|x| *x == 10).collect::<~[&[int]]>(),
+                   ~[&[1,2,3,4,5]]);
+
+        let xs: &[int] = &[];
+        assert_eq!(xs.rsplit(|x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
+    }
+
+    #[test]
+    fn test_rsplitnator() {
+        let xs = &[1,2,3,4,5];
+
+        assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<~[&[int]]>(),
+                   ~[&[1,2,3,4,5]]);
+        assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<~[&[int]]>(),
+                   ~[&[5], &[1,2,3]]);
+        assert_eq!(xs.rsplitn(3, |_| true).collect::<~[&[int]]>(),
+                   ~[&[], &[], &[], &[1,2]]);
+
+        let xs: &[int] = &[];
+        assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
+    }
+
+    #[test]
+    fn test_windowsator() {
+        let v = &[1i,2,3,4];
+
+        assert_eq!(v.windows(2).collect::<~[&[int]]>(), ~[&[1,2], &[2,3], &[3,4]]);
+        assert_eq!(v.windows(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[2,3,4]]);
+        assert!(v.windows(6).next().is_none());
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_windowsator_0() {
+        let v = &[1i,2,3,4];
+        let _it = v.windows(0);
+    }
+
+    #[test]
+    fn test_chunksator() {
+        let v = &[1i,2,3,4,5];
+
+        assert_eq!(v.chunks(2).collect::<~[&[int]]>(), ~[&[1i,2], &[3,4], &[5]]);
+        assert_eq!(v.chunks(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[4,5]]);
+        assert_eq!(v.chunks(6).collect::<~[&[int]]>(), ~[&[1i,2,3,4,5]]);
+
+        assert_eq!(v.chunks(2).rev().collect::<~[&[int]]>(), ~[&[5i], &[3,4], &[1,2]]);
+        let it = v.chunks(2);
+        assert_eq!(it.indexable(), 3);
+        assert_eq!(it.idx(0).unwrap(), &[1,2]);
+        assert_eq!(it.idx(1).unwrap(), &[3,4]);
+        assert_eq!(it.idx(2).unwrap(), &[5]);
+        assert_eq!(it.idx(3), None);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_chunksator_0() {
+        let v = &[1i,2,3,4];
+        let _it = v.chunks(0);
+    }
+
+    #[test]
+    fn test_move_from() {
+        let mut a = [1,2,3,4,5];
+        let b = ~[6,7,8];
+        assert_eq!(a.move_from(b, 0, 3), 3);
+        assert!(a == [6,7,8,4,5]);
+        let mut a = [7,2,8,1];
+        let b = ~[3,1,4,1,5,9];
+        assert_eq!(a.move_from(b, 0, 6), 4);
+        assert!(a == [3,1,4,1]);
+        let mut a = [1,2,3,4];
+        let b = ~[5,6,7,8,9,0];
+        assert_eq!(a.move_from(b, 2, 3), 1);
+        assert!(a == [7,2,3,4]);
+        let mut a = [1,2,3,4,5];
+        let b = ~[5,6,7,8,9,0];
+        assert_eq!(a.mut_slice(2,4).move_from(b,1,6), 2);
+        assert!(a == [1,2,6,7,5]);
+    }
+
+    #[test]
+    fn test_copy_from() {
+        let mut a = [1,2,3,4,5];
+        let b = [6,7,8];
+        assert_eq!(a.copy_from(b), 3);
+        assert!(a == [6,7,8,4,5]);
+        let mut c = [7,2,8,1];
+        let d = [3,1,4,1,5,9];
+        assert_eq!(c.copy_from(d), 4);
+        assert!(c == [3,1,4,1]);
+    }
+
+    #[test]
+    fn test_reverse_part() {
+        let mut values = [1,2,3,4,5];
+        values.mut_slice(1, 4).reverse();
+        assert!(values == [1,4,3,2,5]);
+    }
+
+    #[test]
+    fn test_show() {
+        macro_rules! test_show_vec(
+            ($x:expr, $x_str:expr) => ({
+                let (x, x_str) = ($x, $x_str);
+                assert_eq!(format!("{}", x), x_str);
+                assert_eq!(format!("{}", x.as_slice()), x_str);
+            })
+        )
+        let empty: ~[int] = ~[];
+        test_show_vec!(empty, ~"[]");
+        test_show_vec!(~[1], ~"[1]");
+        test_show_vec!(~[1, 2, 3], ~"[1, 2, 3]");
+        test_show_vec!(~[~[], ~[1u], ~[1u, 1u]], ~"[[], [1], [1, 1]]");
+    }
+
+    #[test]
+    fn test_vec_default() {
+        use default::Default;
+        macro_rules! t (
+            ($ty:ty) => {{
+                let v: $ty = Default::default();
+                assert!(v.is_empty());
+            }}
+        );
+
+        t!(&[int]);
+        t!(~[int]);
+    }
+
+    #[test]
+    fn test_bytes_set_memory() {
+        use slice::bytes::MutableByteVector;
+        let mut values = [1u8,2,3,4,5];
+        values.mut_slice(0,5).set_memory(0xAB);
+        assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
+        values.mut_slice(2,4).set_memory(0xFF);
+        assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_overflow_does_not_cause_segfault() {
+        let mut v = ~[];
+        v.reserve_exact(-1);
+        v.push(1);
+        v.push(2);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_overflow_does_not_cause_segfault_managed() {
+        use rc::Rc;
+        let mut v = ~[Rc::new(1)];
+        v.reserve_exact(-1);
+        v.push(Rc::new(2));
+    }
+
+    #[test]
+    fn test_mut_split_at() {
+        let mut values = [1u8,2,3,4,5];
+        {
+            let (left, right) = values.mut_split_at(2);
+            assert!(left.slice(0, left.len()) == [1, 2]);
+            for p in left.mut_iter() {
+                *p += 1;
+            }
+
+            assert!(right.slice(0, right.len()) == [3, 4, 5]);
+            for p in right.mut_iter() {
+                *p += 2;
+            }
+        }
+
+        assert!(values == [2, 3, 5, 6, 7]);
+    }
+
+    #[deriving(Clone, Eq)]
+    struct Foo;
+
+    #[test]
+    fn test_iter_zero_sized() {
+        let mut v = ~[Foo, Foo, Foo];
+        assert_eq!(v.len(), 3);
+        let mut cnt = 0;
+
+        for f in v.iter() {
+            assert!(*f == Foo);
+            cnt += 1;
+        }
+        assert_eq!(cnt, 3);
+
+        for f in v.slice(1, 3).iter() {
+            assert!(*f == Foo);
+            cnt += 1;
+        }
+        assert_eq!(cnt, 5);
+
+        for f in v.mut_iter() {
+            assert!(*f == Foo);
+            cnt += 1;
+        }
+        assert_eq!(cnt, 8);
+
+        for f in v.move_iter() {
+            assert!(f == Foo);
+            cnt += 1;
+        }
+        assert_eq!(cnt, 11);
+
+        let xs = ~[Foo, Foo, Foo];
+        assert_eq!(format!("{:?}", xs.slice(0, 2).to_owned()),
+                   ~"~[slice::tests::Foo, slice::tests::Foo]");
+
+        let xs: [Foo, ..3] = [Foo, Foo, Foo];
+        assert_eq!(format!("{:?}", xs.slice(0, 2).to_owned()),
+                   ~"~[slice::tests::Foo, slice::tests::Foo]");
+        cnt = 0;
+        for f in xs.iter() {
+            assert!(*f == Foo);
+            cnt += 1;
+        }
+        assert!(cnt == 3);
+    }
+
+    #[test]
+    fn test_shrink_to_fit() {
+        let mut xs = ~[0, 1, 2, 3];
+        for i in range(4, 100) {
+            xs.push(i)
+        }
+        assert_eq!(xs.capacity(), 128);
+        xs.shrink_to_fit();
+        assert_eq!(xs.capacity(), 100);
+        assert_eq!(xs, range(0, 100).to_owned_vec());
+    }
+
+    #[test]
+    fn test_starts_with() {
+        assert!(bytes!("foobar").starts_with(bytes!("foo")));
+        assert!(!bytes!("foobar").starts_with(bytes!("oob")));
+        assert!(!bytes!("foobar").starts_with(bytes!("bar")));
+        assert!(!bytes!("foo").starts_with(bytes!("foobar")));
+        assert!(!bytes!("bar").starts_with(bytes!("foobar")));
+        assert!(bytes!("foobar").starts_with(bytes!("foobar")));
+        let empty: &[u8] = [];
+        assert!(empty.starts_with(empty));
+        assert!(!empty.starts_with(bytes!("foo")));
+        assert!(bytes!("foobar").starts_with(empty));
+    }
+
+    #[test]
+    fn test_ends_with() {
+        assert!(bytes!("foobar").ends_with(bytes!("bar")));
+        assert!(!bytes!("foobar").ends_with(bytes!("oba")));
+        assert!(!bytes!("foobar").ends_with(bytes!("foo")));
+        assert!(!bytes!("foo").ends_with(bytes!("foobar")));
+        assert!(!bytes!("bar").ends_with(bytes!("foobar")));
+        assert!(bytes!("foobar").ends_with(bytes!("foobar")));
+        let empty: &[u8] = [];
+        assert!(empty.ends_with(empty));
+        assert!(!empty.ends_with(bytes!("foo")));
+        assert!(bytes!("foobar").ends_with(empty));
+    }
+
+    #[test]
+    fn test_shift_ref() {
+        let mut x: &[int] = [1, 2, 3, 4, 5];
+        let h = x.shift_ref();
+        assert_eq!(*h.unwrap(), 1);
+        assert_eq!(x.len(), 4);
+        assert_eq!(x[0], 2);
+        assert_eq!(x[3], 5);
+
+        let mut y: &[int] = [];
+        assert_eq!(y.shift_ref(), None);
+    }
+
+    #[test]
+    fn test_pop_ref() {
+        let mut x: &[int] = [1, 2, 3, 4, 5];
+        let h = x.pop_ref();
+        assert_eq!(*h.unwrap(), 5);
+        assert_eq!(x.len(), 4);
+        assert_eq!(x[0], 1);
+        assert_eq!(x[3], 4);
+
+        let mut y: &[int] = [];
+        assert!(y.pop_ref().is_none());
+    }
+
+    #[test]
+    fn test_mut_splitator() {
+        let mut xs = [0,1,0,2,3,0,0,4,5,0];
+        assert_eq!(xs.mut_split(|x| *x == 0).len(), 6);
+        for slice in xs.mut_split(|x| *x == 0) {
+            slice.reverse();
+        }
+        assert!(xs == [0,1,0,3,2,0,0,5,4,0]);
+
+        let mut xs = [0,1,0,2,3,0,0,4,5,0,6,7];
+        for slice in xs.mut_split(|x| *x == 0).take(5) {
+            slice.reverse();
+        }
+        assert!(xs == [0,1,0,3,2,0,0,5,4,0,6,7]);
+    }
+
+    #[test]
+    fn test_mut_splitator_rev() {
+        let mut xs = [1,2,0,3,4,0,0,5,6,0];
+        for slice in xs.mut_split(|x| *x == 0).rev().take(4) {
+            slice.reverse();
+        }
+        assert!(xs == [1,2,0,4,3,0,0,6,5,0]);
+    }
+
+    #[test]
+    fn test_mut_chunks() {
+        let mut v = [0u8, 1, 2, 3, 4, 5, 6];
+        for (i, chunk) in v.mut_chunks(3).enumerate() {
+            for x in chunk.mut_iter() {
+                *x = i as u8;
+            }
+        }
+        let result = [0u8, 0, 0, 1, 1, 1, 2];
+        assert!(v == result);
+    }
+
+    #[test]
+    fn test_mut_chunks_rev() {
+        let mut v = [0u8, 1, 2, 3, 4, 5, 6];
+        for (i, chunk) in v.mut_chunks(3).rev().enumerate() {
+            for x in chunk.mut_iter() {
+                *x = i as u8;
+            }
+        }
+        let result = [2u8, 2, 2, 1, 1, 1, 0];
+        assert!(v == result);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_mut_chunks_0() {
+        let mut v = [1, 2, 3, 4];
+        let _it = v.mut_chunks(0);
+    }
+
+    #[test]
+    fn test_mut_shift_ref() {
+        let mut x: &mut [int] = [1, 2, 3, 4, 5];
+        let h = x.mut_shift_ref();
+        assert_eq!(*h.unwrap(), 1);
+        assert_eq!(x.len(), 4);
+        assert_eq!(x[0], 2);
+        assert_eq!(x[3], 5);
+
+        let mut y: &mut [int] = [];
+        assert!(y.mut_shift_ref().is_none());
+    }
+
+    #[test]
+    fn test_mut_pop_ref() {
+        let mut x: &mut [int] = [1, 2, 3, 4, 5];
+        let h = x.mut_pop_ref();
+        assert_eq!(*h.unwrap(), 5);
+        assert_eq!(x.len(), 4);
+        assert_eq!(x[0], 1);
+        assert_eq!(x[3], 4);
+
+        let mut y: &mut [int] = [];
+        assert!(y.mut_pop_ref().is_none());
+    }
+
+    #[test]
+    fn test_mut_last() {
+        let mut x = [1, 2, 3, 4, 5];
+        let h = x.mut_last();
+        assert_eq!(*h.unwrap(), 5);
+
+        let y: &mut [int] = [];
+        assert!(y.mut_last().is_none());
+    }
+}
+
+#[cfg(test)]
+mod bench {
+    extern crate test;
+    use self::test::BenchHarness;
+    use mem;
+    use prelude::*;
+    use ptr;
+    use rand::{weak_rng, Rng};
+    use slice;
+
+    #[bench]
+    fn iterator(bh: &mut BenchHarness) {
+        // peculiar numbers to stop LLVM from optimising the summation
+        // out.
+        let v = slice::from_fn(100, |i| i ^ (i << 1) ^ (i >> 1));
+
+        bh.iter(|| {
+            let mut sum = 0;
+            for x in v.iter() {
+                sum += *x;
+            }
+            // sum == 11806, to stop dead code elimination.
+            if sum == 0 {fail!()}
+        })
+    }
+
+    #[bench]
+    fn mut_iterator(bh: &mut BenchHarness) {
+        let mut v = slice::from_elem(100, 0);
+
+        bh.iter(|| {
+            let mut i = 0;
+            for x in v.mut_iter() {
+                *x = i;
+                i += 1;
+            }
+        })
+    }
+
+    #[bench]
+    fn add(bh: &mut BenchHarness) {
+        let xs: &[int] = [5, ..10];
+        let ys: &[int] = [5, ..10];
+        bh.iter(|| {
+            xs + ys;
+        });
+    }
+
+    #[bench]
+    fn concat(bh: &mut BenchHarness) {
+        let xss: &[~[uint]] = slice::from_fn(100, |i| range(0, i).collect());
+        bh.iter(|| {
+            let _ = xss.concat_vec();
+        });
+    }
+
+    #[bench]
+    fn connect(bh: &mut BenchHarness) {
+        let xss: &[~[uint]] = slice::from_fn(100, |i| range(0, i).collect());
+        bh.iter(|| {
+            let _ = xss.connect_vec(&0);
+        });
+    }
+
+    #[bench]
+    fn push(bh: &mut BenchHarness) {
+        let mut vec: ~[uint] = ~[0u];
+        bh.iter(|| {
+            vec.push(0);
+            &vec
+        })
+    }
+
+    #[bench]
+    fn starts_with_same_vector(bh: &mut BenchHarness) {
+        let vec: ~[uint] = slice::from_fn(100, |i| i);
+        bh.iter(|| {
+            vec.starts_with(vec)
+        })
+    }
+
+    #[bench]
+    fn starts_with_single_element(bh: &mut BenchHarness) {
+        let vec: ~[uint] = ~[0u];
+        bh.iter(|| {
+            vec.starts_with(vec)
+        })
+    }
+
+    #[bench]
+    fn starts_with_diff_one_element_at_end(bh: &mut BenchHarness) {
+        let vec: ~[uint] = slice::from_fn(100, |i| i);
+        let mut match_vec: ~[uint] = slice::from_fn(99, |i| i);
+        match_vec.push(0);
+        bh.iter(|| {
+            vec.starts_with(match_vec)
+        })
+    }
+
+    #[bench]
+    fn ends_with_same_vector(bh: &mut BenchHarness) {
+        let vec: ~[uint] = slice::from_fn(100, |i| i);
+        bh.iter(|| {
+            vec.ends_with(vec)
+        })
+    }
+
+    #[bench]
+    fn ends_with_single_element(bh: &mut BenchHarness) {
+        let vec: ~[uint] = ~[0u];
+        bh.iter(|| {
+            vec.ends_with(vec)
+        })
+    }
+
+    #[bench]
+    fn ends_with_diff_one_element_at_beginning(bh: &mut BenchHarness) {
+        let vec: ~[uint] = slice::from_fn(100, |i| i);
+        let mut match_vec: ~[uint] = slice::from_fn(100, |i| i);
+        match_vec[0] = 200;
+        bh.iter(|| {
+            vec.starts_with(match_vec)
+        })
+    }
+
+    #[bench]
+    fn contains_last_element(bh: &mut BenchHarness) {
+        let vec: ~[uint] = slice::from_fn(100, |i| i);
+        bh.iter(|| {
+            vec.contains(&99u)
+        })
+    }
+
+    #[bench]
+    fn zero_1kb_from_elem(bh: &mut BenchHarness) {
+        bh.iter(|| {
+            let _v: ~[u8] = slice::from_elem(1024, 0u8);
+        });
+    }
+
+    #[bench]
+    fn zero_1kb_set_memory(bh: &mut BenchHarness) {
+        bh.iter(|| {
+            let mut v: ~[u8] = slice::with_capacity(1024);
+            unsafe {
+                let vp = v.as_mut_ptr();
+                ptr::set_memory(vp, 0, 1024);
+                v.set_len(1024);
+            }
+            v
+        });
+    }
+
+    #[bench]
+    fn zero_1kb_fixed_repeat(bh: &mut BenchHarness) {
+        bh.iter(|| {
+            ~[0u8, ..1024]
+        });
+    }
+
+    #[bench]
+    fn zero_1kb_loop_set(bh: &mut BenchHarness) {
+        // Slower because the { len, cap, [0 x T] }* repr allows a pointer to the length
+        // field to be aliased (in theory) and prevents LLVM from optimizing loads away.
+        bh.iter(|| {
+            let mut v: ~[u8] = slice::with_capacity(1024);
+            unsafe {
+                v.set_len(1024);
+            }
+            for i in range(0, 1024) {
+                v[i] = 0;
+            }
+        });
+    }
+
+    #[bench]
+    fn zero_1kb_mut_iter(bh: &mut BenchHarness) {
+        bh.iter(|| {
+            let mut v: ~[u8] = slice::with_capacity(1024);
+            unsafe {
+                v.set_len(1024);
+            }
+            for x in v.mut_iter() {
+                *x = 0;
+            }
+            v
+        });
+    }
+
+    #[bench]
+    fn random_inserts(bh: &mut BenchHarness) {
+        let mut rng = weak_rng();
+        bh.iter(|| {
+                let mut v = slice::from_elem(30, (0u, 0u));
+                for _ in range(0, 100) {
+                    let l = v.len();
+                    v.insert(rng.gen::<uint>() % (l + 1),
+                             (1, 1));
+                }
+            })
+    }
+    #[bench]
+    fn random_removes(bh: &mut BenchHarness) {
+        let mut rng = weak_rng();
+        bh.iter(|| {
+                let mut v = slice::from_elem(130, (0u, 0u));
+                for _ in range(0, 100) {
+                    let l = v.len();
+                    v.remove(rng.gen::<uint>() % l);
+                }
+            })
+    }
+
+    #[bench]
+    fn sort_random_small(bh: &mut BenchHarness) {
+        let mut rng = weak_rng();
+        bh.iter(|| {
+            let mut v: ~[u64] = rng.gen_vec(5);
+            v.sort();
+        });
+        bh.bytes = 5 * mem::size_of::<u64>() as u64;
+    }
+
+    #[bench]
+    fn sort_random_medium(bh: &mut BenchHarness) {
+        let mut rng = weak_rng();
+        bh.iter(|| {
+            let mut v: ~[u64] = rng.gen_vec(100);
+            v.sort();
+        });
+        bh.bytes = 100 * mem::size_of::<u64>() as u64;
+    }
+
+    #[bench]
+    fn sort_random_large(bh: &mut BenchHarness) {
+        let mut rng = weak_rng();
+        bh.iter(|| {
+            let mut v: ~[u64] = rng.gen_vec(10000);
+            v.sort();
+        });
+        bh.bytes = 10000 * mem::size_of::<u64>() as u64;
+    }
+
+    #[bench]
+    fn sort_sorted(bh: &mut BenchHarness) {
+        let mut v = slice::from_fn(10000, |i| i);
+        bh.iter(|| {
+            v.sort();
+        });
+        bh.bytes = (v.len() * mem::size_of_val(&v[0])) as u64;
+    }
+
+    type BigSortable = (u64,u64,u64,u64);
+
+    #[bench]
+    fn sort_big_random_small(bh: &mut BenchHarness) {
+        let mut rng = weak_rng();
+        bh.iter(|| {
+            let mut v: ~[BigSortable] = rng.gen_vec(5);
+            v.sort();
+        });
+        bh.bytes = 5 * mem::size_of::<BigSortable>() as u64;
+    }
+
+    #[bench]
+    fn sort_big_random_medium(bh: &mut BenchHarness) {
+        let mut rng = weak_rng();
+        bh.iter(|| {
+            let mut v: ~[BigSortable] = rng.gen_vec(100);
+            v.sort();
+        });
+        bh.bytes = 100 * mem::size_of::<BigSortable>() as u64;
+    }
+
+    #[bench]
+    fn sort_big_random_large(bh: &mut BenchHarness) {
+        let mut rng = weak_rng();
+        bh.iter(|| {
+            let mut v: ~[BigSortable] = rng.gen_vec(10000);
+            v.sort();
+        });
+        bh.bytes = 10000 * mem::size_of::<BigSortable>() as u64;
+    }
+
+    #[bench]
+    fn sort_big_sorted(bh: &mut BenchHarness) {
+        let mut v = slice::from_fn(10000u, |i| (i, i, i, i));
+        bh.iter(|| {
+            v.sort();
+        });
+        bh.bytes = (v.len() * mem::size_of_val(&v[0])) as u64;
+    }
+}
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index ccd08e8a716..37aad3f9411 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -99,9 +99,9 @@ use option::{None, Option, Some};
 use ptr;
 use ptr::RawPtr;
 use from_str::FromStr;
-use vec;
-use vec::{OwnedVector, OwnedCloneableVector, ImmutableVector, MutableVector};
-use vec_ng::Vec;
+use slice;
+use slice::{OwnedVector, OwnedCloneableVector, ImmutableVector, MutableVector};
+use vec::Vec;
 use default::Default;
 use raw::Repr;
 
@@ -360,7 +360,7 @@ pub type RevCharOffsets<'a> = Rev<CharOffsets<'a>>;
 /// External iterator for a string's bytes.
 /// Use with the `std::iter` module.
 pub type Bytes<'a> =
-    Map<'a, &'a u8, u8, vec::Items<'a, u8>>;
+    Map<'a, &'a u8, u8, slice::Items<'a, u8>>;
 
 /// External iterator for a string's bytes in reverse order.
 /// Use with the `std::iter` module.
@@ -738,7 +738,7 @@ Section: Misc
 /// `iter` reset such that it is pointing at the first byte in the
 /// invalid sequence.
 #[inline(always)]
-fn run_utf8_validation_iterator(iter: &mut vec::Items<u8>) -> bool {
+fn run_utf8_validation_iterator(iter: &mut slice::Items<u8>) -> bool {
     loop {
         // save the current thing we're pointing at.
         let old = *iter;
@@ -855,7 +855,7 @@ pub fn is_utf16(v: &[u16]) -> bool {
 /// of `u16`s.
 #[deriving(Clone)]
 pub struct UTF16Items<'a> {
-    priv iter: vec::Items<'a, u16>
+    priv iter: slice::Items<'a, u16>
 }
 /// The possibilities for values decoded from a `u16` stream.
 #[deriving(Eq, TotalEq, Clone, Show)]
@@ -1025,7 +1025,7 @@ pub fn from_utf16_lossy(v: &[u16]) -> ~str {
 #[inline]
 pub fn with_capacity(capacity: uint) -> ~str {
     unsafe {
-        cast::transmute(vec::with_capacity::<~[u8]>(capacity))
+        cast::transmute(slice::with_capacity::<~[u8]>(capacity))
     }
 }
 
@@ -1360,13 +1360,13 @@ pub mod raw {
     use ptr::RawPtr;
     use option::{Option, Some, None};
     use str::{is_utf8, OwnedStr, StrSlice};
-    use vec;
-    use vec::{MutableVector, ImmutableVector, OwnedVector};
+    use slice;
+    use slice::{MutableVector, ImmutableVector, OwnedVector};
     use raw::Slice;
 
     /// 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: ~[u8] = vec::with_capacity(len);
+        let mut v: ~[u8] = slice::with_capacity(len);
         ptr::copy_memory(v.as_mut_ptr(), buf, len);
         v.set_len(len);
 
@@ -1463,7 +1463,7 @@ pub mod raw {
     /// The caller must preserve the valid UTF-8 property.
     #[inline]
     pub unsafe fn push_bytes(s: &mut ~str, bytes: &[u8]) {
-        vec::bytes::push_bytes(as_owned_vec(s), bytes);
+        slice::bytes::push_bytes(as_owned_vec(s), bytes);
     }
 
     /// Removes the last byte from a string and returns it.
@@ -2603,7 +2603,7 @@ impl<'a> StrSlice<'a> for &'a str {
     fn to_owned(&self) -> ~str {
         let len = self.len();
         unsafe {
-            let mut v = vec::with_capacity(len);
+            let mut v = slice::with_capacity(len);
 
             ptr::copy_memory(v.as_mut_ptr(), self.as_ptr(), len);
             v.set_len(len);
@@ -2766,7 +2766,7 @@ impl<'a> StrSlice<'a> for &'a str {
         if slen == 0 { return tlen; }
         if tlen == 0 { return slen; }
 
-        let mut dcol = vec::from_fn(tlen + 1, |x| x);
+        let mut dcol = slice::from_fn(tlen + 1, |x| x);
 
         for (i, sc) in self.chars().enumerate() {
 
@@ -2921,7 +2921,7 @@ impl OwnedStr for ~str {
             // Attempt to not use an intermediate buffer by just pushing bytes
             // directly onto this string.
             let write_ptr = v.as_mut_ptr().offset(cur_len as int);
-            let used = vec::raw::mut_buf_as_slice(write_ptr, 4, |slc| c.encode_utf8(slc));
+            let used = slice::raw::mut_buf_as_slice(write_ptr, 4, |slc| c.encode_utf8(slc));
 
             v.set_len(cur_len + used);
         }
@@ -4667,7 +4667,7 @@ mod bench {
 
     #[bench]
     fn from_utf8_lossy_100_invalid(bh: &mut BenchHarness) {
-        let s = ::vec::from_elem(100, 0xF5u8);
+        let s = ::slice::from_elem(100, 0xF5u8);
         bh.iter(|| {
             let _ = from_utf8_lossy(s);
         });
diff --git a/src/libstd/sync/arc.rs b/src/libstd/sync/arc.rs
index 56c71a5e4ff..92974005305 100644
--- a/src/libstd/sync/arc.rs
+++ b/src/libstd/sync/arc.rs
@@ -27,7 +27,8 @@ use kinds::Send;
 use ops::Drop;
 use ptr::RawPtr;
 use sync::atomics::{fence, AtomicUint, Relaxed, Acquire, Release};
-use vec;
+use slice;
+use ty::Unsafe;
 
 /// An atomically reference counted pointer.
 ///
@@ -39,11 +40,14 @@ pub struct UnsafeArc<T> {
 
 struct ArcData<T> {
     count: AtomicUint,
-    data: T,
+    data: Unsafe<T>,
 }
 
 unsafe fn new_inner<T: Send>(data: T, refcount: uint) -> *mut ArcData<T> {
-    let data = ~ArcData { count: AtomicUint::new(refcount), data: data };
+    let data = ~ArcData {
+                    count: AtomicUint::new(refcount),
+                    data: Unsafe::new(data)
+                 };
     cast::transmute(data)
 }
 
@@ -69,7 +73,7 @@ impl<T: Send> UnsafeArc<T> {
                 ~[] // need to free data here
             } else {
                 let ptr = new_inner(data, num_handles);
-                vec::from_fn(num_handles, |_| UnsafeArc { data: ptr })
+                slice::from_fn(num_handles, |_| UnsafeArc { data: ptr })
             }
         }
     }
@@ -82,7 +86,7 @@ impl<T: Send> UnsafeArc<T> {
         unsafe {
             // FIXME(#12049): this needs some sort of debug assertion
             if cfg!(test) { assert!((*self.data).count.load(Relaxed) > 0); }
-            return &mut (*self.data).data as *mut T;
+            return (*self.data).data.get();
         }
     }
 
@@ -93,7 +97,7 @@ impl<T: Send> UnsafeArc<T> {
         unsafe {
             // FIXME(#12049): this needs some sort of debug assertion
             if cfg!(test) { assert!((*self.data).count.load(Relaxed) > 0); }
-            return &(*self.data).data as *T;
+            return (*self.data).data.get() as *T;
         }
     }
 
diff --git a/src/libstd/sync/atomics.rs b/src/libstd/sync/atomics.rs
index 500ae04869b..cbdb38c1c58 100644
--- a/src/libstd/sync/atomics.rs
+++ b/src/libstd/sync/atomics.rs
@@ -114,35 +114,36 @@ use cast;
 use std::kinds::marker;
 use option::{Option,Some,None};
 use ops::Drop;
+use ty::Unsafe;
 
 /// An atomic boolean type.
 pub struct AtomicBool {
-    priv v: uint,
+    priv v: Unsafe<uint>,
     priv nopod: marker::NoPod
 }
 
 /// A signed atomic integer type, supporting basic atomic arithmetic operations
 pub struct AtomicInt {
-    priv v: int,
+    priv v: Unsafe<int>,
     priv nopod: marker::NoPod
 }
 
 /// An unsigned atomic integer type, supporting basic atomic arithmetic operations
 pub struct AtomicUint {
-    priv v: uint,
+    priv v: Unsafe<uint>,
     priv nopod: marker::NoPod
 }
 
 /// An unsigned atomic integer type that is forced to be 64-bits. This does not
 /// support all operations.
 pub struct AtomicU64 {
-    priv v: u64,
+    priv v: Unsafe<u64>,
     priv nopod: marker::NoPod
 }
 
 /// An unsafe atomic pointer. Only supports basic atomic operations
 pub struct AtomicPtr<T> {
-    priv p: uint,
+    priv p: Unsafe<uint>,
     priv nopod: marker::NoPod
 }
 
@@ -152,7 +153,7 @@ pub struct AtomicPtr<T> {
 /// owned heap objects across tasks.
 #[unsafe_no_drop_flag]
 pub struct AtomicOption<T> {
-    priv p: uint,
+    priv p: Unsafe<uint>,
 }
 
 /// Atomic memory orderings
@@ -186,13 +187,21 @@ pub enum Ordering {
 }
 
 /// An `AtomicBool` initialized to `false`
-pub static INIT_ATOMIC_BOOL : AtomicBool = AtomicBool { v: 0, nopod: marker::NoPod };
+pub static INIT_ATOMIC_BOOL : AtomicBool = AtomicBool { v: Unsafe{value: 0,
+                                                                  marker1: marker::InvariantType},
+                                                        nopod: marker::NoPod };
 /// An `AtomicInt` initialized to `0`
-pub static INIT_ATOMIC_INT  : AtomicInt  = AtomicInt  { v: 0, nopod: marker::NoPod };
+pub static INIT_ATOMIC_INT  : AtomicInt  = AtomicInt  { v: Unsafe{value: 0,
+                                                                  marker1: marker::InvariantType},
+                                                        nopod: marker::NoPod };
 /// An `AtomicUint` initialized to `0`
-pub static INIT_ATOMIC_UINT : AtomicUint = AtomicUint { v: 0, nopod: marker::NoPod };
+pub static INIT_ATOMIC_UINT : AtomicUint = AtomicUint { v: Unsafe{value: 0,
+                                                                  marker1: marker::InvariantType},
+                                                        nopod: marker::NoPod };
 /// An `AtomicU64` initialized to `0`
-pub static INIT_ATOMIC_U64 : AtomicU64 = AtomicU64 { v: 0, nopod: marker::NoPod };
+pub static INIT_ATOMIC_U64 : AtomicU64 = AtomicU64 { v: Unsafe{value: 0,
+                                                               marker1: marker::InvariantType},
+                                                     nopod: marker::NoPod };
 
 
 // NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
@@ -201,13 +210,14 @@ static UINT_TRUE: uint = -1;
 impl AtomicBool {
     /// Create a new `AtomicBool`
     pub fn new(v: bool) -> AtomicBool {
-        AtomicBool { v: if v { UINT_TRUE } else { 0 }, nopod: marker::NoPod }
+        let val = if v { UINT_TRUE } else { 0 };
+        AtomicBool { v: Unsafe::new(val), nopod: marker::NoPod }
     }
 
     /// Load the value
     #[inline]
     pub fn load(&self, order: Ordering) -> bool {
-        unsafe { atomic_load(&self.v, order) > 0 }
+        unsafe { atomic_load(&*self.v.get(), order) > 0 }
     }
 
     /// Store the value
@@ -215,7 +225,7 @@ impl AtomicBool {
     pub fn store(&mut self, val: bool, order: Ordering) {
         let val = if val { UINT_TRUE } else { 0 };
 
-        unsafe { atomic_store(&mut self.v, val, order); }
+        unsafe { atomic_store(&mut *self.v.get(), val, order); }
     }
 
     /// Store a value, returning the old value
@@ -223,7 +233,7 @@ impl AtomicBool {
     pub fn swap(&mut self, val: bool, order: Ordering) -> bool {
         let val = if val { UINT_TRUE } else { 0 };
 
-        unsafe { atomic_swap(&mut self.v, val, order) > 0 }
+        unsafe { atomic_swap(&mut *self.v.get(), val, order) > 0 }
     }
 
     /// If the current value is the same as expected, store a new value
@@ -276,7 +286,7 @@ impl AtomicBool {
         let old = if old { UINT_TRUE } else { 0 };
         let new = if new { UINT_TRUE } else { 0 };
 
-        unsafe { atomic_compare_and_swap(&mut self.v, old, new, order) > 0 }
+        unsafe { atomic_compare_and_swap(&mut *self.v.get(), old, new, order) > 0 }
     }
 
     /// A logical "and" operation
@@ -306,7 +316,7 @@ impl AtomicBool {
     pub fn fetch_and(&mut self, val: bool, order: Ordering) -> bool {
         let val = if val { UINT_TRUE } else { 0 };
 
-        unsafe { atomic_and(&mut self.v, val, order) > 0 }
+        unsafe { atomic_and(&mut *self.v.get(), val, order) > 0 }
     }
 
     /// A logical "nand" operation
@@ -337,7 +347,7 @@ impl AtomicBool {
     pub fn fetch_nand(&mut self, val: bool, order: Ordering) -> bool {
         let val = if val { UINT_TRUE } else { 0 };
 
-        unsafe { atomic_nand(&mut self.v, val, order) > 0 }
+        unsafe { atomic_nand(&mut *self.v.get(), val, order) > 0 }
     }
 
     /// A logical "or" operation
@@ -367,7 +377,7 @@ impl AtomicBool {
     pub fn fetch_or(&mut self, val: bool, order: Ordering) -> bool {
         let val = if val { UINT_TRUE } else { 0 };
 
-        unsafe { atomic_or(&mut self.v, val, order) > 0 }
+        unsafe { atomic_or(&mut *self.v.get(), val, order) > 0 }
     }
 
     /// A logical "xor" operation
@@ -397,32 +407,32 @@ impl AtomicBool {
     pub fn fetch_xor(&mut self, val: bool, order: Ordering) -> bool {
         let val = if val { UINT_TRUE } else { 0 };
 
-        unsafe { atomic_xor(&mut self.v, val, order) > 0 }
+        unsafe { atomic_xor(&mut *self.v.get(), val, order) > 0 }
     }
 }
 
 impl AtomicInt {
     /// Create a new `AtomicInt`
     pub fn new(v: int) -> AtomicInt {
-        AtomicInt { v:v, nopod: marker::NoPod}
+        AtomicInt {v: Unsafe::new(v), nopod: marker::NoPod}
     }
 
     /// Load the value
     #[inline]
     pub fn load(&self, order: Ordering) -> int {
-        unsafe { atomic_load(&self.v, order) }
+        unsafe { atomic_load(&*self.v.get(), order) }
     }
 
     /// Store the value
     #[inline]
     pub fn store(&mut self, val: int, order: Ordering) {
-        unsafe { atomic_store(&mut self.v, val, order); }
+        unsafe { atomic_store(&mut *self.v.get(), val, order); }
     }
 
     /// Store a value, returning the old value
     #[inline]
     pub fn swap(&mut self, val: int, order: Ordering) -> int {
-        unsafe { atomic_swap(&mut self.v, val, order) }
+        unsafe { atomic_swap(&mut *self.v.get(), val, order) }
     }
 
     /// If the current value is the same as expected, store a new value
@@ -432,7 +442,7 @@ impl AtomicInt {
     /// If the return value is equal to `old` then the value was updated.
     #[inline]
     pub fn compare_and_swap(&mut self, old: int, new: int, order: Ordering) -> int {
-        unsafe { atomic_compare_and_swap(&mut self.v, old, new, order) }
+        unsafe { atomic_compare_and_swap(&mut *self.v.get(), old, new, order) }
     }
 
     /// Add to the current value, returning the previous
@@ -448,7 +458,7 @@ impl AtomicInt {
     /// ```
     #[inline]
     pub fn fetch_add(&mut self, val: int, order: Ordering) -> int {
-        unsafe { atomic_add(&mut self.v, val, order) }
+        unsafe { atomic_add(&mut *self.v.get(), val, order) }
     }
 
     /// Subtract from the current value, returning the previous
@@ -464,7 +474,7 @@ impl AtomicInt {
     /// ```
     #[inline]
     pub fn fetch_sub(&mut self, val: int, order: Ordering) -> int {
-        unsafe { atomic_sub(&mut self.v, val, order) }
+        unsafe { atomic_sub(&mut *self.v.get(), val, order) }
     }
 }
 
@@ -474,62 +484,62 @@ impl AtomicInt {
 #[cfg(not(target_arch = "mips"))]
 impl AtomicU64 {
     pub fn new(v: u64) -> AtomicU64 {
-        AtomicU64 { v:v, nopod: marker::NoPod }
+        AtomicU64 { v: Unsafe::new(v), nopod: marker::NoPod }
     }
 
     #[inline]
     pub fn load(&self, order: Ordering) -> u64 {
-        unsafe { atomic_load(&self.v, order) }
+        unsafe { atomic_load(&*self.v.get(), order) }
     }
 
     #[inline]
     pub fn store(&mut self, val: u64, order: Ordering) {
-        unsafe { atomic_store(&mut self.v, val, order); }
+        unsafe { atomic_store(&mut *self.v.get(), val, order); }
     }
 
     #[inline]
     pub fn swap(&mut self, val: u64, order: Ordering) -> u64 {
-        unsafe { atomic_swap(&mut self.v, val, order) }
+        unsafe { atomic_swap(&mut *self.v.get(), val, order) }
     }
 
     #[inline]
     pub fn compare_and_swap(&mut self, old: u64, new: u64, order: Ordering) -> u64 {
-        unsafe { atomic_compare_and_swap(&mut self.v, old, new, order) }
+        unsafe { atomic_compare_and_swap(&mut *self.v.get(), old, new, order) }
     }
 
     #[inline]
     pub fn fetch_add(&mut self, val: u64, order: Ordering) -> u64 {
-        unsafe { atomic_add(&mut self.v, val, order) }
+        unsafe { atomic_add(&mut *self.v.get(), val, order) }
     }
 
     #[inline]
     pub fn fetch_sub(&mut self, val: u64, order: Ordering) -> u64 {
-        unsafe { atomic_sub(&mut self.v, val, order) }
+        unsafe { atomic_sub(&mut *self.v.get(), val, order) }
     }
 }
 
 impl AtomicUint {
     /// Create a new `AtomicUint`
     pub fn new(v: uint) -> AtomicUint {
-        AtomicUint { v:v, nopod: marker::NoPod }
+        AtomicUint { v: Unsafe::new(v), nopod: marker::NoPod }
     }
 
     /// Load the value
     #[inline]
     pub fn load(&self, order: Ordering) -> uint {
-        unsafe { atomic_load(&self.v, order) }
+        unsafe { atomic_load(&*self.v.get(), order) }
     }
 
     /// Store the value
     #[inline]
     pub fn store(&mut self, val: uint, order: Ordering) {
-        unsafe { atomic_store(&mut self.v, val, order); }
+        unsafe { atomic_store(&mut *self.v.get(), val, order); }
     }
 
     /// Store a value, returning the old value
     #[inline]
     pub fn swap(&mut self, val: uint, order: Ordering) -> uint {
-        unsafe { atomic_swap(&mut self.v, val, order) }
+        unsafe { atomic_swap(&mut *self.v.get(), val, order) }
     }
 
     /// If the current value is the same as expected, store a new value
@@ -539,7 +549,7 @@ impl AtomicUint {
     /// If the return value is equal to `old` then the value was updated.
     #[inline]
     pub fn compare_and_swap(&mut self, old: uint, new: uint, order: Ordering) -> uint {
-        unsafe { atomic_compare_and_swap(&mut self.v, old, new, order) }
+        unsafe { atomic_compare_and_swap(&mut *self.v.get(), old, new, order) }
     }
 
     /// Add to the current value, returning the previous
@@ -555,7 +565,7 @@ impl AtomicUint {
     /// ```
     #[inline]
     pub fn fetch_add(&mut self, val: uint, order: Ordering) -> uint {
-        unsafe { atomic_add(&mut self.v, val, order) }
+        unsafe { atomic_add(&mut *self.v.get(), val, order) }
     }
 
     /// Subtract from the current value, returning the previous
@@ -571,34 +581,34 @@ impl AtomicUint {
     /// ```
     #[inline]
     pub fn fetch_sub(&mut self, val: uint, order: Ordering) -> uint {
-        unsafe { atomic_sub(&mut self.v, val, order) }
+        unsafe { atomic_sub(&mut *self.v.get(), val, order) }
     }
 }
 
 impl<T> AtomicPtr<T> {
     /// Create a new `AtomicPtr`
     pub fn new(p: *mut T) -> AtomicPtr<T> {
-        AtomicPtr { p: p as uint, nopod: marker::NoPod }
+        AtomicPtr { p: Unsafe::new(p as uint), nopod: marker::NoPod }
     }
 
     /// Load the value
     #[inline]
     pub fn load(&self, order: Ordering) -> *mut T {
         unsafe {
-            atomic_load(&self.p, order) as *mut T
+            atomic_load(&*self.p.get(), order) as *mut T
         }
     }
 
     /// Store the value
     #[inline]
     pub fn store(&mut self, ptr: *mut T, order: Ordering) {
-        unsafe { atomic_store(&mut self.p, ptr as uint, order); }
+        unsafe { atomic_store(&mut *self.p.get(), ptr as uint, order); }
     }
 
     /// Store a value, returning the old value
     #[inline]
     pub fn swap(&mut self, ptr: *mut T, order: Ordering) -> *mut T {
-        unsafe { atomic_swap(&mut self.p, ptr as uint, order) as *mut T }
+        unsafe { atomic_swap(&mut *self.p.get(), ptr as uint, order) as *mut T }
     }
 
     /// If the current value is the same as expected, store a new value
@@ -609,7 +619,7 @@ impl<T> AtomicPtr<T> {
     #[inline]
     pub fn compare_and_swap(&mut self, old: *mut T, new: *mut T, order: Ordering) -> *mut T {
         unsafe {
-            atomic_compare_and_swap(&mut self.p, old as uint,
+            atomic_compare_and_swap(&mut *self.p.get(), old as uint,
                                     new as uint, order) as *mut T
         }
     }
@@ -618,11 +628,11 @@ impl<T> AtomicPtr<T> {
 impl<T> AtomicOption<T> {
     /// Create a new `AtomicOption`
     pub fn new(p: ~T) -> AtomicOption<T> {
-        unsafe { AtomicOption { p: cast::transmute(p) } }
+        unsafe { AtomicOption { p: Unsafe::new(cast::transmute(p)) } }
     }
 
     /// Create a new `AtomicOption` that doesn't contain a value
-    pub fn empty() -> AtomicOption<T> { AtomicOption { p: 0 } }
+    pub fn empty() -> AtomicOption<T> { AtomicOption { p: Unsafe::new(0) } }
 
     /// Store a value, returning the old value
     #[inline]
@@ -630,7 +640,7 @@ impl<T> AtomicOption<T> {
         unsafe {
             let val = cast::transmute(val);
 
-            let p = atomic_swap(&mut self.p, val, order);
+            let p = atomic_swap(&mut *self.p.get(), val, order);
             if p as uint == 0 {
                 None
             } else {
@@ -655,7 +665,7 @@ impl<T> AtomicOption<T> {
         unsafe {
             let val = cast::transmute(val);
             let expected = cast::transmute(0);
-            let oldval = atomic_compare_and_swap(&mut self.p, expected, val, order);
+            let oldval = atomic_compare_and_swap(&mut *self.p.get(), expected, val, order);
             if oldval == expected {
                 None
             } else {
@@ -670,7 +680,7 @@ impl<T> AtomicOption<T> {
     /// result does not get invalidated by another task after this returns.
     #[inline]
     pub fn is_empty(&mut self, order: Ordering) -> bool {
-        unsafe { atomic_load(&self.p, order) as uint == 0 }
+        unsafe { atomic_load(&*self.p.get(), order) as uint == 0 }
     }
 }
 
diff --git a/src/libstd/sync/deque.rs b/src/libstd/sync/deque.rs
index 1cd6920612e..658ee48af1a 100644
--- a/src/libstd/sync/deque.rs
+++ b/src/libstd/sync/deque.rs
@@ -61,7 +61,7 @@ use ptr::RawPtr;
 use sync::arc::UnsafeArc;
 use sync::atomics::{AtomicInt, AtomicPtr, SeqCst};
 use unstable::sync::Exclusive;
-use vec::{OwnedVector, ImmutableVector};
+use slice::{OwnedVector, ImmutableVector};
 
 // Once the queue is less than 1/K full, then it will be downsized. Note that
 // the deque requires that this number be less than 2.
@@ -404,7 +404,7 @@ mod tests {
     use rand::Rng;
     use sync::atomics::{AtomicBool, INIT_ATOMIC_BOOL, SeqCst,
                         AtomicUint, INIT_ATOMIC_UINT};
-    use vec;
+    use slice;
 
     #[test]
     fn smoke() {
@@ -600,7 +600,7 @@ mod tests {
         let mut pool = BufferPool::<(int, uint)>::new();
         let (mut w, s) = pool.deque();
 
-        let (threads, hits) = vec::unzip(range(0, NTHREADS).map(|_| {
+        let (threads, hits) = slice::unzip(range(0, NTHREADS).map(|_| {
             let s = s.clone();
             let unique_box = ~AtomicUint::new(0);
             let thread_box = unsafe {
diff --git a/src/libstd/sync/mpmc_bounded_queue.rs b/src/libstd/sync/mpmc_bounded_queue.rs
index ad0434c634a..95f592baff0 100644
--- a/src/libstd/sync/mpmc_bounded_queue.rs
+++ b/src/libstd/sync/mpmc_bounded_queue.rs
@@ -35,7 +35,7 @@ use num::next_power_of_two;
 use option::{Option, Some, None};
 use sync::arc::UnsafeArc;
 use sync::atomics::{AtomicUint,Relaxed,Release,Acquire};
-use vec;
+use slice;
 
 struct Node<T> {
     sequence: AtomicUint,
@@ -69,8 +69,8 @@ impl<T: Send> State<T> {
         } else {
             capacity
         };
-        let buffer = vec::from_fn(capacity, |i:uint| {
-            Node{sequence:AtomicUint::new(i),value:None}
+        let buffer = slice::from_fn(capacity, |i| {
+            Node { sequence:AtomicUint::new(i), value: None }
         });
         State{
             pad0: [0, ..64],
diff --git a/src/libstd/ty.rs b/src/libstd/ty.rs
new file mode 100644
index 00000000000..344235053f3
--- /dev/null
+++ b/src/libstd/ty.rs
@@ -0,0 +1,82 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Types dealing with unsafe actions.
+
+use cast;
+use kinds::marker;
+
+/// Unsafe type that wraps a type T and indicates unsafe interior operations on the
+/// wrapped type. Types with an `Unsafe<T>` field are considered to have an *unsafe
+/// interior*. The Unsafe type is the only legal way to obtain aliasable data that is
+/// considered mutable. In general, transmuting an &T type into an &mut T is considered
+/// undefined behavior.
+///
+/// Although it is possible to put an Unsafe<T> into static item, it is not permitted to
+/// take the address of the static item if the item is not declared as mutable. This rule
+/// exists because immutable static items are stored in read-only memory, and thus any
+/// attempt to mutate their interior can cause segfaults. Immutable static items containing
+/// Unsafe<T> instances are still useful as read-only initializers, however, so we do not
+/// forbid them altogether.
+///
+/// Types like `Cell` and `RefCell` use this type to wrap their internal data.
+///
+/// Unsafe doesn't opt-out from any kind, instead, types with an `Unsafe` interior
+/// are expected to opt-out from kinds themselves.
+///
+/// # Example:
+///
+/// ```rust
+/// use std::ty::Unsafe;
+/// use std::kinds::marker;
+///
+/// struct NotThreadSafe<T> {
+///     value: Unsafe<T>,
+///     marker1: marker::NoShare
+/// }
+/// ```
+///
+/// **NOTE:** Unsafe<T> fields are public to allow static initializers. It is not recommended
+/// to access its fields directly, `get` should be used instead.
+#[cfg(not(stage0))]
+#[lang="unsafe"]
+pub struct Unsafe<T> {
+    /// Wrapped value
+    value: T,
+
+    /// Invariance marker
+    marker1: marker::InvariantType<T>
+}
+
+/// Unsafe type for stage0
+#[cfg(stage0)]
+pub struct Unsafe<T> {
+    /// Wrapped value
+    value: T,
+
+    /// Invariance marker
+    marker1: marker::InvariantType<T>
+}
+
+impl<T> Unsafe<T> {
+
+    /// Static constructor
+    pub fn new(value: T) -> Unsafe<T> {
+        Unsafe{value: value, marker1: marker::InvariantType}
+    }
+
+    /// Gets a mutable pointer to the wrapped value
+    #[inline]
+    pub unsafe fn get(&self) -> *mut T { cast::transmute(&self.value) }
+
+    /// Unwraps the value
+    #[inline]
+    pub unsafe fn unwrap(self) -> T { self.value }
+}
diff --git a/src/libstd/unicode.rs b/src/libstd/unicode.rs
index b43003f0de2..645db8e040b 100644
--- a/src/libstd/unicode.rs
+++ b/src/libstd/unicode.rs
@@ -13,10 +13,9 @@
 #[allow(missing_doc)];
 #[allow(non_uppercase_statics)];
 
-
 fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
     use cmp::{Equal, Less, Greater};
-    use vec::ImmutableVector;
+    use slice::ImmutableVector;
     use option::None;
     r.bsearch(|&(lo,hi)| {
         if lo <= c && c <= hi { Equal }
@@ -25,7 +24,6 @@ fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
     }) != None
 }
 
-
 pub mod general_category {
     static Cc_table : &'static [(char,char)] = &[
         ('\x00', '\x1f'), ('\x7f', '\x9f')
@@ -108,7 +106,7 @@ pub mod general_category {
 pub mod decompose {
     use option::Option;
     use option::{Some, None};
-    use vec::ImmutableVector;
+    use slice::ImmutableVector;
 
     fn bsearch_table(c: char, r: &'static [(char, &'static [char])]) -> Option<&'static [char]> {
         use cmp::{Equal, Less, Greater};
@@ -4136,8 +4134,8 @@ pub mod derived_property {
     pub fn XID_Start(c: char) -> bool {
         super::bsearch_range_table(c, XID_Start_table)
     }
-
 }
+
 pub mod property {
     static White_Space_table : &'static [(char,char)] = &[
         ('\x09', '\x0d'), ('\x20', '\x20'),
@@ -4151,12 +4149,11 @@ pub mod property {
     pub fn White_Space(c: char) -> bool {
         super::bsearch_range_table(c, White_Space_table)
     }
-
 }
-pub mod conversions {
 
+pub mod conversions {
     use cmp::{Equal, Less, Greater};
-    use vec::ImmutableVector;
+    use slice::ImmutableVector;
     use tuple::Tuple2;
     use option::{Option, Some, None};
 
@@ -4181,7 +4178,8 @@ pub mod conversions {
             else { Greater }
         })
     }
-   static LuLl_table : &'static [(char, char)] = &[
+
+    static LuLl_table : &'static [(char, char)] = &[
         ('\x41', '\x61'), ('\x42', '\x62'),
         ('\x43', '\x63'), ('\x44', '\x64'),
         ('\x45', '\x65'), ('\x46', '\x66'),
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 8080f57550b..5f4f4960a93 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -7,1739 +7,1087 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
+//! An owned, growable vector.
 
-/*!
-
-Utilities for vector manipulation
-
-The `vec` module contains useful code to help work with vector values.
-Vectors are Rust's list type. Vectors contain zero or more values of
-homogeneous types:
-
-```rust
-let int_vector = [1,2,3];
-let str_vector = ["one", "two", "three"];
- ```
-
-This is a big module, but for a high-level overview:
-
-## Structs
-
-Several structs that are useful for vectors, such as `Items`, which
-represents iteration over a vector.
-
-## Traits
-
-A number of traits add methods that allow you to accomplish tasks with vectors.
-
-Traits defined for the `&[T]` type (a vector slice), have methods that can be
-called on either owned vectors, denoted `~[T]`, or on vector slices themselves.
-These traits include `ImmutableVector`, and `MutableVector` for the `&mut [T]`
-case.
-
-An example is the method `.slice(a, b)` that returns an immutable "view" into
-a vector or a vector slice from the index interval `[a, b)`:
-
-```rust
-let numbers = [0, 1, 2];
-let last_numbers = numbers.slice(1, 3);
-// last_numbers is now &[1, 2]
- ```
-
-Traits defined for the `~[T]` type, like `OwnedVector`, can only be called
-on such vectors. These methods deal with adding elements or otherwise changing
-the allocation of the vector.
-
-An example is the method `.push(element)` that will add an element at the end
-of the vector:
-
-```rust
-let mut numbers = ~[0, 1, 2];
-numbers.push(7);
-// numbers is now ~[0, 1, 2, 7];
- ```
-
-## Implementations of other traits
-
-Vectors are a very useful type, and so there's several implementations of
-traits from other modules. Some notable examples:
-
-* `Clone`
-* `Eq`, `Ord`, `TotalEq`, `TotalOrd` -- vectors can be compared,
-  if the element type defines the corresponding trait.
-
-## Iteration
-
-The method `iter()` returns an iteration value for a vector or a vector slice.
-The iterator yields references to the vector's elements, so if the element
-type of the vector is `int`, the element type of the iterator is `&int`.
-
-```rust
-let numbers = [0, 1, 2];
-for &x in numbers.iter() {
-    println!("{} is a number!", x);
-}
- ```
-
-* `.rev_iter()` returns an iterator with the same values as `.iter()`,
-  but going in the reverse order, starting with the back element.
-* `.mut_iter()` returns an iterator that allows modifying each value.
-* `.move_iter()` converts an owned vector into an iterator that
-  moves out a value from the vector each iteration.
-* Further iterators exist that split, chunk or permute the vector.
-
-## Function definitions
-
-There are a number of free functions that create or take vectors, for example:
-
-* Creating a vector, like `from_elem` and `from_fn`
-* Creating a vector with a given size: `with_capacity`
-* Modifying a vector and returning it, like `append`
-* Operations on paired elements, like `unzip`.
-
-*/
-
-#[warn(non_camel_case_types)];
-
-use cast;
-use cast::transmute;
-use ops::Drop;
+use cast::{forget, transmute};
 use clone::Clone;
+use cmp::{Ord, Eq, Ordering, TotalEq, TotalOrd};
 use container::{Container, Mutable};
-use cmp::{Eq, TotalOrd, Ordering, Less, Equal, Greater};
-use cmp;
 use default::Default;
 use fmt;
-use iter::*;
-use num::{CheckedAdd, Saturating, checked_next_power_of_two, div_rem};
+use iter::{DoubleEndedIterator, FromIterator, Extendable, Iterator};
+use libc::{free, c_void};
+use mem::{size_of, move_val_init};
+use mem;
+use num;
+use num::{CheckedMul, CheckedAdd};
+use ops::Drop;
 use option::{None, Option, Some};
-use ptr;
 use ptr::RawPtr;
-use rt::global_heap::{malloc_raw, realloc_raw, exchange_free};
-use result::{Ok, Err};
-use mem;
-use mem::size_of;
-use kinds::marker;
-use uint;
-use unstable::finally::try_finally;
-use raw::{Repr, Slice, Vec};
-
-/**
- * Creates and initializes an owned vector.
- *
- * Creates an owned vector of size `n_elts` and initializes the elements
- * to the value returned by the function `op`.
- */
-pub fn from_fn<T>(n_elts: uint, op: |uint| -> T) -> ~[T] {
-    unsafe {
-        let mut v = with_capacity(n_elts);
-        let p = v.as_mut_ptr();
-        let mut i = 0;
-        try_finally(
-            &mut i, (),
-            |i, ()| while *i < n_elts {
-                mem::move_val_init(
-                    &mut(*p.offset(*i as int)),
-                    op(*i));
-                *i += 1u;
-            },
-            |i| v.set_len(*i));
-        v
-    }
-}
+use ptr;
+use rt::global_heap::{malloc_raw, realloc_raw};
+use raw::Slice;
+use slice::{ImmutableEqVector, ImmutableVector, Items, MutItems, MutableVector};
+use slice::{MutableTotalOrdVector};
 
-/**
- * Creates and initializes an owned vector.
- *
- * Creates an owned vector of size `n_elts` and initializes the elements
- * to the value `t`.
- */
-pub fn from_elem<T:Clone>(n_elts: uint, t: T) -> ~[T] {
-    // FIXME (#7136): manually inline from_fn for 2x plus speedup (sadly very
-    // important, from_elem is a bottleneck in borrowck!). Unfortunately it
-    // still is substantially slower than using the unsafe
-    // vec::with_capacity/ptr::set_memory for primitive types.
-    unsafe {
-        let mut v = with_capacity(n_elts);
-        let p = v.as_mut_ptr();
-        let mut i = 0u;
-        try_finally(
-            &mut i, (),
-            |i, ()| while *i < n_elts {
-                mem::move_val_init(
-                    &mut(*p.offset(*i as int)),
-                    t.clone());
-                *i += 1u;
-            },
-            |i| v.set_len(*i));
-        v
+/// An owned, growable vector.
+///
+/// # Examples
+///
+/// ```rust
+/// # use std::vec::Vec;
+/// let mut vec = Vec::new();
+/// vec.push(1);
+/// vec.push(2);
+///
+/// assert_eq!(vec.len(), 2);
+/// assert_eq!(vec.get(0), &1);
+///
+/// assert_eq!(vec.pop(), Some(2));
+/// assert_eq!(vec.len(), 1);
+/// ```
+///
+/// The `vec!` macro is provided to make initialization more convenient:
+///
+/// ```rust
+/// let mut vec = vec!(1, 2, 3);
+/// vec.push(4);
+/// assert_eq!(vec, vec!(1, 2, 3, 4));
+/// ```
+#[unsafe_no_drop_flag]
+pub struct Vec<T> {
+    priv len: uint,
+    priv cap: uint,
+    priv ptr: *mut T
+}
+
+impl<T> Vec<T> {
+    /// Constructs a new, empty `Vec`.
+    ///
+    /// The vector will not allocate until elements are pushed onto it.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// # use std::vec::Vec;
+    /// let mut vec: Vec<int> = Vec::new();
+    /// ```
+    #[inline]
+    pub fn new() -> Vec<T> {
+        Vec { len: 0, cap: 0, ptr: 0 as *mut T }
     }
-}
 
-/// Creates a new vector with a capacity of `capacity`
-#[inline]
-pub fn with_capacity<T>(capacity: uint) -> ~[T] {
-    unsafe {
-        let alloc = capacity * mem::nonzero_size_of::<T>();
-        let size = alloc + mem::size_of::<Vec<()>>();
-        if alloc / mem::nonzero_size_of::<T>() != capacity || size < alloc {
-            fail!("vector size is too large: {}", capacity);
+    /// Constructs a new, empty `Vec` with the specified capacity.
+    ///
+    /// The vector will be able to hold exactly `capacity` elements without
+    /// reallocating. If `capacity` is 0, the vector will not allocate.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// # use std::vec::Vec;
+    /// let vec: Vec<int> = Vec::with_capacity(10);
+    /// ```
+    pub fn with_capacity(capacity: uint) -> Vec<T> {
+        if capacity == 0 {
+            Vec::new()
+        } else {
+            let size = capacity.checked_mul(&size_of::<T>()).expect("capacity overflow");
+            let ptr = unsafe { malloc_raw(size) };
+            Vec { len: 0, cap: capacity, ptr: ptr as *mut T }
         }
-        let ptr = malloc_raw(size) as *mut Vec<()>;
-        (*ptr).alloc = alloc;
-        (*ptr).fill = 0;
-        transmute(ptr)
-    }
-}
-
-/**
- * Builds a vector by calling a provided function with an argument
- * function that pushes an element to the back of a vector.
- * The initial capacity for the vector may optionally be specified.
- *
- * # Arguments
- *
- * * size - An option, maybe containing initial size of the vector to reserve
- * * builder - A function that will construct the vector. It receives
- *             as an argument a function that will push an element
- *             onto the vector being constructed.
- */
-#[inline]
-pub fn build<A>(size: Option<uint>, builder: |push: |v: A||) -> ~[A] {
-    let mut vec = with_capacity(size.unwrap_or(4));
-    builder(|x| vec.push(x));
-    vec
-}
-
-/**
- * Converts a pointer to A into a slice of length 1 (without copying).
- */
-pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] {
-    unsafe {
-        transmute(Slice { data: s, len: 1 })
     }
-}
 
-/**
- * Converts a pointer to A into a slice of length 1 (without copying).
- */
-pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
-    unsafe {
-        let ptr: *A = transmute(s);
-        transmute(Slice { data: ptr, len: 1 })
+    /// Creates and initializes a `Vec`.
+    ///
+    /// Creates a `Vec` of size `length` and initializes the elements to the
+    /// value returned by the closure `op`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// # use std::vec::Vec;
+    /// let vec = Vec::from_fn(3, |idx| idx * 2);
+    /// assert_eq!(vec, vec!(0, 2, 4));
+    /// ```
+    pub fn from_fn(length: uint, op: |uint| -> T) -> Vec<T> {
+        unsafe {
+            let mut xs = Vec::with_capacity(length);
+            while xs.len < length {
+                move_val_init(xs.as_mut_slice().unsafe_mut_ref(xs.len), op(xs.len));
+                xs.len += 1;
+            }
+            xs
+        }
     }
-}
 
-/// An iterator over the slices of a vector separated by elements that
-/// match a predicate function.
-pub struct Splits<'a, T> {
-    priv v: &'a [T],
-    priv n: uint,
-    priv pred: 'a |t: &T| -> bool,
-    priv finished: bool
-}
-
-impl<'a, T> Iterator<&'a [T]> for Splits<'a, T> {
+    /// Consumes the `Vec`, partitioning it based on a predcate.
+    ///
+    /// Partitions the `Vec` into two `Vec`s `(A,B)`, where all elements of `A`
+    /// satisfy `f` and all elements of `B` do not. The order of elements is
+    /// preserved.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3, 4);
+    /// let (even, odd) = vec.partition(|&n| n % 2 == 0);
+    /// assert_eq!(even, vec!(2, 4));
+    /// assert_eq!(odd, vec!(1, 3));
+    /// ```
     #[inline]
-    fn next(&mut self) -> Option<&'a [T]> {
-        if self.finished { return None; }
+    pub fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
+        let mut lefts  = Vec::new();
+        let mut rights = Vec::new();
 
-        if self.n == 0 {
-            self.finished = true;
-            return Some(self.v);
-        }
-
-        match self.v.iter().position(|x| (self.pred)(x)) {
-            None => {
-                self.finished = true;
-                Some(self.v)
-            }
-            Some(idx) => {
-                let ret = Some(self.v.slice(0, idx));
-                self.v = self.v.slice(idx + 1, self.v.len());
-                self.n -= 1;
-                ret
+        for elt in self.move_iter() {
+            if f(&elt) {
+                lefts.push(elt);
+            } else {
+                rights.push(elt);
             }
         }
-    }
 
-    #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        if self.finished {
-            return (0, Some(0))
-        }
-        // if the predicate doesn't match anything, we yield one slice
-        // if it matches every element, we yield N+1 empty slices where
-        // N is either the number of elements or the number of splits.
-        match (self.v.len(), self.n) {
-            (0,_) => (1, Some(1)),
-            (_,0) => (1, Some(1)),
-            (l,n) => (1, cmp::min(l,n).checked_add(&1u))
-        }
+        (lefts, rights)
     }
 }
 
-/// An iterator over the slices of a vector separated by elements that
-/// match a predicate function, from back to front.
-pub struct RevSplits<'a, T> {
-    priv v: &'a [T],
-    priv n: uint,
-    priv pred: 'a |t: &T| -> bool,
-    priv finished: bool
-}
-
-impl<'a, T> Iterator<&'a [T]> for RevSplits<'a, T> {
-    #[inline]
-    fn next(&mut self) -> Option<&'a [T]> {
-        if self.finished { return None; }
-
-        if self.n == 0 {
-            self.finished = true;
-            return Some(self.v);
-        }
+impl<T: Clone> Vec<T> {
+    /// Constructs a `Vec` by cloning elements of a slice.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// # use std::vec::Vec;
+    /// let slice = [1, 2, 3];
+    /// let vec = Vec::from_slice(slice);
+    /// ```
+    pub fn from_slice(values: &[T]) -> Vec<T> {
+        values.iter().map(|x| x.clone()).collect()
+    }
 
-        let pred = &mut self.pred;
-        match self.v.iter().rposition(|x| (*pred)(x)) {
-            None => {
-                self.finished = true;
-                Some(self.v)
-            }
-            Some(idx) => {
-                let ret = Some(self.v.slice(idx + 1, self.v.len()));
-                self.v = self.v.slice(0, idx);
-                self.n -= 1;
-                ret
+    /// Constructs a `Vec` with copies of a value.
+    ///
+    /// Creates a `Vec` with `length` copies of `value`.
+    ///
+    /// # Example
+    /// ```rust
+    /// # use std::vec::Vec;
+    /// let vec = Vec::from_elem(3, "hi");
+    /// println!("{}", vec); // prints [hi, hi, hi]
+    /// ```
+    pub fn from_elem(length: uint, value: T) -> Vec<T> {
+        unsafe {
+            let mut xs = Vec::with_capacity(length);
+            while xs.len < length {
+                move_val_init(xs.as_mut_slice().unsafe_mut_ref(xs.len), value.clone());
+                xs.len += 1;
             }
+            xs
         }
     }
 
+    /// Appends all elements in a slice to the `Vec`.
+    ///
+    /// Iterates over the slice `other`, clones each element, and then appends
+    /// it to this `Vec`. The `other` vector is traversed in-order.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1);
+    /// vec.push_all([2, 3, 4]);
+    /// assert_eq!(vec, vec!(1, 2, 3, 4));
+    /// ```
     #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        if self.finished {
-            return (0, Some(0))
-        }
-        match (self.v.len(), self.n) {
-            (0,_) => (1, Some(1)),
-            (_,0) => (1, Some(1)),
-            (l,n) => (1, cmp::min(l,n).checked_add(&1u))
+    pub fn push_all(&mut self, other: &[T]) {
+        for element in other.iter() {
+            self.push((*element).clone())
         }
     }
-}
-
-// Appending
 
-/// Iterates over the `rhs` vector, copying each element and appending it to the
-/// `lhs`. Afterwards, the `lhs` is then returned for use again.
-#[inline]
-pub fn append<T:Clone>(lhs: ~[T], rhs: &[T]) -> ~[T] {
-    let mut v = lhs;
-    v.push_all(rhs);
-    v
-}
-
-/// Appends one element to the vector provided. The vector itself is then
-/// returned for use again.
-#[inline]
-pub fn append_one<T>(lhs: ~[T], x: T) -> ~[T] {
-    let mut v = lhs;
-    v.push(x);
-    v
-}
-
-// Functional utilities
-
-/**
- * Apply a function to each element of a vector and return a concatenation
- * of each result vector
- */
-pub fn flat_map<T, U>(v: &[T], f: |t: &T| -> ~[U]) -> ~[U] {
-    let mut result = ~[];
-    for elem in v.iter() { result.push_all_move(f(elem)); }
-    result
-}
-
-#[allow(missing_doc)]
-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];
-
-    /// Concatenate a vector of vectors, placing a given separator between each.
-    fn connect_vec(&self, sep: &T) -> ~[T];
-}
-
-impl<'a, T: Clone, V: Vector<T>> VectorVector<T> for &'a [V] {
-    fn concat_vec(&self) -> ~[T] {
-        let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
-        let mut result = with_capacity(size);
-        for v in self.iter() {
-            result.push_all(v.as_slice())
-        }
-        result
-    }
+    /// Grows the `Vec` in-place.
+    ///
+    /// Adds `n` copies of `value` to the `Vec`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!("hello");
+    /// vec.grow(2, & &"world");
+    /// assert_eq!(vec, vec!("hello", "world", "world"));
+    /// ```
+    pub fn grow(&mut self, n: uint, value: &T) {
+        let new_len = self.len() + n;
+        self.reserve(new_len);
+        let mut i: uint = 0u;
 
-    fn connect_vec(&self, sep: &T) -> ~[T] {
-        let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
-        let mut result = with_capacity(size + self.len());
-        let mut first = true;
-        for v in self.iter() {
-            if first { first = false } else { result.push(sep.clone()) }
-            result.push_all(v.as_slice())
+        while i < n {
+            self.push((*value).clone());
+            i += 1u;
         }
-        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 = with_capacity(lo);
-    let mut us = with_capacity(lo);
-    for (t, u) in iter {
-        ts.push(t);
-        us.push(u);
-    }
-    (ts, us)
-}
-
-/// 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.
-///
-/// The Steinhaus–Johnson–Trotter algorithm is used.
-///
-/// Generates even and odd permutations alternately.
-///
-/// The last generated swap is always (0, 1), and it returns the
-/// sequence to its initial order.
-pub struct ElementSwaps {
-    priv sdir: ~[SizeDirection],
-    /// If true, emit the last swap that returns the sequence to initial state
-    priv emit_reset: bool,
-}
-
-impl ElementSwaps {
-    /// Create an `ElementSwaps` iterator for a sequence of `length` elements
-    pub fn new(length: uint) -> ElementSwaps {
-        // Initialize `sdir` with a direction that position should move in
-        // (all negative at the beginning) and the `size` of the
-        // element (equal to the original index).
-        ElementSwaps{
-            emit_reset: true,
-            sdir: range(0, length)
-                    .map(|i| SizeDirection{ size: i, dir: Neg })
-                    .to_owned_vec()
+    /// Sets the value of a vector element at a given index, growing the vector
+    /// as needed.
+    ///
+    /// Sets the element at position `index` to `value`. If `index` is past the
+    /// end of the vector, expands the vector by replicating `initval` to fill
+    /// the intervening space.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!("a", "b", "c");
+    /// vec.grow_set(1, & &"fill", "d");
+    /// vec.grow_set(4, & &"fill", "e");
+    /// assert_eq!(vec, vec!("a", "d", "c", "fill", "e"));
+    /// ```
+    pub fn grow_set(&mut self, index: uint, initval: &T, value: T) {
+        let l = self.len();
+        if index >= l {
+            self.grow(index - l + 1u, initval);
         }
+        *self.get_mut(index) = value;
     }
-}
-
-enum Direction { Pos, Neg }
-
-/// An Index and Direction together
-struct SizeDirection {
-    size: uint,
-    dir: Direction,
-}
-
-impl Iterator<(uint, uint)> for ElementSwaps {
-    #[inline]
-    fn next(&mut self) -> Option<(uint, uint)> {
-        fn new_pos(i: uint, s: Direction) -> uint {
-            i + match s { Pos => 1, Neg => -1 }
-        }
 
-        // Find the index of the largest mobile element:
-        // The direction should point into the vector, and the
-        // swap should be with a smaller `size` element.
-        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)
-                           .max_by(|&(_, sd)| sd.size);
-        match max {
-            Some((i, sd)) => {
-                let j = new_pos(i, sd.dir);
-                self.sdir.swap(i, j);
+    /// Partitions a vector based on a predcate.
+    ///
+    /// Clones the elements of the vector, partitioning them into two `Vec`s
+    /// `(A,B)`, where all elements of `A` satisfy `f` and all elements of `B`
+    /// do not. The order of elements is preserved.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3, 4);
+    /// let (even, odd) = vec.partitioned(|&n| n % 2 == 0);
+    /// assert_eq!(even, vec!(2, 4));
+    /// assert_eq!(odd, vec!(1, 3));
+    /// ```
+    pub fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
+        let mut lefts = Vec::new();
+        let mut rights = Vec::new();
 
-                // Swap the direction of each larger SizeDirection
-                for x in self.sdir.mut_iter() {
-                    if x.size > sd.size {
-                        x.dir = match x.dir { Pos => Neg, Neg => Pos };
-                    }
-                }
-                Some((i, j))
-            },
-            None => if self.emit_reset && self.sdir.len() > 1 {
-                self.emit_reset = false;
-                Some((0, 1))
+        for elt in self.iter() {
+            if f(elt) {
+                lefts.push(elt.clone());
             } else {
-                None
+                rights.push(elt.clone());
             }
         }
-    }
-}
 
-/// An Iterator that uses `ElementSwaps` to iterate through
-/// all possible permutations of a vector.
-///
-/// The first iteration yields a clone of the vector as it is,
-/// then each successive element is the vector with one
-/// swap applied.
-///
-/// Generates even and odd permutations alternately.
-pub struct Permutations<T> {
-    priv swaps: ElementSwaps,
-    priv v: ~[T],
+        (lefts, rights)
+    }
 }
 
-impl<T: Clone> Iterator<~[T]> for Permutations<T> {
-    #[inline]
-    fn next(&mut self) -> Option<~[T]> {
-        match self.swaps.next() {
-            None => None,
-            Some((a, b)) => {
-                let elt = self.v.clone();
-                self.v.swap(a, b);
-                Some(elt)
-            }
+impl<T:Clone> Clone for Vec<T> {
+    fn clone(&self) -> Vec<T> {
+        let mut vector = Vec::with_capacity(self.len());
+        for element in self.iter() {
+            vector.push((*element).clone())
         }
+        vector
     }
 }
 
-/// An iterator over the (overlapping) slices of length `size` within
-/// a vector.
-#[deriving(Clone)]
-pub struct Windows<'a, T> {
-    priv v: &'a [T],
-    priv size: uint
-}
-
-impl<'a, T> Iterator<&'a [T]> for Windows<'a, T> {
-    #[inline]
-    fn next(&mut self) -> Option<&'a [T]> {
-        if self.size > self.v.len() {
-            None
-        } else {
-            let ret = Some(self.v.slice(0, self.size));
-            self.v = self.v.slice(1, self.v.len());
-            ret
+impl<T> FromIterator<T> for Vec<T> {
+    fn from_iterator<I:Iterator<T>>(iterator: &mut I) -> Vec<T> {
+        let (lower, _) = iterator.size_hint();
+        let mut vector = Vec::with_capacity(lower);
+        for element in *iterator {
+            vector.push(element)
         }
+        vector
     }
+}
 
-    #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        if self.size > self.v.len() {
-            (0, Some(0))
-        } else {
-            let x = self.v.len() - self.size;
-            (x.saturating_add(1), x.checked_add(&1u))
+impl<T> Extendable<T> for Vec<T> {
+    fn extend<I: Iterator<T>>(&mut self, iterator: &mut I) {
+        let (lower, _) = iterator.size_hint();
+        self.reserve_additional(lower);
+        for element in *iterator {
+            self.push(element)
         }
     }
 }
 
-/// An iterator over a vector in (non-overlapping) chunks (`size`
-/// elements at a time).
-///
-/// When the vector len is not evenly divided by the chunk size,
-/// the last slice of the iteration will be the remainder.
-#[deriving(Clone)]
-pub struct Chunks<'a, T> {
-    priv v: &'a [T],
-    priv size: uint
-}
-
-impl<'a, T> Iterator<&'a [T]> for Chunks<'a, T> {
+impl<T: Eq> Eq for Vec<T> {
     #[inline]
-    fn next(&mut self) -> Option<&'a [T]> {
-        if self.v.len() == 0 {
-            None
-        } else {
-            let chunksz = cmp::min(self.v.len(), self.size);
-            let (fst, snd) = (self.v.slice_to(chunksz),
-                              self.v.slice_from(chunksz));
-            self.v = snd;
-            Some(fst)
-        }
+    fn eq(&self, other: &Vec<T>) -> bool {
+        self.as_slice() == other.as_slice()
     }
+}
 
+impl<T: Ord> Ord for Vec<T> {
     #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        if self.v.len() == 0 {
-            (0, Some(0))
-        } else {
-            let (n, rem) = div_rem(self.v.len(), self.size);
-            let n = if rem > 0 { n+1 } else { n };
-            (n, Some(n))
-        }
+    fn lt(&self, other: &Vec<T>) -> bool {
+        self.as_slice() < other.as_slice()
     }
 }
 
-impl<'a, T> DoubleEndedIterator<&'a [T]> for Chunks<'a, T> {
+impl<T: TotalEq> TotalEq for Vec<T> {
     #[inline]
-    fn next_back(&mut self) -> Option<&'a [T]> {
-        if self.v.len() == 0 {
-            None
-        } else {
-            let remainder = self.v.len() % self.size;
-            let chunksz = if remainder != 0 { remainder } else { self.size };
-            let (fst, snd) = (self.v.slice_to(self.v.len() - chunksz),
-                              self.v.slice_from(self.v.len() - chunksz));
-            self.v = fst;
-            Some(snd)
-        }
+    fn equals(&self, other: &Vec<T>) -> bool {
+        self.as_slice().equals(&other.as_slice())
     }
 }
 
-impl<'a, T> RandomAccessIterator<&'a [T]> for Chunks<'a, T> {
+impl<T: TotalOrd> TotalOrd for Vec<T> {
     #[inline]
-    fn indexable(&self) -> uint {
-        self.v.len()/self.size + if self.v.len() % self.size != 0 { 1 } else { 0 }
+    fn cmp(&self, other: &Vec<T>) -> Ordering {
+        self.as_slice().cmp(&other.as_slice())
     }
+}
 
+impl<T> Container for Vec<T> {
     #[inline]
-    fn idx(&self, index: uint) -> Option<&'a [T]> {
-        if index < self.indexable() {
-            let lo = index * self.size;
-            let mut hi = lo + self.size;
-            if hi < lo || hi > self.v.len() { hi = self.v.len(); }
-
-            Some(self.v.slice(lo, hi))
-        } else {
-            None
-        }
+    fn len(&self) -> uint {
+        self.len
     }
 }
 
-// Equality
-
-#[cfg(not(test))]
-#[allow(missing_doc)]
-pub mod traits {
-    use super::*;
-
-    use container::Container;
-    use clone::Clone;
-    use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Equiv};
-    use iter::order;
-    use ops::Add;
-
-    impl<'a,T:Eq> Eq for &'a [T] {
-        fn eq(&self, other: & &'a [T]) -> bool {
-            self.len() == other.len() &&
-                order::eq(self.iter(), other.iter())
-        }
-        fn ne(&self, other: & &'a [T]) -> bool {
-            self.len() != other.len() ||
-                order::ne(self.iter(), other.iter())
-        }
-    }
-
-    impl<T:Eq> Eq for ~[T] {
-        #[inline]
-        fn eq(&self, other: &~[T]) -> bool { self.as_slice() == *other }
-        #[inline]
-        fn ne(&self, other: &~[T]) -> bool { !self.eq(other) }
-    }
-
-    impl<'a,T:TotalEq> TotalEq for &'a [T] {
-        fn equals(&self, other: & &'a [T]) -> bool {
-            self.len() == other.len() &&
-                order::equals(self.iter(), other.iter())
-        }
-    }
-
-    impl<T:TotalEq> TotalEq for ~[T] {
-        #[inline]
-        fn equals(&self, other: &~[T]) -> bool { self.as_slice().equals(&other.as_slice()) }
-    }
-
-    impl<'a,T:Eq, V: Vector<T>> Equiv<V> for &'a [T] {
-        #[inline]
-        fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
-    }
-
-    impl<'a,T:Eq, V: Vector<T>> Equiv<V> for ~[T] {
-        #[inline]
-        fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
-    }
-
-    impl<'a,T:TotalOrd> TotalOrd for &'a [T] {
-        fn cmp(&self, other: & &'a [T]) -> Ordering {
-            order::cmp(self.iter(), other.iter())
+impl<T> Vec<T> {
+    /// Returns the number of elements the vector can hold without
+    /// reallocating.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// # use std::vec::Vec;
+    /// let vec: Vec<int> = Vec::with_capacity(10);
+    /// assert_eq!(vec.capacity(), 10);
+    /// ```
+    #[inline]
+    pub fn capacity(&self) -> uint {
+        self.cap
+    }
+
+     /// Reserves capacity for at least `n` additional elements in the given
+     /// vector.
+     ///
+     /// # Failure
+     ///
+     /// Fails if the new capacity overflows `uint`.
+     ///
+     /// # Example
+     ///
+     /// ```rust
+     /// # use std::vec::Vec;
+     /// let mut vec: Vec<int> = vec!(1);
+     /// vec.reserve_additional(10);
+     /// assert!(vec.capacity() >= 11);
+     /// ```
+    pub fn reserve_additional(&mut self, extra: uint) {
+        if self.cap - self.len < extra {
+            match self.len.checked_add(&extra) {
+                None => fail!("Vec::reserve_additional: `uint` overflow"),
+                Some(new_cap) => self.reserve(new_cap)
+            }
         }
     }
 
-    impl<T: TotalOrd> TotalOrd for ~[T] {
-        #[inline]
-        fn cmp(&self, other: &~[T]) -> Ordering { self.as_slice().cmp(&other.as_slice()) }
-    }
-
-    impl<'a, T: Ord> Ord for &'a [T] {
-        fn lt(&self, other: & &'a [T]) -> bool {
-            order::lt(self.iter(), other.iter())
-        }
-        #[inline]
-        fn le(&self, other: & &'a [T]) -> bool {
-            order::le(self.iter(), other.iter())
-        }
-        #[inline]
-        fn ge(&self, other: & &'a [T]) -> bool {
-            order::ge(self.iter(), other.iter())
-        }
-        #[inline]
-        fn gt(&self, other: & &'a [T]) -> bool {
-            order::gt(self.iter(), other.iter())
+    /// Reserves capacity for at least `n` elements in the given vector.
+    ///
+    /// This function will over-allocate in order to amortize the allocation
+    /// costs in scenarios where the caller may need to repeatedly reserve
+    /// additional space.
+    ///
+    /// If the capacity for `self` is already equal to or greater than the
+    /// requested capacity, then no action is taken.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// vec.reserve(10);
+    /// assert!(vec.capacity() >= 10);
+    /// ```
+    pub fn reserve(&mut self, capacity: uint) {
+        if capacity >= self.len {
+            self.reserve_exact(num::next_power_of_two(capacity))
         }
     }
 
-    impl<T: Ord> Ord for ~[T] {
-        #[inline]
-        fn lt(&self, other: &~[T]) -> bool { self.as_slice() < other.as_slice() }
-        #[inline]
-        fn le(&self, other: &~[T]) -> bool { self.as_slice() <= other.as_slice() }
-        #[inline]
-        fn ge(&self, other: &~[T]) -> bool { self.as_slice() >= other.as_slice() }
-        #[inline]
-        fn gt(&self, other: &~[T]) -> bool { self.as_slice() > other.as_slice() }
-    }
-
-    impl<'a,T:Clone, V: Vector<T>> Add<V, ~[T]> for &'a [T] {
-        #[inline]
-        fn add(&self, rhs: &V) -> ~[T] {
-            let mut res = with_capacity(self.len() + rhs.as_slice().len());
-            res.push_all(*self);
-            res.push_all(rhs.as_slice());
-            res
+    /// Reserves capacity for exactly `capacity` elements in the given vector.
+    ///
+    /// If the capacity for `self` is already equal to or greater than the
+    /// requested capacity, then no action is taken.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// # use std::vec::Vec;
+    /// let mut vec: Vec<int> = Vec::with_capacity(10);
+    /// vec.reserve_exact(11);
+    /// assert_eq!(vec.capacity(), 11);
+    /// ```
+    pub fn reserve_exact(&mut self, capacity: uint) {
+        if capacity >= self.len {
+            let size = capacity.checked_mul(&size_of::<T>()).expect("capacity overflow");
+            self.cap = capacity;
+            unsafe {
+                self.ptr = realloc_raw(self.ptr as *mut u8, size) as *mut T;
+            }
         }
     }
 
-    impl<T:Clone, V: Vector<T>> Add<V, ~[T]> for ~[T] {
-        #[inline]
-        fn add(&self, rhs: &V) -> ~[T] {
-            self.as_slice() + rhs.as_slice()
+    /// Shrink the capacity of the vector to match the length
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// vec.shrink_to_fit();
+    /// assert_eq!(vec.capacity(), vec.len());
+    /// ```
+    pub fn shrink_to_fit(&mut self) {
+        if self.len == 0 {
+            unsafe { free(self.ptr as *mut c_void) };
+            self.cap = 0;
+            self.ptr = 0 as *mut T;
+        } else {
+            unsafe {
+                // Overflow check is unnecessary as the vector is already at least this large.
+                self.ptr = realloc_raw(self.ptr as *mut u8, self.len * size_of::<T>()) as *mut T;
+            }
+            self.cap = self.len;
         }
     }
-}
-
-#[cfg(test)]
-pub mod traits {}
-
-/// Any vector that can be represented as a slice.
-pub trait Vector<T> {
-    /// Work with `self` as a slice.
-    fn as_slice<'a>(&'a self) -> &'a [T];
-}
-
-impl<'a,T> Vector<T> for &'a [T] {
-    #[inline(always)]
-    fn as_slice<'a>(&'a self) -> &'a [T] { *self }
-}
-
-impl<T> Vector<T> for ~[T] {
-    #[inline(always)]
-    fn as_slice<'a>(&'a self) -> &'a [T] { let v: &'a [T] = *self; v }
-}
-
-impl<'a, T> Container for &'a [T] {
-    /// Returns the length of a vector
-    #[inline]
-    fn len(&self) -> uint {
-        self.repr().len
-    }
-}
-
-impl<T> Container for ~[T] {
-    /// Returns the length of a vector
-    #[inline]
-    fn len(&self) -> uint {
-        self.as_slice().len()
-    }
-}
-
-/// Extension methods for vector slices with cloneable elements
-pub trait CloneableVector<T> {
-    /// Copy `self` into a new owned vector
-    fn to_owned(&self) -> ~[T];
 
-    /// Convert `self` into an owned vector, not making a copy if possible.
-    fn into_owned(self) -> ~[T];
-}
-
-/// Extension methods for vector slices
-impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
-    /// Returns a copy of `v`.
+    /// Remove the last element from a vector and return it, or `None` if it is
+    /// empty.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// assert_eq!(vec.pop(), Some(3));
+    /// assert_eq!(vec, vec!(1, 2));
+    /// ```
     #[inline]
-    fn to_owned(&self) -> ~[T] {
-        let mut result = with_capacity(self.len());
-        for e in self.iter() {
-            result.push((*e).clone());
+    pub fn pop(&mut self) -> Option<T> {
+        if self.len == 0 {
+            None
+        } else {
+            unsafe {
+                self.len -= 1;
+                Some(ptr::read(self.as_slice().unsafe_ref(self.len())))
+            }
         }
-        result
     }
 
-    #[inline(always)]
-    fn into_owned(self) -> ~[T] { self.to_owned() }
-}
-
-/// Extension methods for owned vectors
-impl<T: Clone> CloneableVector<T> for ~[T] {
+    /// Append an element to a vector.
+    ///
+    /// # Failure
+    ///
+    /// Fails if the number of elements in the vector overflows a `uint`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2);
+    /// vec.push(3);
+    /// assert_eq!(vec, vec!(1, 2, 3));
+    /// ```
     #[inline]
-    fn to_owned(&self) -> ~[T] { self.clone() }
-
-    #[inline(always)]
-    fn into_owned(self) -> ~[T] { self }
-}
-
-/// Extension methods for vectors
-pub trait ImmutableVector<'a, T> {
-    /**
-     * Returns a slice of self between `start` and `end`.
-     *
-     * Fails when `start` or `end` point outside the bounds of self,
-     * or when `start` > `end`.
-     */
-    fn slice(&self, start: uint, end: uint) -> &'a [T];
-
-    /**
-     * Returns a slice of self from `start` to the end of the vec.
-     *
-     * Fails when `start` points outside the bounds of self.
-     */
-    fn slice_from(&self, start: uint) -> &'a [T];
-
-    /**
-     * Returns a slice of self from the start of the vec to `end`.
-     *
-     * Fails when `end` points outside the bounds of self.
-     */
-    fn slice_to(&self, end: uint) -> &'a [T];
-    /// Returns an iterator over the vector
-    fn iter(self) -> Items<'a, T>;
-    /// Returns a reversed iterator over a vector
-    fn rev_iter(self) -> RevItems<'a, T>;
-    /// Returns an iterator over the subslices of the vector which are
-    /// separated by elements that match `pred`.  The matched element
-    /// is not contained in the subslices.
-    fn split(self, pred: 'a |&T| -> bool) -> Splits<'a, T>;
-    /// Returns an iterator over the subslices of the vector which are
-    /// separated by elements that match `pred`, limited to splitting
-    /// at most `n` times.  The matched element is not contained in
-    /// the subslices.
-    fn splitn(self, n: uint, pred: 'a |&T| -> bool) -> Splits<'a, T>;
-    /// Returns an iterator over the subslices of the vector which are
-    /// separated by elements that match `pred`. This starts at the
-    /// end of the vector and works backwards.  The matched element is
-    /// not contained in the subslices.
-    fn rsplit(self, pred: 'a |&T| -> bool) -> RevSplits<'a, T>;
-    /// Returns an iterator over the subslices of the vector which are
-    /// separated by elements that match `pred` limited to splitting
-    /// at most `n` times. This starts at the end of the vector and
-    /// works backwards.  The matched element is not contained in the
-    /// subslices.
-    fn rsplitn(self,  n: uint, pred: 'a |&T| -> bool) -> RevSplits<'a, T>;
-
-    /**
-     * Returns an iterator over all contiguous windows of length
-     * `size`. The windows overlap. If the vector is shorter than
-     * `size`, the iterator returns no values.
-     *
-     * # Failure
-     *
-     * Fails if `size` is 0.
-     *
-     * # Example
-     *
-     * Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`,
-     * `[3,4]`):
-     *
-     * ```rust
-     * let v = &[1,2,3,4];
-     * for win in v.windows(2) {
-     *     println!("{:?}", win);
-     * }
-     * ```
-     *
-     */
-    fn windows(self, size: uint) -> Windows<'a, T>;
-    /**
-     *
-     * Returns an iterator over `size` elements of the vector at a
-     * time. The chunks do not overlap. If `size` does not divide the
-     * length of the vector, then the last chunk will not have length
-     * `size`.
-     *
-     * # Failure
-     *
-     * Fails if `size` is 0.
-     *
-     * # Example
-     *
-     * Print the vector two elements at a time (i.e. `[1,2]`,
-     * `[3,4]`, `[5]`):
-     *
-     * ```rust
-     * let v = &[1,2,3,4,5];
-     * for win in v.chunks(2) {
-     *     println!("{:?}", win);
-     * }
-     * ```
-     *
-     */
-    fn chunks(self, size: uint) -> Chunks<'a, T>;
-
-    /// Returns the element of a vector at the given index, or `None` if the
-    /// index is out of bounds
-    fn get(&self, index: uint) -> Option<&'a T>;
-    /// Returns the first element of a vector, or `None` if it is empty
-    fn head(&self) -> Option<&'a T>;
-    /// Returns all but the first element of a vector
-    fn tail(&self) -> &'a [T];
-    /// Returns all but the first `n' elements of a vector
-    fn tailn(&self, n: uint) -> &'a [T];
-    /// Returns all but the last element of a vector
-    fn init(&self) -> &'a [T];
-    /// Returns all but the last `n' elements of a vector
-    fn initn(&self, n: uint) -> &'a [T];
-    /// Returns the last element of a vector, or `None` if it is empty.
-    fn last(&self) -> Option<&'a T>;
-    /**
-     * Apply a function to each element of a vector and return a concatenation
-     * of each result vector
-     */
-    fn flat_map<U>(&self, f: |t: &T| -> ~[U]) -> ~[U];
-    /// Returns a pointer to the element at the given index, without doing
-    /// bounds checking.
-    unsafe fn unsafe_ref(self, index: uint) -> &'a T;
-
-    /**
-     * Returns an unsafe pointer to the vector's buffer
-     *
-     * The caller must ensure that the vector outlives the pointer this
-     * function returns, or else it will end up pointing to garbage.
-     *
-     * Modifying the vector may cause its buffer to be reallocated, which
-     * would also make any pointers to it invalid.
-     */
-    fn as_ptr(&self) -> *T;
-
-    /**
-     * Binary search a sorted vector with a comparator function.
-     *
-     * The comparator function should implement an order consistent
-     * with the sort order of the underlying vector, returning an
-     * order code that indicates whether its argument is `Less`,
-     * `Equal` or `Greater` the desired target.
-     *
-     * Returns the index where the comparator returned `Equal`, or `None` if
-     * not found.
-     */
-    fn bsearch(&self, f: |&T| -> Ordering) -> Option<uint>;
-
-    /// Deprecated, use iterators where possible
-    /// (`self.iter().map(f)`). Apply a function to each element
-    /// of a vector and return the results.
-    fn map<U>(&self, |t: &T| -> U) -> ~[U];
-
-    /**
-     * Returns a mutable reference to the first element in this slice
-     * and adjusts the slice in place so that it no longer contains
-     * that element. O(1).
-     *
-     * Equivalent to:
-     *
-     * ```ignore
-     *     if self.len() == 0 { return None }
-     *     let head = &self[0];
-     *     *self = self.slice_from(1);
-     *     Some(head)
-     * ```
-     *
-     * Returns `None` if vector is empty
-     */
-    fn shift_ref(&mut self) -> Option<&'a T>;
-
-    /**
-     * Returns a mutable reference to the last element in this slice
-     * and adjusts the slice in place so that it no longer contains
-     * that element. O(1).
-     *
-     * Equivalent to:
-     *
-     * ```ignore
-     *     if self.len() == 0 { return None; }
-     *     let tail = &self[self.len() - 1];
-     *     *self = self.slice_to(self.len() - 1);
-     *     Some(tail)
-     * ```
-     *
-     * Returns `None` if slice is empty.
-     */
-    fn pop_ref(&mut self) -> Option<&'a T>;
-}
+    pub fn push(&mut self, value: T) {
+        if self.len == self.cap {
+            if self.cap == 0 { self.cap += 2 }
+            let old_size = self.cap * size_of::<T>();
+            self.cap = self.cap * 2;
+            let size = old_size * 2;
+            if old_size > size { fail!("capacity overflow") }
+            unsafe {
+                self.ptr = realloc_raw(self.ptr as *mut u8, size) as *mut T;
+            }
+        }
 
-impl<'a,T> ImmutableVector<'a, T> for &'a [T] {
-    #[inline]
-    fn slice(&self, start: uint, end: uint) -> &'a [T] {
-        assert!(start <= end);
-        assert!(end <= self.len());
         unsafe {
-            transmute(Slice {
-                    data: self.as_ptr().offset(start as int),
-                    len: (end - start)
-                })
+            let end = (self.ptr as *T).offset(self.len as int) as *mut T;
+            move_val_init(&mut *end, value);
+            self.len += 1;
         }
     }
 
-    #[inline]
-    fn slice_from(&self, start: uint) -> &'a [T] {
-        self.slice(start, self.len())
-    }
-
-    #[inline]
-    fn slice_to(&self, end: uint) -> &'a [T] {
-        self.slice(0, end)
-    }
-
-    #[inline]
-    fn iter(self) -> Items<'a, T> {
+    /// Shorten a vector, dropping excess elements.
+    ///
+    /// If `len` is greater than the vector's current length, this has no
+    /// effect.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3, 4);
+    /// vec.truncate(2);
+    /// assert_eq!(vec, vec!(1, 2));
+    /// ```
+    pub fn truncate(&mut self, len: uint) {
         unsafe {
-            let p = self.as_ptr();
-            if mem::size_of::<T>() == 0 {
-                Items{ptr: p,
-                      end: (p as uint + self.len()) as *T,
-                      marker: marker::ContravariantLifetime::<'a>}
-            } else {
-                Items{ptr: p,
-                      end: p.offset(self.len() as int),
-                      marker: marker::ContravariantLifetime::<'a>}
+            let mut i = len;
+            // drop any extra elements
+            while i < self.len {
+                ptr::read(self.as_slice().unsafe_ref(i));
+                i += 1;
             }
         }
+        self.len = len;
     }
 
+    /// Work with `self` as a slice.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// fn foo(slice: &[int]) {}
+    ///
+    /// let vec = vec!(1, 2);
+    /// foo(vec.as_slice());
+    /// ```
     #[inline]
-    fn rev_iter(self) -> RevItems<'a, T> {
-        self.iter().rev()
-    }
-
-    #[inline]
-    fn split(self, pred: 'a |&T| -> bool) -> Splits<'a, T> {
-        self.splitn(uint::MAX, pred)
-    }
-
-    #[inline]
-    fn splitn(self, n: uint, pred: 'a |&T| -> bool) -> Splits<'a, T> {
-        Splits {
-            v: self,
-            n: n,
-            pred: pred,
-            finished: false
-        }
+    pub fn as_slice<'a>(&'a self) -> &'a [T] {
+        let slice = Slice { data: self.ptr as *T, len: self.len };
+        unsafe { transmute(slice) }
     }
 
+    /// Work with `self` as a mutable slice.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// fn foo(slice: &mut [int]) {}
+    ///
+    /// let mut vec = vec!(1, 2);
+    /// foo(vec.as_mut_slice());
+    /// ```
     #[inline]
-    fn rsplit(self, pred: 'a |&T| -> bool) -> RevSplits<'a, T> {
-        self.rsplitn(uint::MAX, pred)
+    pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
+        let slice = Slice { data: self.ptr as *T, len: self.len };
+        unsafe { transmute(slice) }
     }
 
+    /// Creates a consuming iterator, that is, one that moves each
+    /// value out of the vector (from start to end). The vector cannot
+    /// be used after calling this.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let v = vec!(~"a", ~"b");
+    /// for s in v.move_iter() {
+    ///     // s has type ~str, not &~str
+    ///     println!("{}", s);
+    /// }
+    /// ```
     #[inline]
-    fn rsplitn(self, n: uint, pred: 'a |&T| -> bool) -> RevSplits<'a, T> {
-        RevSplits {
-            v: self,
-            n: n,
-            pred: pred,
-            finished: false
+    pub fn move_iter(self) -> MoveItems<T> {
+        unsafe {
+            let iter = transmute(self.as_slice().iter());
+            let ptr = self.ptr as *mut c_void;
+            forget(self);
+            MoveItems { allocation: ptr, iter: iter }
         }
     }
 
-    #[inline]
-    fn windows(self, size: uint) -> Windows<'a, T> {
-        assert!(size != 0);
-        Windows { v: self, size: size }
-    }
-
-    #[inline]
-    fn chunks(self, size: uint) -> Chunks<'a, T> {
-        assert!(size != 0);
-        Chunks { v: self, size: size }
-    }
-
-    #[inline]
-    fn get(&self, index: uint) -> Option<&'a T> {
-        if index < self.len() { Some(&self[index]) } else { None }
-    }
-
-    #[inline]
-    fn head(&self) -> Option<&'a T> {
-        if self.len() == 0 { None } else { Some(&self[0]) }
-    }
-
-    #[inline]
-    fn tail(&self) -> &'a [T] { self.slice(1, self.len()) }
-
-    #[inline]
-    fn tailn(&self, n: uint) -> &'a [T] { self.slice(n, self.len()) }
-
-    #[inline]
-    fn init(&self) -> &'a [T] {
-        self.slice(0, self.len() - 1)
-    }
-
-    #[inline]
-    fn initn(&self, n: uint) -> &'a [T] {
-        self.slice(0, self.len() - n)
-    }
-
-    #[inline]
-    fn last(&self) -> Option<&'a T> {
-            if self.len() == 0 { None } else { Some(&self[self.len() - 1]) }
-    }
 
+    /// Sets the length of a vector.
+    ///
+    /// This will explicitly set the size of the vector, without actually
+    /// modifying its buffers, so it is up to the caller to ensure that the
+    /// vector is actually the specified size.
     #[inline]
-    fn flat_map<U>(&self, f: |t: &T| -> ~[U]) -> ~[U] {
-        flat_map(*self, f)
+    pub unsafe fn set_len(&mut self, len: uint) {
+        self.len = len;
     }
 
+    /// Returns a reference to the value at index `index`.
+    ///
+    /// # Failure
+    ///
+    /// Fails if `index` is out of bounds
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3);
+    /// assert!(vec.get(1) == &2);
+    /// ```
     #[inline]
-    unsafe fn unsafe_ref(self, index: uint) -> &'a T {
-        transmute(self.repr().data.offset(index as int))
+    pub fn get<'a>(&'a self, index: uint) -> &'a T {
+        &self.as_slice()[index]
     }
 
+    /// Returns a mutable reference to the value at index `index`.
+    ///
+    /// # Failure
+    ///
+    /// Fails if `index` is out of bounds
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// *vec.get_mut(1) = 4;
+    /// assert_eq!(vec, vec!(1, 4, 3));
+    /// ```
     #[inline]
-    fn as_ptr(&self) -> *T {
-        self.repr().data
+    pub fn get_mut<'a>(&'a mut self, index: uint) -> &'a mut T {
+        &mut self.as_mut_slice()[index]
     }
 
-
-    fn bsearch(&self, f: |&T| -> Ordering) -> Option<uint> {
-        let mut base : uint = 0;
-        let mut lim : uint = self.len();
-
-        while lim != 0 {
-            let ix = base + (lim >> 1);
-            match f(&self[ix]) {
-                Equal => return Some(ix),
-                Less => {
-                    base = ix + 1;
-                    lim -= 1;
-                }
-                Greater => ()
-            }
-            lim >>= 1;
-        }
-        return None;
-    }
-
-    fn map<U>(&self, f: |t: &T| -> U) -> ~[U] {
-        self.iter().map(f).collect()
-    }
-
-    fn shift_ref(&mut self) -> Option<&'a T> {
-        if self.len() == 0 { return None; }
-        unsafe {
-            let s: &mut Slice<T> = transmute(self);
-            Some(&*raw::shift_ptr(s))
-        }
-    }
-
-    fn pop_ref(&mut self) -> Option<&'a T> {
-        if self.len() == 0 { return None; }
-        unsafe {
-            let s: &mut Slice<T> = transmute(self);
-            Some(&*raw::pop_ptr(s))
-        }
-    }
-}
-
-/// Extension methods for vectors contain `Eq` elements.
-pub trait ImmutableEqVector<T:Eq> {
-    /// Find the first index containing a matching value
-    fn position_elem(&self, t: &T) -> Option<uint>;
-
-    /// Find the last index containing a matching value
-    fn rposition_elem(&self, t: &T) -> Option<uint>;
-
-    /// Return true if a vector contains an element with the given value
-    fn contains(&self, x: &T) -> bool;
-
-    /// Returns true if `needle` is a prefix of the vector.
-    fn starts_with(&self, needle: &[T]) -> bool;
-
-    /// Returns true if `needle` is a suffix of the vector.
-    fn ends_with(&self, needle: &[T]) -> bool;
-}
-
-impl<'a,T:Eq> ImmutableEqVector<T> for &'a [T] {
+    /// Returns an iterator over references to the elements of the vector in
+    /// order.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3);
+    /// for num in vec.iter() {
+    ///     println!("{}", *num);
+    /// }
+    /// ```
     #[inline]
-    fn position_elem(&self, x: &T) -> Option<uint> {
-        self.iter().position(|y| *x == *y)
+    pub fn iter<'a>(&'a self) -> Items<'a,T> {
+        self.as_slice().iter()
     }
 
-    #[inline]
-    fn rposition_elem(&self, t: &T) -> Option<uint> {
-        self.iter().rposition(|x| *x == *t)
-    }
 
+    /// Returns an iterator over mutable references to the elements of the
+    /// vector in order.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// for num in vec.mut_iter() {
+    ///     *num = 0;
+    /// }
+    /// ```
     #[inline]
-    fn contains(&self, x: &T) -> bool {
-        self.iter().any(|elt| *x == *elt)
+    pub fn mut_iter<'a>(&'a mut self) -> MutItems<'a,T> {
+        self.as_mut_slice().mut_iter()
     }
 
+    /// Sort the vector, in place, using `compare` to compare elements.
+    ///
+    /// This sort is `O(n log n)` worst-case and stable, but allocates
+    /// approximately `2 * n`, where `n` is the length of `self`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = vec!(5i, 4, 1, 3, 2);
+    /// v.sort_by(|a, b| a.cmp(b));
+    /// assert_eq!(v, vec!(1, 2, 3, 4, 5));
+    ///
+    /// // reverse sorting
+    /// v.sort_by(|a, b| b.cmp(a));
+    /// assert_eq!(v, vec!(5, 4, 3, 2, 1));
+    /// ```
     #[inline]
-    fn starts_with(&self, needle: &[T]) -> bool {
-        let n = needle.len();
-        self.len() >= n && needle == self.slice_to(n)
+    pub fn sort_by(&mut self, compare: |&T, &T| -> Ordering) {
+        self.as_mut_slice().sort_by(compare)
     }
 
+    /// Returns a slice of `self` between `start` and `end`.
+    ///
+    /// # Failure
+    ///
+    /// Fails when `start` or `end` point outside the bounds of `self`, or when
+    /// `start` > `end`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3, 4);
+    /// assert!(vec.slice(0, 2) == [1, 2]);
+    /// ```
     #[inline]
-    fn ends_with(&self, needle: &[T]) -> bool {
-        let (m, n) = (self.len(), needle.len());
-        m >= n && needle == self.slice_from(m - n)
+    pub fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T] {
+        self.as_slice().slice(start, end)
     }
-}
-
-/// Extension methods for vectors containing `TotalOrd` elements.
-pub trait ImmutableTotalOrdVector<T: TotalOrd> {
-    /**
-     * Binary search a sorted vector for a given element.
-     *
-     * Returns the index of the element or None if not found.
-     */
-    fn bsearch_elem(&self, x: &T) -> Option<uint>;
-}
-
-impl<'a, T: TotalOrd> ImmutableTotalOrdVector<T> for &'a [T] {
-    fn bsearch_elem(&self, x: &T) -> Option<uint> {
-        self.bsearch(|p| p.cmp(x))
-    }
-}
 
-/// Extension methods for vectors containing `Clone` elements.
-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]);
-
-    /// Create an iterator that yields every possible permutation of the
-    /// vector in succession.
-    fn permutations(self) -> Permutations<T>;
-}
-
-impl<'a,T:Clone> ImmutableCloneableVector<T> for &'a [T] {
+    /// Returns a slice containing all but the first element of the vector.
+    ///
+    /// # Failure
+    ///
+    /// Fails when the vector is empty.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3);
+    /// assert!(vec.tail() == [2, 3]);
+    /// ```
     #[inline]
-    fn partitioned(&self, f: |&T| -> bool) -> (~[T], ~[T]) {
-        let mut lefts  = ~[];
-        let mut rights = ~[];
-
-        for elt in self.iter() {
-            if f(elt) {
-                lefts.push((*elt).clone());
-            } else {
-                rights.push((*elt).clone());
-            }
-        }
-
-        (lefts, rights)
+    pub fn tail<'a>(&'a self) -> &'a [T] {
+        self.as_slice().tail()
     }
 
-    fn permutations(self) -> Permutations<T> {
-        Permutations{
-            swaps: ElementSwaps::new(self.len()),
-            v: self.to_owned(),
-        }
-    }
-
-}
-
-/// Extension methods for owned vectors.
-pub trait OwnedVector<T> {
-    /// Creates a consuming iterator, that is, one that moves each
-    /// value out of the vector (from start to end). The vector cannot
-    /// be used after calling this.
+    /// Returns all but the first `n' elements of a vector.
+    ///
+    /// # Failure
     ///
-    /// # Examples
+    /// Fails when there are fewer than `n` elements in the vector.
+    ///
+    /// # Example
     ///
     /// ```rust
-    /// let v = ~[~"a", ~"b"];
-    /// for s in v.move_iter() {
-    ///   // s has type ~str, not &~str
-    ///   println!("{}", s);
-    /// }
+    /// let vec = vec!(1, 2, 3, 4);
+    /// assert!(vec.tailn(2) == [3, 4]);
     /// ```
-    fn move_iter(self) -> MoveItems<T>;
-    /// Creates a consuming iterator that moves out of the vector in
-    /// reverse order.
-    fn move_rev_iter(self) -> RevMoveItems<T>;
-
-    /**
-     * Reserves capacity for exactly `n` elements in the given vector.
-     *
-     * If the capacity for `self` is already equal to or greater than the requested
-     * capacity, then no action is taken.
-     *
-     * # Arguments
-     *
-     * * n - The number of elements to reserve space for
-     *
-     * # Failure
-     *
-     * This method always succeeds in reserving space for `n` elements, or it does
-     * not return.
-     */
-    fn reserve_exact(&mut self, n: uint);
-    /**
-     * Reserves capacity for at least `n` elements in the given vector.
-     *
-     * This function will over-allocate in order to amortize the allocation costs
-     * in scenarios where the caller may need to repeatedly reserve additional
-     * space.
-     *
-     * If the capacity for `self` is already equal to or greater than the requested
-     * capacity, then no action is taken.
-     *
-     * # Arguments
-     *
-     * * n - The number of elements to reserve space for
-     */
-    fn reserve(&mut self, n: uint);
-    /**
-     * Reserves capacity for at least `n` additional elements in the given vector.
-     *
-     * # Failure
-     *
-     * Fails if the new required capacity overflows uint.
-     *
-     * May also fail if `reserve` fails.
-     */
-    fn reserve_additional(&mut self, n: uint);
-    /// Returns the number of elements the vector can hold without reallocating.
-    fn capacity(&self) -> uint;
-    /// Shrink the capacity of the vector to match the length
-    fn shrink_to_fit(&mut self);
+    #[inline]
+    pub fn tailn<'a>(&'a self, n: uint) -> &'a [T] {
+        self.as_slice().tailn(n)
+    }
 
-    /// Append an element to a vector
-    fn push(&mut self, t: T);
-    /// Takes ownership of the vector `rhs`, moving all elements into
-    /// the current vector. This does not copy any elements, and it is
-    /// illegal to use the `rhs` vector after calling this method
-    /// (because it is moved here).
+    /// Returns a reference to the last element of a vector, or `None` if it is
+    /// empty.
     ///
     /// # Example
     ///
     /// ```rust
-    /// let mut a = ~[~1];
-    /// a.push_all_move(~[~2, ~3, ~4]);
-    /// assert!(a == ~[~1, ~2, ~3, ~4]);
+    /// let vec = vec!(1, 2, 3);
+    /// assert!(vec.last() == Some(&3));
     /// ```
-    fn push_all_move(&mut self, rhs: ~[T]);
-    /// Remove the last element from a vector and return it, or `None` if it is empty
-    fn pop(&mut self) -> Option<T>;
-    /// Removes the first element from a vector and return it, or `None` if it is empty
-    fn shift(&mut self) -> Option<T>;
-    /// Prepend an element to the vector
-    fn unshift(&mut self, x: T);
-
-    /// Insert an element at position i within v, shifting all
-    /// elements after position i one position to the right.
-    fn insert(&mut self, i: uint, x:T);
+    #[inline]
+    pub fn last<'a>(&'a self) -> Option<&'a T> {
+        self.as_slice().last()
+    }
 
-    /// Remove and return the element at position `i` within `v`,
-    /// shifting all elements after position `i` one position to the
-    /// left. Returns `None` if `i` is out of bounds.
+    /// Returns a mutable reference to the last element of a vector, or `None`
+    /// if it is empty.
     ///
     /// # Example
-    /// ```rust
-    /// let mut v = ~[1, 2, 3];
-    /// assert_eq!(v.remove(1), Some(2));
-    /// assert_eq!(v, ~[1, 3]);
     ///
-    /// assert_eq!(v.remove(4), None);
-    /// // v is unchanged:
-    /// assert_eq!(v, ~[1, 3]);
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// *vec.mut_last().unwrap() = 4;
+    /// assert_eq!(vec, vec!(1, 2, 4));
     /// ```
-    fn remove(&mut self, i: uint) -> Option<T>;
+    #[inline]
+    pub fn mut_last<'a>(&'a mut self) -> Option<&'a mut T> {
+        self.as_mut_slice().mut_last()
+    }
 
-    /// Remove an element from anywhere in the vector and return it, replacing it
-    /// with the last element. This does not preserve ordering, but is O(1).
+    /// Remove an element from anywhere in the vector and return it, replacing
+    /// it with the last element. This does not preserve ordering, but is O(1).
     ///
     /// Returns `None` if `index` is out of bounds.
     ///
     /// # Example
     /// ```rust
-    /// let mut v = ~[~"foo", ~"bar", ~"baz", ~"qux"];
+    /// let mut v = vec!(~"foo", ~"bar", ~"baz", ~"qux");
     ///
     /// assert_eq!(v.swap_remove(1), Some(~"bar"));
-    /// assert_eq!(v, ~[~"foo", ~"qux", ~"baz"]);
+    /// assert_eq!(v, vec!(~"foo", ~"qux", ~"baz"));
     ///
     /// assert_eq!(v.swap_remove(0), Some(~"foo"));
-    /// assert_eq!(v, ~[~"baz", ~"qux"]);
+    /// assert_eq!(v, vec!(~"baz", ~"qux"));
     ///
     /// assert_eq!(v.swap_remove(2), None);
     /// ```
-    fn swap_remove(&mut self, index: uint) -> Option<T>;
-
-    /// Shorten a vector, dropping excess elements.
-    fn truncate(&mut self, newlen: uint);
-
-    /**
-     * Like `filter()`, but in place.  Preserves order of `v`.  Linear time.
-     */
-    fn retain(&mut self, f: |t: &T| -> bool);
-
-    /**
-     * 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]);
-
-    /**
-     * Expands a vector in place, initializing the new elements to the result of
-     * a function.
-     *
-     * Function `init_op` is called `n` times with the values [0..`n`)
-     *
-     * # Arguments
-     *
-     * * n - The number of elements to add
-     * * init_op - A function to call to retrieve each appended element's
-     *             value
-     */
-    fn grow_fn(&mut self, n: uint, op: |uint| -> T);
-
-    /**
-     * Sets the length of a vector
-     *
-     * This will explicitly set the size of the vector, without actually
-     * modifying its buffers, so it is up to the caller to ensure that
-     * the vector is actually the specified size.
-     */
-    unsafe fn set_len(&mut self, new_len: uint);
-}
-
-impl<T> OwnedVector<T> for ~[T] {
-    #[inline]
-    fn move_iter(self) -> MoveItems<T> {
-        unsafe {
-            let iter = transmute(self.iter());
-            let ptr = transmute(self);
-            MoveItems { allocation: ptr, iter: iter }
-        }
-    }
-
     #[inline]
-    fn move_rev_iter(self) -> RevMoveItems<T> {
-        self.move_iter().rev()
-    }
-
-    fn reserve_exact(&mut self, n: uint) {
-        // Only make the (slow) call into the runtime if we have to
-        if self.capacity() < n {
-            unsafe {
-                let ptr: *mut *mut Vec<()> = transmute(self);
-                let alloc = n * mem::nonzero_size_of::<T>();
-                let size = alloc + mem::size_of::<Vec<()>>();
-                if alloc / mem::nonzero_size_of::<T>() != n || size < alloc {
-                    fail!("vector size is too large: {}", n);
-                }
-                *ptr = realloc_raw(*ptr as *mut u8, size)
-                                   as *mut Vec<()>;
-                (**ptr).alloc = alloc;
-            }
-        }
-    }
-
-    #[inline]
-    fn reserve(&mut self, n: uint) {
-        self.reserve_exact(checked_next_power_of_two(n).unwrap_or(n));
-    }
-
-    #[inline]
-    fn reserve_additional(&mut self, n: uint) {
-        if self.capacity() - self.len() < n {
-            match self.len().checked_add(&n) {
-                None => fail!("vec::reserve_additional: `uint` overflow"),
-                Some(new_cap) => self.reserve(new_cap)
-            }
-        }
-    }
-
-    #[inline]
-    fn capacity(&self) -> uint {
-        unsafe {
-            let repr: **Vec<()> = transmute(self);
-            (**repr).alloc / mem::nonzero_size_of::<T>()
-        }
-    }
-
-    fn shrink_to_fit(&mut self) {
-        unsafe {
-            let ptr: *mut *mut Vec<()> = transmute(self);
-            let alloc = (**ptr).fill;
-            let size = alloc + mem::size_of::<Vec<()>>();
-            *ptr = realloc_raw(*ptr as *mut u8, size) as *mut Vec<()>;
-            (**ptr).alloc = alloc;
-        }
-    }
-
-    #[inline]
-    fn push(&mut self, t: T) {
-        unsafe {
-            let repr: **Vec<()> = transmute(&mut *self);
-            let fill = (**repr).fill;
-            if (**repr).alloc <= fill {
-                self.reserve_additional(1);
-            }
-
-            push_fast(self, t);
-        }
-
-        // This doesn't bother to make sure we have space.
-        #[inline] // really pretty please
-        unsafe fn push_fast<T>(this: &mut ~[T], t: T) {
-            let repr: **mut Vec<u8> = transmute(this);
-            let fill = (**repr).fill;
-            (**repr).fill += mem::nonzero_size_of::<T>();
-            let p = &((**repr).data) as *u8;
-            let p = p.offset(fill as int) as *mut T;
-            mem::move_val_init(&mut(*p), t);
+    pub fn swap_remove(&mut self, index: uint) -> Option<T> {
+        let length = self.len();
+        if index < length - 1 {
+            self.as_mut_slice().swap(index, length - 1);
+        } else if index >= length {
+            return None
         }
+        self.pop()
     }
 
+    /// Prepend an element to the vector.
+    ///
+    /// # Warning
+    ///
+    /// This is an O(n) operation as it requires copying every element in the
+    /// vector.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// vec.unshift(4);
+    /// assert_eq!(vec, vec!(4, 1, 2, 3));
+    /// ```
     #[inline]
-    fn push_all_move(&mut self, mut rhs: ~[T]) {
-        let self_len = self.len();
-        let rhs_len = rhs.len();
-        let new_len = self_len + rhs_len;
-        self.reserve_additional(rhs.len());
-        unsafe { // Note: infallible.
-            let self_p = self.as_mut_ptr();
-            let rhs_p = rhs.as_ptr();
-            ptr::copy_memory(self_p.offset(self_len as int), rhs_p, rhs_len);
-            self.set_len(new_len);
-            rhs.set_len(0);
-        }
-    }
-
-    fn pop(&mut self) -> Option<T> {
-        match self.len() {
-            0  => None,
-            ln => {
-                let valptr = &mut self[ln - 1u] as *mut T;
-                unsafe {
-                    self.set_len(ln - 1u);
-                    Some(ptr::read(&*valptr))
-                }
-            }
-        }
+    pub fn unshift(&mut self, element: T) {
+        self.insert(0, element)
     }
 
-
+    /// Removes the first element from a vector and returns it, or `None` if
+    /// the vector is empty.
+    ///
+    /// # Warning
+    ///
+    /// This is an O(n) operation as it requires copying every element in the
+    /// vector.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// assert!(vec.shift() == Some(1));
+    /// assert_eq!(vec, vec!(2, 3));
+    /// ```
     #[inline]
-    fn shift(&mut self) -> Option<T> {
+    pub fn shift(&mut self) -> Option<T> {
         self.remove(0)
     }
 
-    #[inline]
-    fn unshift(&mut self, x: T) {
-        self.insert(0, x)
-    }
-
-    fn insert(&mut self, i: uint, x: T) {
+    /// Insert an element at position `index` within the vector, shifting all
+    /// elements after position i one position to the right.
+    ///
+    /// # Failure
+    ///
+    /// Fails if `index` is out of bounds of the vector.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// vec.insert(1, 4);
+    /// assert_eq!(vec, vec!(1, 4, 2, 3));
+    /// ```
+    pub fn insert(&mut self, index: uint, element: T) {
         let len = self.len();
-        assert!(i <= len);
+        assert!(index <= len);
         // space for the new element
-        self.reserve_additional(1);
+        self.reserve(len + 1);
 
         unsafe { // infallible
             // The spot to put the new value
-            let p = self.as_mut_ptr().offset(i as int);
-            // Shift everything over to make space. (Duplicating the
-            // `i`th element into two consecutive places.)
-            ptr::copy_memory(p.offset(1), &*p, len - i);
-            // Write it in, overwriting the first copy of the `i`th
-            // element.
-            mem::move_val_init(&mut *p, x);
+            {
+                let p = self.as_mut_ptr().offset(index as int);
+                // Shift everything over to make space. (Duplicating the
+                // `index`th element into two consecutive places.)
+                ptr::copy_memory(p.offset(1), &*p, len - index);
+                // Write it in, overwriting the first copy of the `index`th
+                // element.
+                move_val_init(&mut *p, element);
+            }
             self.set_len(len + 1);
         }
     }
 
-    fn remove(&mut self, i: uint) -> Option<T> {
+    /// Remove and return the element at position `index` within the vector,
+    /// shifting all elements after position `index` one position to the left.
+    /// Returns `None` if `i` is out of bounds.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = vec!(1, 2, 3);
+    /// assert_eq!(v.remove(1), Some(2));
+    /// assert_eq!(v, vec!(1, 3));
+    ///
+    /// assert_eq!(v.remove(4), None);
+    /// // v is unchanged:
+    /// assert_eq!(v, vec!(1, 3));
+    /// ```
+    pub fn remove(&mut self, index: uint) -> Option<T> {
         let len = self.len();
-        if i < len {
+        if index < len {
             unsafe { // infallible
-                // the place we are taking from.
-                let ptr = self.as_mut_ptr().offset(i as int);
-                // copy it out, unsafely having a copy of the value on
-                // the stack and in the vector at the same time.
-                let ret = Some(ptr::read(ptr as *T));
-
-                // Shift everything down to fill in that spot.
-                ptr::copy_memory(ptr, &*ptr.offset(1), len - i - 1);
+                let ret;
+                {
+                    // the place we are taking from.
+                    let ptr = self.as_mut_ptr().offset(index as int);
+                    // copy it out, unsafely having a copy of the value on
+                    // the stack and in the vector at the same time.
+                    ret = Some(ptr::read(ptr as *T));
+
+                    // Shift everything down to fill in that spot.
+                    ptr::copy_memory(ptr, &*ptr.offset(1), len - index - 1);
+                }
                 self.set_len(len - 1);
-
                 ret
             }
         } else {
             None
         }
     }
-    fn swap_remove(&mut self, index: uint) -> Option<T> {
-        let ln = self.len();
-        if index < ln - 1 {
-            self.swap(index, ln - 1);
-        } else if index >= ln {
-            return None
-        }
-        self.pop()
-    }
-    fn truncate(&mut self, newlen: uint) {
-        let oldlen = self.len();
-        assert!(newlen <= oldlen);
 
-        unsafe {
-            let p = self.as_mut_ptr();
-            // This loop is optimized out for non-drop types.
-            for i in range(newlen, oldlen) {
-                ptr::read_and_zero(p.offset(i as int));
-            }
-        }
-        unsafe { self.set_len(newlen); }
+    ///Apply a function to each element of a vector and return the results.
+    #[inline]
+    #[deprecated="Use `xs.iter().map(closure)` instead."]
+    pub fn map<U>(&self, f: |t: &T| -> U) -> Vec<U> {
+        self.iter().map(f).collect()
     }
 
-    fn retain(&mut self, f: |t: &T| -> bool) {
-        let len = self.len();
-        let mut deleted: uint = 0;
-
-        for i in range(0u, len) {
-            if !f(&self[i]) {
-                deleted += 1;
-            } else if deleted > 0 {
-                self.swap(i - deleted, i);
-            }
-        }
-
-        if deleted > 0 {
-            self.truncate(len - deleted);
+    /// Takes ownership of the vector `other`, moving all elements into
+    /// the current vector. This does not copy any elements, and it is
+    /// illegal to use the `other` vector after calling this method
+    /// (because it is moved here).
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(~1);
+    /// vec.push_all_move(vec!(~2, ~3, ~4));
+    /// assert_eq!(vec, vec!(~1, ~2, ~3, ~4));
+    /// ```
+    pub fn push_all_move(&mut self, other: Vec<T>) {
+        for element in other.move_iter() {
+            self.push(element)
         }
     }
 
+    /// Returns a mutable slice of `self` between `start` and `end`.
+    ///
+    /// # Failure
+    ///
+    /// Fails when `start` or `end` point outside the bounds of `self`, or when
+    /// `start` > `end`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3, 4);
+    /// assert!(vec.mut_slice(0, 2) == [1, 2]);
+    /// ```
     #[inline]
-    fn partition(self, f: |&T| -> bool) -> (~[T], ~[T]) {
-        let mut lefts  = ~[];
-        let mut rights = ~[];
-
-        for elt in self.move_iter() {
-            if f(&elt) {
-                lefts.push(elt);
-            } else {
-                rights.push(elt);
-            }
-        }
-
-        (lefts, rights)
-    }
-    fn grow_fn(&mut self, n: uint, op: |uint| -> T) {
-        let new_len = self.len() + n;
-        self.reserve(new_len);
-        let mut i: uint = 0u;
-        while i < n {
-            self.push(op(i));
-            i += 1u;
-        }
+    pub fn mut_slice<'a>(&'a mut self, start: uint, end: uint)
+                         -> &'a mut [T] {
+        self.as_mut_slice().mut_slice(start, end)
     }
 
+    /// Reverse the order of elements in a vector, in place.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = vec!(1, 2, 3);
+    /// v.reverse();
+    /// assert_eq!(v, vec!(3, 2, 1));
+    /// ```
     #[inline]
-    unsafe fn set_len(&mut self, new_len: uint) {
-        let repr: **mut Vec<()> = transmute(self);
-        (**repr).fill = new_len * mem::nonzero_size_of::<T>();
+    pub fn reverse(&mut self) {
+        self.as_mut_slice().reverse()
     }
-}
 
-impl<T> Mutable for ~[T] {
-    /// Clear the vector, removing all values.
-    fn clear(&mut self) { self.truncate(0) }
-}
+    /// Returns a slice of `self` from `start` to the end of the vec.
+    ///
+    /// # Failure
+    ///
+    /// Fails when `start` points outside the bounds of self.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3);
+    /// assert!(vec.slice_from(1) == [2, 3]);
+    /// ```
+    #[inline]
+    pub fn slice_from<'a>(&'a self, start: uint) -> &'a [T] {
+        self.as_slice().slice_from(start)
+    }
 
-/// Extension methods for owned vectors containing `Clone` elements.
-pub trait OwnedCloneableVector<T:Clone> {
-    /// Iterates over the slice `rhs`, copies each element, and then appends it to
-    /// the vector provided `v`. The `rhs` vector is traversed in-order.
+    /// Returns a slice of self from the start of the vec to `end`.
+    ///
+    /// # Failure
+    ///
+    /// Fails when `end` points outside the bounds of self.
     ///
     /// # Example
     ///
     /// ```rust
-    /// let mut a = ~[1];
-    /// a.push_all([2, 3, 4]);
-    /// assert!(a == ~[1, 2, 3, 4]);
+    /// let vec = vec!(1, 2, 3);
+    /// assert!(vec.slice_to(2) == [1, 2]);
     /// ```
-    fn push_all(&mut self, rhs: &[T]);
+    #[inline]
+    pub fn slice_to<'a>(&'a self, end: uint) -> &'a [T] {
+        self.as_slice().slice_to(end)
+    }
 
-    /**
-     * Expands a vector in place, initializing the new elements to a given value
-     *
-     * # Arguments
-     *
-     * * n - The number of elements to add
-     * * initval - The value for the new elements
-     */
-    fn grow(&mut self, n: uint, initval: &T);
+    /// Returns a slice containing all but the last element of the vector.
+    ///
+    /// # Failure
+    ///
+    /// Fails if the vector is empty
+    #[inline]
+    pub fn init<'a>(&'a self) -> &'a [T] {
+        self.slice(0, self.len() - 1)
+    }
 
-    /**
-     * Sets the value of a vector element at a given index, growing the vector as
-     * needed
-     *
-     * Sets the element at position `index` to `val`. If `index` is past the end
-     * of the vector, expands the vector by replicating `initval` to fill the
-     * intervening space.
-     */
-    fn grow_set(&mut self, index: uint, initval: &T, val: T);
-}
 
-impl<T:Clone> OwnedCloneableVector<T> for ~[T] {
+    /// Returns an unsafe pointer to the vector's buffer.
+    ///
+    /// The caller must ensure that the vector outlives the pointer this
+    /// function returns, or else it will end up pointing to garbage.
+    ///
+    /// Modifying the vector may cause its buffer to be reallocated, which
+    /// would also make any pointers to it invalid.
     #[inline]
-    fn push_all(&mut self, rhs: &[T]) {
-        let new_len = self.len() + rhs.len();
-        self.reserve_exact(new_len);
-
-        for elt in rhs.iter() {
-            self.push((*elt).clone())
-        }
+    pub fn as_ptr(&self) -> *T {
+        self.as_slice().as_ptr()
     }
-    fn grow(&mut self, n: uint, initval: &T) {
-        let new_len = self.len() + n;
-        self.reserve(new_len);
-        let mut i: uint = 0u;
 
-        while i < n {
-            self.push((*initval).clone());
-            i += 1u;
-        }
+    /// Returns a mutable unsafe pointer to the vector's buffer.
+    ///
+    /// The caller must ensure that the vector outlives the pointer this
+    /// function returns, or else it will end up pointing to garbage.
+    ///
+    /// Modifying the vector may cause its buffer to be reallocated, which
+    /// would also make any pointers to it invalid.
+    #[inline]
+    pub fn as_mut_ptr(&mut self) -> *mut T {
+        self.as_mut_slice().as_mut_ptr()
     }
-    fn grow_set(&mut self, index: uint, initval: &T, val: T) {
-        let l = self.len();
-        if index >= l { self.grow(index - l + 1u, initval); }
-        self[index] = val;
+}
+
+impl<T:TotalOrd> Vec<T> {
+    /// Sorts the vector in place.
+    ///
+    /// This sort is `O(n log n)` worst-case and stable, but allocates
+    /// approximately `2 * n`, where `n` is the length of `self`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(3i, 1, 2);
+    /// vec.sort();
+    /// assert_eq!(vec, vec!(1, 2, 3));
+    /// ```
+    pub fn sort(&mut self) {
+        self.as_mut_slice().sort()
     }
 }
 
-/// Extension methods for owned vectors containing `Eq` elements.
-pub trait OwnedEqVector<T:Eq> {
-    /**
-    * Remove consecutive repeated elements from a vector; if the vector is
-    * sorted, this removes all duplicates.
-    */
-    fn dedup(&mut self);
+impl<T> Mutable for Vec<T> {
+    #[inline]
+    fn clear(&mut self) {
+        self.truncate(0)
+    }
 }
 
-impl<T:Eq> OwnedEqVector<T> for ~[T] {
-    fn dedup(&mut self) {
+impl<T:Eq> Vec<T> {
+    /// Return true if a vector contains an element with the given value
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3);
+    /// assert!(vec.contains(&1));
+    /// ```
+    pub fn contains(&self, x: &T) -> bool {
+        self.as_slice().contains(x)
+    }
+
+    /// Remove consecutive repeated elements in the vector.
+    ///
+    /// If the vector is sorted, this removes all duplicates.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 2, 3, 2);
+    /// vec.dedup();
+    /// assert_eq!(vec, vec!(1, 2, 3, 2));
+    /// ```
+    pub fn dedup(&mut self) {
         unsafe {
             // Although we have a mutable reference to `self`, we cannot make
             // *arbitrary* changes. The `Eq` comparisons could fail, so we
@@ -1802,7 +1150,7 @@ impl<T:Eq> OwnedEqVector<T> for ~[T] {
             if ln < 1 { return; }
 
             // Avoid bounds checks by using unsafe pointers.
-            let p = self.as_mut_ptr();
+            let p = self.as_mut_slice().as_mut_ptr();
             let mut r = 1;
             let mut w = 1;
 
@@ -1824,1068 +1172,67 @@ impl<T:Eq> OwnedEqVector<T> for ~[T] {
     }
 }
 
-fn insertion_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
-    let len = v.len() as int;
-    let buf_v = v.as_mut_ptr();
-
-    // 1 <= i < len;
-    for i in range(1, len) {
-        // j satisfies: 0 <= j <= i;
-        let mut j = i;
-        unsafe {
-            // `i` is in bounds.
-            let read_ptr = buf_v.offset(i) as *T;
-
-            // find where to insert, we need to do strict <,
-            // rather than <=, to maintain stability.
-
-            // 0 <= j - 1 < len, so .offset(j - 1) is in bounds.
-            while j > 0 &&
-                    compare(&*read_ptr, &*buf_v.offset(j - 1)) == Less {
-                j -= 1;
-            }
-
-            // shift everything to the right, to make space to
-            // insert this value.
-
-            // j + 1 could be `len` (for the last `i`), but in
-            // that case, `i == j` so we don't copy. The
-            // `.offset(j)` is always in bounds.
-
-            if i != j {
-                let tmp = ptr::read(read_ptr);
-                ptr::copy_memory(buf_v.offset(j + 1),
-                                 &*buf_v.offset(j),
-                                 (i - j) as uint);
-                ptr::copy_nonoverlapping_memory(buf_v.offset(j),
-                                                &tmp as *T,
-                                                1);
-                cast::forget(tmp);
-            }
-        }
-    }
-}
-
-fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
-    // warning: this wildly uses unsafe.
-    static BASE_INSERTION: uint = 32;
-    static LARGE_INSERTION: uint = 16;
-
-    // FIXME #12092: smaller insertion runs seems to make sorting
-    // vectors of large elements a little faster on some platforms,
-    // but hasn't been tested/tuned extensively
-    let insertion = if size_of::<T>() <= 16 {
-        BASE_INSERTION
-    } else {
-        LARGE_INSERTION
-    };
-
-    let len = v.len();
-
-    // short vectors get sorted in-place via insertion sort to avoid allocations
-    if len <= insertion {
-        insertion_sort(v, compare);
-        return;
-    }
-
-    // allocate some memory to use as scratch memory, we keep the
-    // length 0 so we can keep shallow copies of the contents of `v`
-    // without risking the dtors running on an object twice if
-    // `compare` fails.
-    let mut working_space = with_capacity(2 * len);
-    // these both are buffers of length `len`.
-    let mut buf_dat = working_space.as_mut_ptr();
-    let mut buf_tmp = unsafe {buf_dat.offset(len as int)};
-
-    // length `len`.
-    let buf_v = v.as_ptr();
-
-    // step 1. sort short runs with insertion sort. This takes the
-    // values from `v` and sorts them into `buf_dat`, leaving that
-    // with sorted runs of length INSERTION.
-
-    // We could hardcode the sorting comparisons here, and we could
-    // manipulate/step the pointers themselves, rather than repeatedly
-    // .offset-ing.
-    for start in range_step(0, len, insertion) {
-        // start <= i < len;
-        for i in range(start, cmp::min(start + insertion, len)) {
-            // j satisfies: start <= j <= i;
-            let mut j = i as int;
-            unsafe {
-                // `i` is in bounds.
-                let read_ptr = buf_v.offset(i as int);
-
-                // find where to insert, we need to do strict <,
-                // rather than <=, to maintain stability.
-
-                // start <= j - 1 < len, so .offset(j - 1) is in
-                // bounds.
-                while j > start as int &&
-                        compare(&*read_ptr, &*buf_dat.offset(j - 1)) == Less {
-                    j -= 1;
-                }
-
-                // shift everything to the right, to make space to
-                // insert this value.
-
-                // j + 1 could be `len` (for the last `i`), but in
-                // that case, `i == j` so we don't copy. The
-                // `.offset(j)` is always in bounds.
-                ptr::copy_memory(buf_dat.offset(j + 1),
-                                 &*buf_dat.offset(j),
-                                 i - j as uint);
-                ptr::copy_nonoverlapping_memory(buf_dat.offset(j), read_ptr, 1);
-            }
-        }
-    }
-
-    // step 2. merge the sorted runs.
-    let mut width = insertion;
-    while width < len {
-        // merge the sorted runs of length `width` in `buf_dat` two at
-        // a time, placing the result in `buf_tmp`.
-
-        // 0 <= start <= len.
-        for start in range_step(0, len, 2 * width) {
-            // manipulate pointers directly for speed (rather than
-            // using a `for` loop with `range` and `.offset` inside
-            // that loop).
-            unsafe {
-                // the end of the first run & start of the
-                // second. Offset of `len` is defined, since this is
-                // precisely one byte past the end of the object.
-                let right_start = buf_dat.offset(cmp::min(start + width, len) as int);
-                // end of the second. Similar reasoning to the above re safety.
-                let right_end_idx = cmp::min(start + 2 * width, len);
-                let right_end = buf_dat.offset(right_end_idx as int);
-
-                // the pointers to the elements under consideration
-                // from the two runs.
-
-                // both of these are in bounds.
-                let mut left = buf_dat.offset(start as int);
-                let mut right = right_start;
-
-                // where we're putting the results, it is a run of
-                // length `2*width`, so we step it once for each step
-                // of either `left` or `right`.  `buf_tmp` has length
-                // `len`, so these are in bounds.
-                let mut out = buf_tmp.offset(start as int);
-                let out_end = buf_tmp.offset(right_end_idx as int);
-
-                while out < out_end {
-                    // Either the left or the right run are exhausted,
-                    // so just copy the remainder from the other run
-                    // and move on; this gives a huge speed-up (order
-                    // of 25%) for mostly sorted vectors (the best
-                    // case).
-                    if left == right_start {
-                        // the number remaining in this run.
-                        let elems = (right_end as uint - right as uint) / mem::size_of::<T>();
-                        ptr::copy_nonoverlapping_memory(out, &*right, elems);
-                        break;
-                    } else if right == right_end {
-                        let elems = (right_start as uint - left as uint) / mem::size_of::<T>();
-                        ptr::copy_nonoverlapping_memory(out, &*left, elems);
-                        break;
-                    }
-
-                    // check which side is smaller, and that's the
-                    // next element for the new run.
-
-                    // `left < right_start` and `right < right_end`,
-                    // so these are valid.
-                    let to_copy = if compare(&*left, &*right) == Greater {
-                        step(&mut right)
-                    } else {
-                        step(&mut left)
-                    };
-                    ptr::copy_nonoverlapping_memory(out, &*to_copy, 1);
-                    step(&mut out);
-                }
-            }
-        }
-
-        mem::swap(&mut buf_dat, &mut buf_tmp);
-
-        width *= 2;
-    }
-
-    // write the result to `v` in one go, so that there are never two copies
-    // of the same object in `v`.
-    unsafe {
-        ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), &*buf_dat, len);
-    }
-
-    // increment the pointer, returning the old pointer.
-    #[inline(always)]
-    unsafe fn step<T>(ptr: &mut *mut T) -> *mut T {
-        let old = *ptr;
-        *ptr = ptr.offset(1);
-        old
-    }
-}
-
-/// Extension methods for vectors such that their elements are
-/// mutable.
-pub trait MutableVector<'a, T> {
-    /// Work with `self` as a mut slice.
-    /// Primarily intended for getting a &mut [T] from a [T, ..N].
-    fn as_mut_slice(self) -> &'a mut [T];
-
-    /// Return a slice that points into another slice.
-    fn mut_slice(self, start: uint, end: uint) -> &'a mut [T];
-
-    /**
-     * Returns a slice of self from `start` to the end of the vec.
-     *
-     * Fails when `start` points outside the bounds of self.
-     */
-    fn mut_slice_from(self, start: uint) -> &'a mut [T];
-
-    /**
-     * Returns a slice of self from the start of the vec to `end`.
-     *
-     * Fails when `end` points outside the bounds of self.
-     */
-    fn mut_slice_to(self, end: uint) -> &'a mut [T];
-
-    /// Returns an iterator that allows modifying each value
-    fn mut_iter(self) -> MutItems<'a, T>;
-
-    /// Returns a mutable pointer to the last item in the vector.
-    fn mut_last(self) -> Option<&'a mut T>;
-
-    /// Returns a reversed iterator that allows modifying each value
-    fn mut_rev_iter(self) -> RevMutItems<'a, T>;
-
-    /// Returns an iterator over the mutable subslices of the vector
-    /// which are separated by elements that match `pred`.  The
-    /// matched element is not contained in the subslices.
-    fn mut_split(self, pred: 'a |&T| -> bool) -> MutSplits<'a, T>;
-
-    /**
-     * Returns an iterator over `size` elements of the vector at a time.
-     * The chunks are mutable and do not overlap. If `size` does not divide the
-     * length of the vector, then the last chunk will not have length
-     * `size`.
-     *
-     * # Failure
-     *
-     * Fails if `size` is 0.
-     */
-    fn mut_chunks(self, chunk_size: uint) -> MutChunks<'a, T>;
-
-    /**
-     * Returns a mutable reference to the first element in this slice
-     * and adjusts the slice in place so that it no longer contains
-     * that element. O(1).
-     *
-     * Equivalent to:
-     *
-     * ```ignore
-     *     if self.len() == 0 { return None; }
-     *     let head = &mut self[0];
-     *     *self = self.mut_slice_from(1);
-     *     Some(head)
-     * ```
-     *
-     * Returns `None` if slice is empty
-     */
-    fn mut_shift_ref(&mut self) -> Option<&'a mut T>;
-
-    /**
-     * Returns a mutable reference to the last element in this slice
-     * and adjusts the slice in place so that it no longer contains
-     * that element. O(1).
-     *
-     * Equivalent to:
-     *
-     * ```ignore
-     *     if self.len() == 0 { return None; }
-     *     let tail = &mut self[self.len() - 1];
-     *     *self = self.mut_slice_to(self.len() - 1);
-     *     Some(tail)
-     * ```
-     *
-     * Returns `None` if slice is empty.
-     */
-    fn mut_pop_ref(&mut self) -> Option<&'a mut T>;
-
-    /// Swaps two elements in a vector.
-    ///
-    /// Fails if `a` or `b` are out of bounds.
-    ///
-    /// # Arguments
-    ///
-    /// * a - The index of the first element
-    /// * b - The index of the second element
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut v = ["a", "b", "c", "d"];
-    /// v.swap(1, 3);
-    /// assert!(v == ["a", "d", "c", "b"]);
-    /// ```
-    fn swap(self, a: uint, b: uint);
-
-
-    /// Divides one `&mut` into two at an index.
-    ///
-    /// The first will contain all indices from `[0, mid)` (excluding
-    /// the index `mid` itself) and the second will contain all
-    /// indices from `[mid, len)` (excluding the index `len` itself).
-    ///
-    /// Fails if `mid > len`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut v = [1, 2, 3, 4, 5, 6];
-    ///
-    /// // scoped to restrict the lifetime of the borrows
-    /// {
-    ///    let (left, right) = v.mut_split_at(0);
-    ///    assert!(left == &mut []);
-    ///    assert!(right == &mut [1, 2, 3, 4, 5, 6]);
-    /// }
-    ///
-    /// {
-    ///     let (left, right) = v.mut_split_at(2);
-    ///     assert!(left == &mut [1, 2]);
-    ///     assert!(right == &mut [3, 4, 5, 6]);
-    /// }
-    ///
-    /// {
-    ///     let (left, right) = v.mut_split_at(6);
-    ///     assert!(left == &mut [1, 2, 3, 4, 5, 6]);
-    ///     assert!(right == &mut []);
-    /// }
-    /// ```
-    fn mut_split_at(self, mid: uint) -> (&'a mut [T], &'a mut [T]);
-
-    /// Reverse the order of elements in a vector, in place.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut v = [1, 2, 3];
-    /// v.reverse();
-    /// assert!(v == [3, 2, 1]);
-    /// ```
-    fn reverse(self);
-
-    /// Sort the vector, in place, using `compare` to compare
-    /// elements.
-    ///
-    /// This sort is `O(n log n)` worst-case and stable, but allocates
-    /// approximately `2 * n`, where `n` is the length of `self`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut v = [5i, 4, 1, 3, 2];
-    /// v.sort_by(|a, b| a.cmp(b));
-    /// assert!(v == [1, 2, 3, 4, 5]);
-    ///
-    /// // reverse sorting
-    /// v.sort_by(|a, b| b.cmp(a));
-    /// assert!(v == [5, 4, 3, 2, 1]);
-    /// ```
-    fn sort_by(self, compare: |&T, &T| -> Ordering);
-
-    /**
-     * Consumes `src` and moves as many elements as it can into `self`
-     * from the range [start,end).
-     *
-     * Returns the number of elements copied (the shorter of self.len()
-     * and end - start).
-     *
-     * # Arguments
-     *
-     * * src - A mutable vector of `T`
-     * * start - The index into `src` to start copying from
-     * * end - The index into `str` to stop copying from
-     */
-    fn move_from(self, src: ~[T], start: uint, end: uint) -> uint;
-
-    /// Returns an unsafe mutable pointer to the element in index
-    unsafe fn unsafe_mut_ref(self, index: uint) -> &'a mut T;
-
-    /// Return an unsafe mutable pointer to the vector's buffer.
-    ///
-    /// The caller must ensure that the vector outlives the pointer this
-    /// function returns, or else it will end up pointing to garbage.
-    ///
-    /// Modifying the vector may cause its buffer to be reallocated, which
-    /// would also make any pointers to it invalid.
-    #[inline]
-    fn as_mut_ptr(self) -> *mut T;
-
-    /// Unsafely sets the element in index to the value.
-    ///
-    /// This performs no bounds checks, and it is undefined behaviour
-    /// if `index` is larger than the length of `self`. However, it
-    /// does run the destructor at `index`. It is equivalent to
-    /// `self[index] = val`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut v = ~[~"foo", ~"bar", ~"baz"];
-    ///
-    /// unsafe {
-    ///     // `~"baz"` is deallocated.
-    ///     v.unsafe_set(2, ~"qux");
-    ///
-    ///     // Out of bounds: could cause a crash, or overwriting
-    ///     // other data, or something else.
-    ///     // v.unsafe_set(10, ~"oops");
-    /// }
-    /// ```
-    unsafe fn unsafe_set(self, index: uint, val: T);
-
-    /// Unchecked vector index assignment.  Does not drop the
-    /// old value and hence is only suitable when the vector
-    /// is newly allocated.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut v = [~"foo", ~"bar"];
-    ///
-    /// // memory leak! `~"bar"` is not deallocated.
-    /// unsafe { v.init_elem(1, ~"baz"); }
-    /// ```
-    unsafe fn init_elem(self, i: uint, val: T);
-
-    /// Copies raw bytes from `src` to `self`.
-    ///
-    /// This does not run destructors on the overwritten elements, and
-    /// ignores move semantics. `self` and `src` must not
-    /// overlap. Fails if `self` is shorter than `src`.
-    unsafe fn copy_memory(self, src: &[T]);
-}
-
-impl<'a,T> MutableVector<'a, T> for &'a mut [T] {
-    #[inline]
-    fn as_mut_slice(self) -> &'a mut [T] { self }
-
-    fn mut_slice(self, start: uint, end: uint) -> &'a mut [T] {
-        assert!(start <= end);
-        assert!(end <= self.len());
-        unsafe {
-            transmute(Slice {
-                    data: self.as_mut_ptr().offset(start as int) as *T,
-                    len: (end - start)
-                })
-        }
-    }
-
-    #[inline]
-    fn mut_slice_from(self, start: uint) -> &'a mut [T] {
-        let len = self.len();
-        self.mut_slice(start, len)
-    }
-
-    #[inline]
-    fn mut_slice_to(self, end: uint) -> &'a mut [T] {
-        self.mut_slice(0, end)
-    }
-
-    #[inline]
-    fn mut_split_at(self, mid: uint) -> (&'a mut [T], &'a mut [T]) {
-        unsafe {
-            let len = self.len();
-            let self2: &'a mut [T] = cast::transmute_copy(&self);
-            (self.mut_slice(0, mid), self2.mut_slice(mid, len))
-        }
-    }
-
-    #[inline]
-    fn mut_iter(self) -> MutItems<'a, T> {
-        unsafe {
-            let p = self.as_mut_ptr();
-            if mem::size_of::<T>() == 0 {
-                MutItems{ptr: p,
-                         end: (p as uint + self.len()) as *mut T,
-                         marker: marker::ContravariantLifetime::<'a>,
-                         marker2: marker::NoPod}
-            } else {
-                MutItems{ptr: p,
-                         end: p.offset(self.len() as int),
-                         marker: marker::ContravariantLifetime::<'a>,
-                         marker2: marker::NoPod}
-            }
-        }
-    }
-
-    #[inline]
-    fn mut_last(self) -> Option<&'a mut T> {
-        let len = self.len();
-        if len == 0 { return None; }
-        Some(&mut self[len - 1])
-    }
-
-    #[inline]
-    fn mut_rev_iter(self) -> RevMutItems<'a, T> {
-        self.mut_iter().rev()
-    }
-
-    #[inline]
-    fn mut_split(self, pred: 'a |&T| -> bool) -> MutSplits<'a, T> {
-        MutSplits { v: self, pred: pred, finished: false }
-    }
-
-    #[inline]
-    fn mut_chunks(self, chunk_size: uint) -> MutChunks<'a, T> {
-        assert!(chunk_size > 0);
-        MutChunks { v: self, chunk_size: chunk_size }
-    }
-
-    fn mut_shift_ref(&mut self) -> Option<&'a mut T> {
-        if self.len() == 0 { return None; }
-        unsafe {
-            let s: &mut Slice<T> = transmute(self);
-            Some(cast::transmute_mut(&*raw::shift_ptr(s)))
-        }
-    }
-
-    fn mut_pop_ref(&mut self) -> Option<&'a mut T> {
-        if self.len() == 0 { return None; }
-        unsafe {
-            let s: &mut Slice<T> = transmute(self);
-            Some(cast::transmute_mut(&*raw::pop_ptr(s)))
-        }
-    }
-
-    fn swap(self, a: uint, b: uint) {
-        unsafe {
-            // Can't take two mutable loans from one vector, so instead just cast
-            // them to their raw pointers to do the swap
-            let pa: *mut T = &mut self[a];
-            let pb: *mut T = &mut self[b];
-            ptr::swap(pa, pb);
-        }
-    }
-
-    fn reverse(self) {
-        let mut i: uint = 0;
-        let ln = self.len();
-        while i < ln / 2 {
-            self.swap(i, ln - i - 1);
-            i += 1;
-        }
-    }
-
-    #[inline]
-    fn sort_by(self, compare: |&T, &T| -> Ordering) {
-        merge_sort(self, compare)
-    }
-
-    #[inline]
-    fn move_from(self, mut src: ~[T], start: uint, end: uint) -> uint {
-        for (a, b) in self.mut_iter().zip(src.mut_slice(start, end).mut_iter()) {
-            mem::swap(a, b);
-        }
-        cmp::min(self.len(), end-start)
-    }
-
-    #[inline]
-    unsafe fn unsafe_mut_ref(self, index: uint) -> &'a mut T {
-        transmute((self.repr().data as *mut T).offset(index as int))
-    }
-
-    #[inline]
-    fn as_mut_ptr(self) -> *mut T {
-        self.repr().data as *mut T
-    }
-
-    #[inline]
-    unsafe fn unsafe_set(self, index: uint, val: T) {
-        *self.unsafe_mut_ref(index) = val;
-    }
-
-    #[inline]
-    unsafe fn init_elem(self, i: uint, val: T) {
-        mem::move_val_init(&mut (*self.as_mut_ptr().offset(i as int)), val);
-    }
-
-    #[inline]
-    unsafe fn copy_memory(self, src: &[T]) {
-        let len_src = src.len();
-        assert!(self.len() >= len_src);
-        ptr::copy_nonoverlapping_memory(self.as_mut_ptr(), src.as_ptr(), len_src)
-    }
-}
-
-/// Trait for &[T] where T is Cloneable
-pub trait MutableCloneableVector<T> {
-    /// Copies as many elements from `src` as it can into `self` (the
-    /// shorter of `self.len()` and `src.len()`). Returns the number
-    /// of elements copied.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::vec::MutableCloneableVector;
-    ///
-    /// let mut dst = [0, 0, 0];
-    /// let src = [1, 2];
-    ///
-    /// assert!(dst.copy_from(src) == 2);
-    /// assert!(dst == [1, 2, 0]);
-    ///
-    /// let src2 = [3, 4, 5, 6];
-    /// assert!(dst.copy_from(src2) == 3);
-    /// assert!(dst == [3, 4, 5]);
-    /// ```
-    fn copy_from(self, &[T]) -> uint;
-}
-
-impl<'a, T:Clone> MutableCloneableVector<T> for &'a mut [T] {
-    #[inline]
-    fn copy_from(self, src: &[T]) -> uint {
-        for (a, b) in self.mut_iter().zip(src.iter()) {
-            a.clone_from(b);
-        }
-        cmp::min(self.len(), src.len())
-    }
-}
-
-/// Methods for mutable vectors with orderable elements, such as
-/// in-place sorting.
-pub trait MutableTotalOrdVector<T> {
-    /// Sort the vector, in place.
-    ///
-    /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut v = [-5, 4, 1, -3, 2];
-    ///
-    /// v.sort();
-    /// assert!(v == [-5, -3, 1, 2, 4]);
-    /// ```
-    fn sort(self);
-}
-impl<'a, T: TotalOrd> MutableTotalOrdVector<T> for &'a mut [T] {
-    #[inline]
-    fn sort(self) {
-        self.sort_by(|a,b| a.cmp(b))
-    }
-}
-
-/**
-* 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)
+/// Iterates over the `second` vector, copying each element and appending it to
+/// the `first`. Afterwards, the `first` is then returned for use again.
+///
+/// # Example
+///
+/// ```rust
+/// let vec = vec!(1, 2);
+/// let vec = std::vec::append(vec, [3, 4]);
+/// assert_eq!(vec, vec!(1, 2, 3, 4));
+/// ```
+#[inline]
+pub fn append<T:Clone>(mut first: Vec<T>, second: &[T]) -> Vec<T> {
+    first.push_all(second);
+    first
 }
 
-/// Unsafe operations
-pub mod raw {
-    use cast::transmute;
-    use ptr;
-    use ptr::RawPtr;
-    use vec::{with_capacity, MutableVector, OwnedVector};
-    use raw::Slice;
-
-    /**
-     * Form a slice from a pointer and length (as a number of units,
-     * not bytes).
-     */
-    #[inline]
-    pub unsafe fn buf_as_slice<T,U>(p: *T, len: uint, f: |v: &[T]| -> U)
-                               -> U {
-        f(transmute(Slice {
-            data: p,
-            len: len
-        }))
-    }
-
-    /**
-     * Form a slice from a pointer and length (as a number of units,
-     * not bytes).
-     */
-    #[inline]
-    pub unsafe fn mut_buf_as_slice<T,
-                                   U>(
-                                   p: *mut T,
-                                   len: uint,
-                                   f: |v: &mut [T]| -> U)
-                                   -> U {
-        f(transmute(Slice {
-            data: p as *T,
-            len: len
-        }))
-    }
-
-    /**
-    * 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 = with_capacity(elts);
-        dst.set_len(elts);
-        ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
-        dst
-    }
-
-    /**
-     * Returns a pointer to first element in slice and adjusts
-     * slice so it no longer contains that element. Fails if
-     * slice is empty. O(1).
-     */
-    pub unsafe fn shift_ptr<T>(slice: &mut Slice<T>) -> *T {
-        if slice.len == 0 { fail!("shift on empty slice"); }
-        let head: *T = slice.data;
-        slice.data = slice.data.offset(1);
-        slice.len -= 1;
-        head
-    }
-
-    /**
-     * Returns a pointer to last element in slice and adjusts
-     * slice so it no longer contains that element. Fails if
-     * slice is empty. O(1).
-     */
-    pub unsafe fn pop_ptr<T>(slice: &mut Slice<T>) -> *T {
-        if slice.len == 0 { fail!("pop on empty slice"); }
-        let tail: *T = slice.data.offset((slice.len - 1) as int);
-        slice.len -= 1;
-        tail
-    }
+/// Appends one element to the vector provided. The vector itself is then
+/// returned for use again.
+///
+/// # Example
+///
+/// ```rust
+/// let vec = vec!(1, 2);
+/// let vec = std::vec::append_one(vec, 3);
+/// assert_eq!(vec, vec!(1, 2, 3));
+/// ```
+#[inline]
+pub fn append_one<T>(mut lhs: Vec<T>, x: T) -> Vec<T> {
+    lhs.push(x);
+    lhs
 }
 
-/// Operations on `[u8]`.
-pub mod bytes {
-    use container::Container;
-    use vec::{MutableVector, OwnedVector, ImmutableVector};
-    use ptr;
-    use ptr::RawPtr;
-
-    /// A trait for operations on mutable `[u8]`s.
-    pub trait MutableByteVector {
-        /// Sets all bytes of the receiver to the given value.
-        fn set_memory(self, value: u8);
-    }
-
-    impl<'a> MutableByteVector for &'a mut [u8] {
-        #[inline]
-        fn set_memory(self, value: u8) {
-            unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
-        }
-    }
-
-    /// Copies data from `src` to `dst`
-    ///
-    /// `src` and `dst` must not overlap. Fails if the length of `dst`
-    /// is less than the length of `src`.
-    #[inline]
-    pub fn copy_memory(dst: &mut [u8], src: &[u8]) {
-        // Bound checks are done at .copy_memory.
-        unsafe { dst.copy_memory(src) }
-    }
-
-    /**
-     * Allocate space in `dst` and append the data to `src`.
-     */
-    #[inline]
-    pub fn push_bytes(dst: &mut ~[u8], src: &[u8]) {
-        let old_len = dst.len();
-        dst.reserve_additional(src.len());
+#[unsafe_destructor]
+impl<T> Drop for Vec<T> {
+    fn drop(&mut self) {
+        // This is (and should always remain) a no-op if the fields are
+        // zeroed (when moving out, because of #[unsafe_no_drop_flag]).
         unsafe {
-            ptr::copy_memory(dst.as_mut_ptr().offset(old_len as int), src.as_ptr(), src.len());
-            dst.set_len(old_len + src.len());
-        }
-    }
-}
-
-impl<A: Clone> Clone for ~[A] {
-    #[inline]
-    fn clone(&self) -> ~[A] {
-        self.iter().map(|item| item.clone()).collect()
-    }
-
-    fn clone_from(&mut self, source: &~[A]) {
-        if self.len() < source.len() {
-            *self = source.clone()
-        } else {
-            self.truncate(source.len());
-            for (x, y) in self.mut_iter().zip(source.iter()) {
-                x.clone_from(y);
+            for x in self.as_mut_slice().iter() {
+                ptr::read(x);
             }
+            free(self.ptr as *mut c_void)
         }
     }
 }
 
-impl<'a, T: fmt::Show> fmt::Show for &'a [T] {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f.buf, "["));
-        let mut is_first = true;
-        for x in self.iter() {
-            if is_first {
-                is_first = false;
-            } else {
-                try!(write!(f.buf, ", "));
-            }
-            try!(write!(f.buf, "{}", *x))
-        }
-        write!(f.buf, "]")
+impl<T> Default for Vec<T> {
+    fn default() -> Vec<T> {
+        Vec::new()
     }
 }
 
-impl<T: fmt::Show> fmt::Show for ~[T] {
+impl<T:fmt::Show> fmt::Show for Vec<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.as_slice().fmt(f)
     }
 }
 
-// This works because every lifetime is a sub-lifetime of 'static
-impl<'a, A> Default for &'a [A] {
-    fn default() -> &'a [A] { &'a [] }
-}
-
-impl<A> Default for ~[A] {
-    fn default() -> ~[A] { ~[] }
-}
-
-/// Immutable slice iterator
-pub struct Items<'a, T> {
-    priv ptr: *T,
-    priv end: *T,
-    priv marker: marker::ContravariantLifetime<'a>
-}
-
-/// Mutable slice iterator
-pub struct MutItems<'a, T> {
-    priv ptr: *mut T,
-    priv end: *mut T,
-    priv marker: marker::ContravariantLifetime<'a>,
-    priv marker2: marker::NoPod
-}
-
-macro_rules! iterator {
-    (struct $name:ident -> $ptr:ty, $elem:ty) => {
-        impl<'a, T> Iterator<$elem> for $name<'a, T> {
-            #[inline]
-            fn next(&mut self) -> Option<$elem> {
-                // could be implemented with slices, but this avoids bounds checks
-                unsafe {
-                    if self.ptr == self.end {
-                        None
-                    } else {
-                        let old = self.ptr;
-                        self.ptr = if mem::size_of::<T>() == 0 {
-                            // purposefully don't use 'ptr.offset' because for
-                            // vectors with 0-size elements this would return the
-                            // same pointer.
-                            transmute(self.ptr as uint + 1)
-                        } else {
-                            self.ptr.offset(1)
-                        };
-
-                        Some(transmute(old))
-                    }
-                }
-            }
-
-            #[inline]
-            fn size_hint(&self) -> (uint, Option<uint>) {
-                let diff = (self.end as uint) - (self.ptr as uint);
-                let exact = diff / mem::nonzero_size_of::<T>();
-                (exact, Some(exact))
-            }
-        }
-
-        impl<'a, T> DoubleEndedIterator<$elem> for $name<'a, T> {
-            #[inline]
-            fn next_back(&mut self) -> Option<$elem> {
-                // could be implemented with slices, but this avoids bounds checks
-                unsafe {
-                    if self.end == self.ptr {
-                        None
-                    } else {
-                        self.end = if mem::size_of::<T>() == 0 {
-                            // See above for why 'ptr.offset' isn't used
-                            transmute(self.end as uint - 1)
-                        } else {
-                            self.end.offset(-1)
-                        };
-                        Some(transmute(self.end))
-                    }
-                }
-            }
-        }
-    }
-}
-
-impl<'a, T> RandomAccessIterator<&'a T> for Items<'a, T> {
-    #[inline]
-    fn indexable(&self) -> uint {
-        let (exact, _) = self.size_hint();
-        exact
-    }
-
-    #[inline]
-    fn idx(&self, index: uint) -> Option<&'a T> {
-        unsafe {
-            if index < self.indexable() {
-                transmute(self.ptr.offset(index as int))
-            } else {
-                None
-            }
-        }
-    }
-}
-
-iterator!{struct Items -> *T, &'a T}
-pub type RevItems<'a, T> = Rev<Items<'a, T>>;
-
-impl<'a, T> ExactSize<&'a T> for Items<'a, T> {}
-impl<'a, T> ExactSize<&'a mut T> for MutItems<'a, T> {}
-
-impl<'a, T> Clone for Items<'a, T> {
-    fn clone(&self) -> Items<'a, T> { *self }
-}
-
-iterator!{struct MutItems -> *mut T, &'a mut T}
-pub type RevMutItems<'a, T> = Rev<MutItems<'a, T>>;
-
-/// An iterator over the subslices of the vector which are separated
-/// by elements that match `pred`.
-pub struct MutSplits<'a, T> {
-    priv v: &'a mut [T],
-    priv pred: 'a |t: &T| -> bool,
-    priv finished: bool
-}
-
-impl<'a, T> Iterator<&'a mut [T]> for MutSplits<'a, T> {
-    #[inline]
-    fn next(&mut self) -> Option<&'a mut [T]> {
-        if self.finished { return None; }
-
-        match self.v.iter().position(|x| (self.pred)(x)) {
-            None => {
-                self.finished = true;
-                let tmp = mem::replace(&mut self.v, &mut []);
-                let len = tmp.len();
-                let (head, tail) = tmp.mut_split_at(len);
-                self.v = tail;
-                Some(head)
-            }
-            Some(idx) => {
-                let tmp = mem::replace(&mut self.v, &mut []);
-                let (head, tail) = tmp.mut_split_at(idx);
-                self.v = tail.mut_slice_from(1);
-                Some(head)
-            }
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        if self.finished {
-            (0, Some(0))
-        } else {
-            // if the predicate doesn't match anything, we yield one slice
-            // if it matches every element, we yield len+1 empty slices.
-            (1, Some(self.v.len() + 1))
-        }
-    }
-}
-
-impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T> {
-    #[inline]
-    fn next_back(&mut self) -> Option<&'a mut [T]> {
-        if self.finished { return None; }
-
-        match self.v.iter().rposition(|x| (self.pred)(x)) {
-            None => {
-                self.finished = true;
-                let tmp = mem::replace(&mut self.v, &mut []);
-                Some(tmp)
-            }
-            Some(idx) => {
-                let tmp = mem::replace(&mut self.v, &mut []);
-                let (head, tail) = tmp.mut_split_at(idx);
-                self.v = head;
-                Some(tail.mut_slice_from(1))
-            }
-        }
-    }
-}
-
-/// An iterator over a vector in (non-overlapping) mutable chunks (`size`  elements at a time). When
-/// the vector len is not evenly divided by the chunk size, the last slice of the iteration will be
-/// the remainder.
-pub struct MutChunks<'a, T> {
-    priv v: &'a mut [T],
-    priv chunk_size: uint
-}
-
-impl<'a, T> Iterator<&'a mut [T]> for MutChunks<'a, T> {
-    #[inline]
-    fn next(&mut self) -> Option<&'a mut [T]> {
-        if self.v.len() == 0 {
-            None
-        } else {
-            let sz = cmp::min(self.v.len(), self.chunk_size);
-            let tmp = mem::replace(&mut self.v, &mut []);
-            let (head, tail) = tmp.mut_split_at(sz);
-            self.v = tail;
-            Some(head)
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        if self.v.len() == 0 {
-            (0, Some(0))
-        } else {
-            let (n, rem) = div_rem(self.v.len(), self.chunk_size);
-            let n = if rem > 0 { n + 1 } else { n };
-            (n, Some(n))
-        }
-    }
-}
-
-impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutChunks<'a, T> {
-    #[inline]
-    fn next_back(&mut self) -> Option<&'a mut [T]> {
-        if self.v.len() == 0 {
-            None
-        } else {
-            let remainder = self.v.len() % self.chunk_size;
-            let sz = if remainder != 0 { remainder } else { self.chunk_size };
-            let tmp = mem::replace(&mut self.v, &mut []);
-            let tmp_len = tmp.len();
-            let (head, tail) = tmp.mut_split_at(tmp_len - sz);
-            self.v = head;
-            Some(tail)
-        }
-    }
-}
-
 /// An iterator that moves out of a vector.
 pub struct MoveItems<T> {
-    priv allocation: *mut u8, // the block of memory allocated for the vector
+    priv allocation: *mut c_void, // the block of memory allocated for the vector
     priv iter: Items<'static, T>
 }
 
@@ -2918,1735 +1265,99 @@ impl<T> Drop for MoveItems<T> {
         // destroy the remaining elements
         for _x in *self {}
         unsafe {
-            exchange_free(self.allocation as *u8)
-        }
-    }
-}
-
-/// An iterator that moves out of a vector in reverse order.
-pub type RevMoveItems<T> = Rev<MoveItems<T>>;
-
-impl<A> FromIterator<A> for ~[A] {
-    fn from_iterator<T: Iterator<A>>(iterator: &mut T) -> ~[A] {
-        let (lower, _) = iterator.size_hint();
-        let mut xs = with_capacity(lower);
-        for x in *iterator {
-            xs.push(x);
-        }
-        xs
-    }
-}
-
-impl<A> Extendable<A> for ~[A] {
-    fn extend<T: Iterator<A>>(&mut self, iterator: &mut T) {
-        let (lower, _) = iterator.size_hint();
-        let len = self.len();
-        self.reserve_exact(len + lower);
-        for x in *iterator {
-            self.push(x);
+            free(self.allocation)
         }
     }
 }
 
 #[cfg(test)]
 mod tests {
-    use prelude::*;
-    use mem;
-    use vec::*;
-    use cmp::*;
-    use rand::{Rng, task_rng};
-
-    fn square(n: uint) -> uint { n * n }
-
-    fn square_ref(n: &uint) -> uint { square(*n) }
-
-    fn is_odd(n: &uint) -> bool { *n % 2u == 1u }
-
-    #[test]
-    fn test_unsafe_ptrs() {
-        unsafe {
-            // Test on-stack copy-from-buf.
-            let a = ~[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 = ~[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 = from_fn(3u, square);
-        assert_eq!(v.len(), 3u);
-        assert_eq!(v[0], 0u);
-        assert_eq!(v[1], 1u);
-        assert_eq!(v[2], 4u);
-
-        // Test on-heap from_fn.
-        v = from_fn(5u, square);
-        assert_eq!(v.len(), 5u);
-        assert_eq!(v[0], 0u);
-        assert_eq!(v[1], 1u);
-        assert_eq!(v[2], 4u);
-        assert_eq!(v[3], 9u);
-        assert_eq!(v[4], 16u);
-    }
-
-    #[test]
-    fn test_from_elem() {
-        // Test on-stack from_elem.
-        let mut v = from_elem(2u, 10u);
-        assert_eq!(v.len(), 2u);
-        assert_eq!(v[0], 10u);
-        assert_eq!(v[1], 10u);
-
-        // Test on-heap from_elem.
-        v = from_elem(6u, 20u);
-        assert_eq!(v[0], 20u);
-        assert_eq!(v[1], 20u);
-        assert_eq!(v[2], 20u);
-        assert_eq!(v[3], 20u);
-        assert_eq!(v[4], 20u);
-        assert_eq!(v[5], 20u);
-    }
-
-    #[test]
-    fn test_is_empty() {
-        let xs: [int, ..0] = [];
-        assert!(xs.is_empty());
-        assert!(![0].is_empty());
-    }
-
-    #[test]
-    fn test_len_divzero() {
-        type Z = [i8, ..0];
-        let v0 : &[Z] = &[];
-        let v1 : &[Z] = &[[]];
-        let v2 : &[Z] = &[[], []];
-        assert_eq!(mem::size_of::<Z>(), 0);
-        assert_eq!(v0.len(), 0);
-        assert_eq!(v1.len(), 1);
-        assert_eq!(v2.len(), 2);
-    }
-
-    #[test]
-    fn test_get() {
-        let mut a = ~[11];
-        assert_eq!(a.get(1), None);
-        a = ~[11, 12];
-        assert_eq!(a.get(1).unwrap(), &12);
-        a = ~[11, 12, 13];
-        assert_eq!(a.get(1).unwrap(), &12);
-    }
-
-    #[test]
-    fn test_head() {
-        let mut a = ~[];
-        assert_eq!(a.head(), None);
-        a = ~[11];
-        assert_eq!(a.head().unwrap(), &11);
-        a = ~[11, 12];
-        assert_eq!(a.head().unwrap(), &11);
-    }
-
-    #[test]
-    fn test_tail() {
-        let mut a = ~[11];
-        assert_eq!(a.tail(), &[]);
-        a = ~[11, 12];
-        assert_eq!(a.tail(), &[12]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_tail_empty() {
-        let a: ~[int] = ~[];
-        a.tail();
-    }
-
-    #[test]
-    fn test_tailn() {
-        let mut a = ~[11, 12, 13];
-        assert_eq!(a.tailn(0), &[11, 12, 13]);
-        a = ~[11, 12, 13];
-        assert_eq!(a.tailn(2), &[13]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_tailn_empty() {
-        let a: ~[int] = ~[];
-        a.tailn(2);
-    }
-
-    #[test]
-    fn test_init() {
-        let mut a = ~[11];
-        assert_eq!(a.init(), &[]);
-        a = ~[11, 12];
-        assert_eq!(a.init(), &[11]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_init_empty() {
-        let a: ~[int] = ~[];
-        a.init();
-    }
-
-    #[test]
-    fn test_initn() {
-        let mut a = ~[11, 12, 13];
-        assert_eq!(a.initn(0), &[11, 12, 13]);
-        a = ~[11, 12, 13];
-        assert_eq!(a.initn(2), &[11]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_initn_empty() {
-        let a: ~[int] = ~[];
-        a.initn(2);
-    }
-
-    #[test]
-    fn test_last() {
-        let mut a = ~[];
-        assert_eq!(a.last(), None);
-        a = ~[11];
-        assert_eq!(a.last().unwrap(), &11);
-        a = ~[11, 12];
-        assert_eq!(a.last().unwrap(), &12);
-    }
-
-    #[test]
-    fn test_slice() {
-        // Test fixed length vector.
-        let vec_fixed = [1, 2, 3, 4];
-        let v_a = vec_fixed.slice(1u, vec_fixed.len()).to_owned();
-        assert_eq!(v_a.len(), 3u);
-        assert_eq!(v_a[0], 2);
-        assert_eq!(v_a[1], 3);
-        assert_eq!(v_a[2], 4);
-
-        // Test on stack.
-        let vec_stack = &[1, 2, 3];
-        let v_b = vec_stack.slice(1u, 3u).to_owned();
-        assert_eq!(v_b.len(), 2u);
-        assert_eq!(v_b[0], 2);
-        assert_eq!(v_b[1], 3);
-
-        // Test on exchange heap.
-        let vec_unique = ~[1, 2, 3, 4, 5, 6];
-        let v_d = vec_unique.slice(1u, 6u).to_owned();
-        assert_eq!(v_d.len(), 5u);
-        assert_eq!(v_d[0], 2);
-        assert_eq!(v_d[1], 3);
-        assert_eq!(v_d[2], 4);
-        assert_eq!(v_d[3], 5);
-        assert_eq!(v_d[4], 6);
-    }
-
-    #[test]
-    fn test_slice_from() {
-        let vec = &[1, 2, 3, 4];
-        assert_eq!(vec.slice_from(0), vec);
-        assert_eq!(vec.slice_from(2), &[3, 4]);
-        assert_eq!(vec.slice_from(4), &[]);
-    }
-
-    #[test]
-    fn test_slice_to() {
-        let vec = &[1, 2, 3, 4];
-        assert_eq!(vec.slice_to(4), vec);
-        assert_eq!(vec.slice_to(2), &[1, 2]);
-        assert_eq!(vec.slice_to(0), &[]);
-    }
-
-
-    #[test]
-    fn test_pop() {
-        let mut v = ~[5];
-        let e = v.pop();
-        assert_eq!(v.len(), 0);
-        assert_eq!(e, Some(5));
-        let f = v.pop();
-        assert_eq!(f, None);
-        let g = v.pop();
-        assert_eq!(g, None);
-    }
-
-    #[test]
-    fn test_swap_remove() {
-        let mut v = ~[1, 2, 3, 4, 5];
-        let mut e = v.swap_remove(0);
-        assert_eq!(e, Some(1));
-        assert_eq!(v, ~[5, 2, 3, 4]);
-        e = v.swap_remove(3);
-        assert_eq!(e, Some(4));
-        assert_eq!(v, ~[5, 2, 3]);
-
-        e = v.swap_remove(3);
-        assert_eq!(e, None);
-        assert_eq!(v, ~[5, 2, 3]);
-    }
-
-    #[test]
-    fn test_swap_remove_noncopyable() {
-        // Tests that we don't accidentally run destructors twice.
-        let mut v = ~[::unstable::sync::Exclusive::new(()),
-                      ::unstable::sync::Exclusive::new(()),
-                      ::unstable::sync::Exclusive::new(())];
-        let mut _e = v.swap_remove(0);
-        assert_eq!(v.len(), 2);
-        _e = v.swap_remove(1);
-        assert_eq!(v.len(), 1);
-        _e = v.swap_remove(0);
-        assert_eq!(v.len(), 0);
-    }
-
-    #[test]
-    fn test_push() {
-        // Test on-stack push().
-        let mut v = ~[];
-        v.push(1);
-        assert_eq!(v.len(), 1u);
-        assert_eq!(v[0], 1);
-
-        // Test on-heap push().
-        v.push(2);
-        assert_eq!(v.len(), 2u);
-        assert_eq!(v[0], 1);
-        assert_eq!(v[1], 2);
-    }
-
-    #[test]
-    fn test_grow() {
-        // Test on-stack grow().
-        let mut v = ~[];
-        v.grow(2u, &1);
-        assert_eq!(v.len(), 2u);
-        assert_eq!(v[0], 1);
-        assert_eq!(v[1], 1);
-
-        // Test on-heap grow().
-        v.grow(3u, &2);
-        assert_eq!(v.len(), 5u);
-        assert_eq!(v[0], 1);
-        assert_eq!(v[1], 1);
-        assert_eq!(v[2], 2);
-        assert_eq!(v[3], 2);
-        assert_eq!(v[4], 2);
-    }
-
-    #[test]
-    fn test_grow_fn() {
-        let mut v = ~[];
-        v.grow_fn(3u, square);
-        assert_eq!(v.len(), 3u);
-        assert_eq!(v[0], 0u);
-        assert_eq!(v[1], 1u);
-        assert_eq!(v[2], 4u);
-    }
-
-    #[test]
-    fn test_grow_set() {
-        let mut v = ~[1, 2, 3];
-        v.grow_set(4u, &4, 5);
-        assert_eq!(v.len(), 5u);
-        assert_eq!(v[0], 1);
-        assert_eq!(v[1], 2);
-        assert_eq!(v[2], 3);
-        assert_eq!(v[3], 4);
-        assert_eq!(v[4], 5);
-    }
-
-    #[test]
-    fn test_truncate() {
-        let mut v = ~[~6,~5,~4];
-        v.truncate(1);
-        assert_eq!(v.len(), 1);
-        assert_eq!(*(v[0]), 6);
-        // If the unsafe block didn't drop things properly, we blow up here.
-    }
-
-    #[test]
-    fn test_clear() {
-        let mut v = ~[~6,~5,~4];
-        v.clear();
-        assert_eq!(v.len(), 0);
-        // If the unsafe block didn't drop things properly, we blow up here.
-    }
-
-    #[test]
-    fn test_dedup() {
-        fn case(a: ~[uint], b: ~[uint]) {
-            let mut v = a;
-            v.dedup();
-            assert_eq!(v, b);
-        }
-        case(~[], ~[]);
-        case(~[1], ~[1]);
-        case(~[1,1], ~[1]);
-        case(~[1,2,3], ~[1,2,3]);
-        case(~[1,1,2,3], ~[1,2,3]);
-        case(~[1,2,2,3], ~[1,2,3]);
-        case(~[1,2,3,3], ~[1,2,3]);
-        case(~[1,1,2,2,2,3,3], ~[1,2,3]);
-    }
-
-    #[test]
-    fn test_dedup_unique() {
-        let mut v0 = ~[~1, ~1, ~2, ~3];
-        v0.dedup();
-        let mut v1 = ~[~1, ~2, ~2, ~3];
-        v1.dedup();
-        let mut v2 = ~[~1, ~2, ~3, ~3];
-        v2.dedup();
-        /*
-         * If the ~pointers were leaked or otherwise misused, valgrind and/or
-         * rustrt should raise errors.
-         */
-    }
-
-    #[test]
-    fn test_dedup_shared() {
-        let mut v0 = ~[~1, ~1, ~2, ~3];
-        v0.dedup();
-        let mut v1 = ~[~1, ~2, ~2, ~3];
-        v1.dedup();
-        let mut v2 = ~[~1, ~2, ~3, ~3];
-        v2.dedup();
-        /*
-         * If the pointers were leaked or otherwise misused, valgrind and/or
-         * rustrt should raise errors.
-         */
-    }
-
-    #[test]
-    fn test_map() {
-        // Test on-stack map.
-        let v = &[1u, 2u, 3u];
-        let mut w = v.map(square_ref);
-        assert_eq!(w.len(), 3u);
-        assert_eq!(w[0], 1u);
-        assert_eq!(w[1], 4u);
-        assert_eq!(w[2], 9u);
-
-        // Test on-heap map.
-        let v = ~[1u, 2u, 3u, 4u, 5u];
-        w = v.map(square_ref);
-        assert_eq!(w.len(), 5u);
-        assert_eq!(w[0], 1u);
-        assert_eq!(w[1], 4u);
-        assert_eq!(w[2], 9u);
-        assert_eq!(w[3], 16u);
-        assert_eq!(w[4], 25u);
-    }
-
-    #[test]
-    fn test_retain() {
-        let mut v = ~[1, 2, 3, 4, 5];
-        v.retain(is_odd);
-        assert_eq!(v, ~[1, 3, 5]);
-    }
-
-    #[test]
-    fn test_zip_unzip() {
-        let z1 = ~[(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() {
-            v.swap(a, b);
-            match i {
-                0 => assert!(v == [1, 3, 2]),
-                1 => assert!(v == [3, 1, 2]),
-                2 => assert!(v == [3, 2, 1]),
-                3 => assert!(v == [2, 3, 1]),
-                4 => assert!(v == [2, 1, 3]),
-                5 => assert!(v == [1, 2, 3]),
-                _ => fail!(),
-            }
-        }
-    }
-
-    #[test]
-    fn test_permutations() {
-        {
-            let v: [int, ..0] = [];
-            let mut it = v.permutations();
-            assert_eq!(it.next(), None);
-        }
-        {
-            let v = [~"Hello"];
-            let mut it = v.permutations();
-            assert_eq!(it.next(), None);
-        }
-        {
-            let v = [1, 2, 3];
-            let mut it = v.permutations();
-            assert_eq!(it.next(), Some(~[1,2,3]));
-            assert_eq!(it.next(), Some(~[1,3,2]));
-            assert_eq!(it.next(), Some(~[3,1,2]));
-            assert_eq!(it.next(), Some(~[3,2,1]));
-            assert_eq!(it.next(), Some(~[2,3,1]));
-            assert_eq!(it.next(), Some(~[2,1,3]));
-            assert_eq!(it.next(), None);
-        }
-        {
-            // check that we have N! permutations
-            let v = ['A', 'B', 'C', 'D', 'E', 'F'];
-            let mut amt = 0;
-            for _perm in v.permutations() {
-                amt += 1;
-            }
-            assert_eq!(amt, 2 * 3 * 4 * 5 * 6);
-        }
-    }
-
-    #[test]
-    fn test_position_elem() {
-        assert!([].position_elem(&1).is_none());
-
-        let v1 = ~[1, 2, 3, 3, 2, 5];
-        assert_eq!(v1.position_elem(&1), Some(0u));
-        assert_eq!(v1.position_elem(&2), Some(1u));
-        assert_eq!(v1.position_elem(&5), Some(5u));
-        assert!(v1.position_elem(&4).is_none());
-    }
-
-    #[test]
-    fn test_bsearch_elem() {
-        assert_eq!([1,2,3,4,5].bsearch_elem(&5), Some(4));
-        assert_eq!([1,2,3,4,5].bsearch_elem(&4), Some(3));
-        assert_eq!([1,2,3,4,5].bsearch_elem(&3), Some(2));
-        assert_eq!([1,2,3,4,5].bsearch_elem(&2), Some(1));
-        assert_eq!([1,2,3,4,5].bsearch_elem(&1), Some(0));
-
-        assert_eq!([2,4,6,8,10].bsearch_elem(&1), None);
-        assert_eq!([2,4,6,8,10].bsearch_elem(&5), None);
-        assert_eq!([2,4,6,8,10].bsearch_elem(&4), Some(1));
-        assert_eq!([2,4,6,8,10].bsearch_elem(&10), Some(4));
-
-        assert_eq!([2,4,6,8].bsearch_elem(&1), None);
-        assert_eq!([2,4,6,8].bsearch_elem(&5), None);
-        assert_eq!([2,4,6,8].bsearch_elem(&4), Some(1));
-        assert_eq!([2,4,6,8].bsearch_elem(&8), Some(3));
-
-        assert_eq!([2,4,6].bsearch_elem(&1), None);
-        assert_eq!([2,4,6].bsearch_elem(&5), None);
-        assert_eq!([2,4,6].bsearch_elem(&4), Some(1));
-        assert_eq!([2,4,6].bsearch_elem(&6), Some(2));
-
-        assert_eq!([2,4].bsearch_elem(&1), None);
-        assert_eq!([2,4].bsearch_elem(&5), None);
-        assert_eq!([2,4].bsearch_elem(&2), Some(0));
-        assert_eq!([2,4].bsearch_elem(&4), Some(1));
-
-        assert_eq!([2].bsearch_elem(&1), None);
-        assert_eq!([2].bsearch_elem(&5), None);
-        assert_eq!([2].bsearch_elem(&2), Some(0));
-
-        assert_eq!([].bsearch_elem(&1), None);
-        assert_eq!([].bsearch_elem(&5), None);
-
-        assert!([1,1,1,1,1].bsearch_elem(&1) != None);
-        assert!([1,1,1,1,2].bsearch_elem(&1) != None);
-        assert!([1,1,1,2,2].bsearch_elem(&1) != None);
-        assert!([1,1,2,2,2].bsearch_elem(&1) != None);
-        assert_eq!([1,2,2,2,2].bsearch_elem(&1), Some(0));
-
-        assert_eq!([1,2,3,4,5].bsearch_elem(&6), None);
-        assert_eq!([1,2,3,4,5].bsearch_elem(&0), None);
-    }
-
-    #[test]
-    fn test_reverse() {
-        let mut v: ~[int] = ~[10, 20];
-        assert_eq!(v[0], 10);
-        assert_eq!(v[1], 20);
-        v.reverse();
-        assert_eq!(v[0], 20);
-        assert_eq!(v[1], 10);
-
-        let mut v3: ~[int] = ~[];
-        v3.reverse();
-        assert!(v3.is_empty());
-    }
-
-    #[test]
-    fn test_sort() {
-        for len in range(4u, 25) {
-            for _ in range(0, 100) {
-                let mut v = task_rng().gen_vec::<uint>(len);
-                let mut v1 = v.clone();
-
-                v.sort();
-                assert!(v.windows(2).all(|w| w[0] <= w[1]));
-
-                v1.sort_by(|a, b| a.cmp(b));
-                assert!(v1.windows(2).all(|w| w[0] <= w[1]));
-
-                v1.sort_by(|a, b| b.cmp(a));
-                assert!(v1.windows(2).all(|w| w[0] >= w[1]));
-            }
-        }
-
-        // shouldn't fail/crash
-        let mut v: [uint, .. 0] = [];
-        v.sort();
-
-        let mut v = [0xDEADBEEFu];
-        v.sort();
-        assert!(v == [0xDEADBEEF]);
-    }
-
-    #[test]
-    fn test_sort_stability() {
-        for len in range(4, 25) {
-            for _ in range(0 , 10) {
-                let mut counts = [0, .. 10];
-
-                // create a vector like [(6, 1), (5, 1), (6, 2), ...],
-                // where the first item of each tuple is random, but
-                // the second item represents which occurrence of that
-                // number this element is, i.e. the second elements
-                // will occur in sorted order.
-                let mut v = range(0, len).map(|_| {
-                        let n = task_rng().gen::<uint>() % 10;
-                        counts[n] += 1;
-                        (n, counts[n])
-                    }).to_owned_vec();
-
-                // only sort on the first element, so an unstable sort
-                // may mix up the counts.
-                v.sort_by(|&(a,_), &(b,_)| a.cmp(&b));
-
-                // this comparison includes the count (the second item
-                // of the tuple), so elements with equal first items
-                // 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]));
-            }
-        }
-    }
-
-    #[test]
-    fn test_partition() {
-        assert_eq!((~[]).partition(|x: &int| *x < 3), (~[], ~[]));
-        assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 4), (~[1, 2, 3], ~[]));
-        assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 2), (~[1], ~[2, 3]));
-        assert_eq!((~[1, 2, 3]).partition(|x: &int| *x < 0), (~[], ~[1, 2, 3]));
-    }
-
-    #[test]
-    fn test_partitioned() {
-        assert_eq!(([]).partitioned(|x: &int| *x < 3), (~[], ~[]))
-        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 4), (~[1, 2, 3], ~[]));
-        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 2), (~[1], ~[2, 3]));
-        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 0), (~[], ~[1, 2, 3]));
-    }
-
-    #[test]
-    fn test_concat() {
-        let v: [~[int], ..0] = [];
-        assert_eq!(v.concat_vec(), ~[]);
-        assert_eq!([~[1], ~[2,3]].concat_vec(), ~[1, 2, 3]);
-
-        assert_eq!([&[1], &[2,3]].concat_vec(), ~[1, 2, 3]);
-    }
-
-    #[test]
-    fn test_connect() {
-        let v: [~[int], ..0] = [];
-        assert_eq!(v.connect_vec(&0), ~[]);
-        assert_eq!([~[1], ~[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
-        assert_eq!([~[1], ~[2], ~[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
-
-        assert_eq!(v.connect_vec(&0), ~[]);
-        assert_eq!([&[1], &[2, 3]].connect_vec(&0), ~[1, 0, 2, 3]);
-        assert_eq!([&[1], &[2], &[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
-    }
-
-    #[test]
-    fn test_shift() {
-        let mut x = ~[1, 2, 3];
-        assert_eq!(x.shift(), Some(1));
-        assert_eq!(&x, &~[2, 3]);
-        assert_eq!(x.shift(), Some(2));
-        assert_eq!(x.shift(), Some(3));
-        assert_eq!(x.shift(), None);
-        assert_eq!(x.len(), 0);
-    }
-
-    #[test]
-    fn test_unshift() {
-        let mut x = ~[1, 2, 3];
-        x.unshift(0);
-        assert_eq!(x, ~[0, 1, 2, 3]);
-    }
-
-    #[test]
-    fn test_insert() {
-        let mut a = ~[1, 2, 4];
-        a.insert(2, 3);
-        assert_eq!(a, ~[1, 2, 3, 4]);
-
-        let mut a = ~[1, 2, 3];
-        a.insert(0, 0);
-        assert_eq!(a, ~[0, 1, 2, 3]);
-
-        let mut a = ~[1, 2, 3];
-        a.insert(3, 4);
-        assert_eq!(a, ~[1, 2, 3, 4]);
-
-        let mut a = ~[];
-        a.insert(0, 1);
-        assert_eq!(a, ~[1]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_insert_oob() {
-        let mut a = ~[1, 2, 3];
-        a.insert(4, 5);
-    }
-
-    #[test]
-    fn test_remove() {
-        let mut a = ~[1,2,3,4];
-
-        assert_eq!(a.remove(2), Some(3));
-        assert_eq!(a, ~[1,2,4]);
-
-        assert_eq!(a.remove(2), Some(4));
-        assert_eq!(a, ~[1,2]);
-
-        assert_eq!(a.remove(2), None);
-        assert_eq!(a, ~[1,2]);
-
-        assert_eq!(a.remove(0), Some(1));
-        assert_eq!(a, ~[2]);
-
-        assert_eq!(a.remove(0), Some(2));
-        assert_eq!(a, ~[]);
-
-        assert_eq!(a.remove(0), None);
-        assert_eq!(a.remove(10), None);
-    }
-
-    #[test]
-    fn test_capacity() {
-        let mut v = ~[0u64];
-        v.reserve_exact(10u);
-        assert_eq!(v.capacity(), 10u);
-        let mut v = ~[0u32];
-        v.reserve_exact(10u);
-        assert_eq!(v.capacity(), 10u);
-    }
-
-    #[test]
-    fn test_slice_2() {
-        let v = ~[1, 2, 3, 4, 5];
-        let v = v.slice(1u, 3u);
-        assert_eq!(v.len(), 2u);
-        assert_eq!(v[0], 2);
-        assert_eq!(v[1], 3);
-    }
-
+    use super::Vec;
+    use iter::{Iterator, range, Extendable};
+    use mem::{drop, size_of};
+    use ops::Drop;
+    use option::{Some, None};
+    use ptr;
 
     #[test]
-    #[should_fail]
-    fn test_from_fn_fail() {
-        from_fn(100, |v| {
-            if v == 50 { fail!() }
-            ~0
-        });
+    fn test_small_vec_struct() {
+        assert!(size_of::<Vec<u8>>() == size_of::<uint>() * 3);
     }
 
     #[test]
-    #[should_fail]
-    fn test_from_elem_fail() {
-        use cast;
-        use rc::Rc;
-
-        struct S {
-            f: int,
-            boxes: (~int, Rc<int>)
+    fn test_double_drop() {
+        struct TwoVec<T> {
+            x: Vec<T>,
+            y: Vec<T>
         }
 
-        impl Clone for S {
-            fn clone(&self) -> S {
-                let s = unsafe { cast::transmute_mut(self) };
-                s.f += 1;
-                if s.f == 10 { fail!() }
-                S { f: s.f, boxes: s.boxes.clone() }
-            }
+        struct DropCounter<'a> {
+            count: &'a mut int
         }
 
-        let s = S { f: 0, boxes: (~0, Rc::new(0)) };
-        let _ = from_elem(100, s);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_build_fail() {
-        use rc::Rc;
-        build(None, |push| {
-            push((~0, Rc::new(0)));
-            push((~0, Rc::new(0)));
-            push((~0, Rc::new(0)));
-            push((~0, Rc::new(0)));
-            fail!();
-        });
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_grow_fn_fail() {
-        use rc::Rc;
-        let mut v = ~[];
-        v.grow_fn(100, |i| {
-            if i == 50 {
-                fail!()
+        #[unsafe_destructor]
+        impl<'a> Drop for DropCounter<'a> {
+            fn drop(&mut self) {
+                *self.count += 1;
             }
-            (~0, Rc::new(0))
-        })
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_map_fail() {
-        use rc::Rc;
-        let v = [(~0, Rc::new(0)), (~0, Rc::new(0)), (~0, Rc::new(0)), (~0, Rc::new(0))];
-        let mut i = 0;
-        v.map(|_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 1;
-            ~[(~0, Rc::new(0))]
-        });
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_flat_map_fail() {
-        use rc::Rc;
-        let v = [(~0, Rc::new(0)), (~0, Rc::new(0)), (~0, Rc::new(0)), (~0, Rc::new(0))];
-        let mut i = 0;
-        flat_map(v, |_elt| {
-            if i == 2 {
-                fail!()
-            }
-            i += 1;
-            ~[(~0, Rc::new(0))]
-        });
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_permute_fail() {
-        use rc::Rc;
-        let v = [(~0, Rc::new(0)), (~0, Rc::new(0)), (~0, Rc::new(0)), (~0, Rc::new(0))];
-        let mut i = 0;
-        for _ in v.permutations() {
-            if i == 2 {
-                fail!()
-            }
-            i += 1;
-        }
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_copy_memory_oob() {
-        unsafe {
-            let mut a = [1, 2, 3, 4];
-            let b = [1, 2, 3, 4, 5];
-            a.copy_memory(b);
-        }
-    }
-
-    #[test]
-    fn test_total_ord() {
-        [1, 2, 3, 4].cmp(& &[1, 2, 3]) == Greater;
-        [1, 2, 3].cmp(& &[1, 2, 3, 4]) == Less;
-        [1, 2, 3, 4].cmp(& &[1, 2, 3, 4]) == Equal;
-        [1, 2, 3, 4, 5, 5, 5, 5].cmp(& &[1, 2, 3, 4, 5, 6]) == Less;
-        [2, 2].cmp(& &[1, 2, 3, 4]) == Greater;
-    }
-
-    #[test]
-    fn test_iterator() {
-        use iter::*;
-        let xs = [1, 2, 5, 10, 11];
-        let mut it = xs.iter();
-        assert_eq!(it.size_hint(), (5, Some(5)));
-        assert_eq!(it.next().unwrap(), &1);
-        assert_eq!(it.size_hint(), (4, Some(4)));
-        assert_eq!(it.next().unwrap(), &2);
-        assert_eq!(it.size_hint(), (3, Some(3)));
-        assert_eq!(it.next().unwrap(), &5);
-        assert_eq!(it.size_hint(), (2, Some(2)));
-        assert_eq!(it.next().unwrap(), &10);
-        assert_eq!(it.size_hint(), (1, Some(1)));
-        assert_eq!(it.next().unwrap(), &11);
-        assert_eq!(it.size_hint(), (0, Some(0)));
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_random_access_iterator() {
-        use iter::*;
-        let xs = [1, 2, 5, 10, 11];
-        let mut it = xs.iter();
-
-        assert_eq!(it.indexable(), 5);
-        assert_eq!(it.idx(0).unwrap(), &1);
-        assert_eq!(it.idx(2).unwrap(), &5);
-        assert_eq!(it.idx(4).unwrap(), &11);
-        assert!(it.idx(5).is_none());
-
-        assert_eq!(it.next().unwrap(), &1);
-        assert_eq!(it.indexable(), 4);
-        assert_eq!(it.idx(0).unwrap(), &2);
-        assert_eq!(it.idx(3).unwrap(), &11);
-        assert!(it.idx(4).is_none());
-
-        assert_eq!(it.next().unwrap(), &2);
-        assert_eq!(it.indexable(), 3);
-        assert_eq!(it.idx(1).unwrap(), &10);
-        assert!(it.idx(3).is_none());
-
-        assert_eq!(it.next().unwrap(), &5);
-        assert_eq!(it.indexable(), 2);
-        assert_eq!(it.idx(1).unwrap(), &11);
-
-        assert_eq!(it.next().unwrap(), &10);
-        assert_eq!(it.indexable(), 1);
-        assert_eq!(it.idx(0).unwrap(), &11);
-        assert!(it.idx(1).is_none());
-
-        assert_eq!(it.next().unwrap(), &11);
-        assert_eq!(it.indexable(), 0);
-        assert!(it.idx(0).is_none());
-
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_iter_size_hints() {
-        use iter::*;
-        let mut xs = [1, 2, 5, 10, 11];
-        assert_eq!(xs.iter().size_hint(), (5, Some(5)));
-        assert_eq!(xs.rev_iter().size_hint(), (5, Some(5)));
-        assert_eq!(xs.mut_iter().size_hint(), (5, Some(5)));
-        assert_eq!(xs.mut_rev_iter().size_hint(), (5, Some(5)));
-    }
-
-    #[test]
-    fn test_iter_clone() {
-        let xs = [1, 2, 5];
-        let mut it = xs.iter();
-        it.next();
-        let mut jt = it.clone();
-        assert_eq!(it.next(), jt.next());
-        assert_eq!(it.next(), jt.next());
-        assert_eq!(it.next(), jt.next());
-    }
-
-    #[test]
-    fn test_mut_iterator() {
-        use iter::*;
-        let mut xs = [1, 2, 3, 4, 5];
-        for x in xs.mut_iter() {
-            *x += 1;
-        }
-        assert!(xs == [2, 3, 4, 5, 6])
-    }
-
-    #[test]
-    fn test_rev_iterator() {
-        use iter::*;
-
-        let xs = [1, 2, 5, 10, 11];
-        let ys = [11, 10, 5, 2, 1];
-        let mut i = 0;
-        for &x in xs.rev_iter() {
-            assert_eq!(x, ys[i]);
-            i += 1;
         }
-        assert_eq!(i, 5);
-    }
-
-    #[test]
-    fn test_mut_rev_iterator() {
-        use iter::*;
-        let mut xs = [1u, 2, 3, 4, 5];
-        for (i,x) in xs.mut_rev_iter().enumerate() {
-            *x += i;
-        }
-        assert!(xs == [5, 5, 5, 5, 5])
-    }
-
-    #[test]
-    fn test_move_iterator() {
-        use iter::*;
-        let xs = ~[1u,2,3,4,5];
-        assert_eq!(xs.move_iter().fold(0, |a: uint, b: uint| 10*a + b), 12345);
-    }
-
-    #[test]
-    fn test_move_rev_iterator() {
-        use iter::*;
-        let xs = ~[1u,2,3,4,5];
-        assert_eq!(xs.move_rev_iter().fold(0, |a: uint, b: uint| 10*a + b), 54321);
-    }
-
-    #[test]
-    fn test_splitator() {
-        let xs = &[1i,2,3,4,5];
-
-        assert_eq!(xs.split(|x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   ~[&[1], &[3], &[5]]);
-        assert_eq!(xs.split(|x| *x == 1).collect::<~[&[int]]>(),
-                   ~[&[], &[2,3,4,5]]);
-        assert_eq!(xs.split(|x| *x == 5).collect::<~[&[int]]>(),
-                   ~[&[1,2,3,4], &[]]);
-        assert_eq!(xs.split(|x| *x == 10).collect::<~[&[int]]>(),
-                   ~[&[1,2,3,4,5]]);
-        assert_eq!(xs.split(|_| true).collect::<~[&[int]]>(),
-                   ~[&[], &[], &[], &[], &[], &[]]);
-
-        let xs: &[int] = &[];
-        assert_eq!(xs.split(|x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
-    }
-
-    #[test]
-    fn test_splitnator() {
-        let xs = &[1i,2,3,4,5];
-
-        assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   ~[&[1,2,3,4,5]]);
-        assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   ~[&[1], &[3,4,5]]);
-        assert_eq!(xs.splitn(3, |_| true).collect::<~[&[int]]>(),
-                   ~[&[], &[], &[], &[4,5]]);
-
-        let xs: &[int] = &[];
-        assert_eq!(xs.splitn(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
-    }
-
-    #[test]
-    fn test_rsplitator() {
-        let xs = &[1i,2,3,4,5];
-
-        assert_eq!(xs.rsplit(|x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   ~[&[5], &[3], &[1]]);
-        assert_eq!(xs.rsplit(|x| *x == 1).collect::<~[&[int]]>(),
-                   ~[&[2,3,4,5], &[]]);
-        assert_eq!(xs.rsplit(|x| *x == 5).collect::<~[&[int]]>(),
-                   ~[&[], &[1,2,3,4]]);
-        assert_eq!(xs.rsplit(|x| *x == 10).collect::<~[&[int]]>(),
-                   ~[&[1,2,3,4,5]]);
-
-        let xs: &[int] = &[];
-        assert_eq!(xs.rsplit(|x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
-    }
-
-    #[test]
-    fn test_rsplitnator() {
-        let xs = &[1,2,3,4,5];
-
-        assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   ~[&[1,2,3,4,5]]);
-        assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<~[&[int]]>(),
-                   ~[&[5], &[1,2,3]]);
-        assert_eq!(xs.rsplitn(3, |_| true).collect::<~[&[int]]>(),
-                   ~[&[], &[], &[], &[1,2]]);
-
-        let xs: &[int] = &[];
-        assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
-    }
-
-    #[test]
-    fn test_windowsator() {
-        let v = &[1i,2,3,4];
-
-        assert_eq!(v.windows(2).collect::<~[&[int]]>(), ~[&[1,2], &[2,3], &[3,4]]);
-        assert_eq!(v.windows(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[2,3,4]]);
-        assert!(v.windows(6).next().is_none());
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_windowsator_0() {
-        let v = &[1i,2,3,4];
-        let _it = v.windows(0);
-    }
-
-    #[test]
-    fn test_chunksator() {
-        let v = &[1i,2,3,4,5];
-
-        assert_eq!(v.chunks(2).collect::<~[&[int]]>(), ~[&[1i,2], &[3,4], &[5]]);
-        assert_eq!(v.chunks(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[4,5]]);
-        assert_eq!(v.chunks(6).collect::<~[&[int]]>(), ~[&[1i,2,3,4,5]]);
-
-        assert_eq!(v.chunks(2).rev().collect::<~[&[int]]>(), ~[&[5i], &[3,4], &[1,2]]);
-        let it = v.chunks(2);
-        assert_eq!(it.indexable(), 3);
-        assert_eq!(it.idx(0).unwrap(), &[1,2]);
-        assert_eq!(it.idx(1).unwrap(), &[3,4]);
-        assert_eq!(it.idx(2).unwrap(), &[5]);
-        assert_eq!(it.idx(3), None);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_chunksator_0() {
-        let v = &[1i,2,3,4];
-        let _it = v.chunks(0);
-    }
-
-    #[test]
-    fn test_move_from() {
-        let mut a = [1,2,3,4,5];
-        let b = ~[6,7,8];
-        assert_eq!(a.move_from(b, 0, 3), 3);
-        assert!(a == [6,7,8,4,5]);
-        let mut a = [7,2,8,1];
-        let b = ~[3,1,4,1,5,9];
-        assert_eq!(a.move_from(b, 0, 6), 4);
-        assert!(a == [3,1,4,1]);
-        let mut a = [1,2,3,4];
-        let b = ~[5,6,7,8,9,0];
-        assert_eq!(a.move_from(b, 2, 3), 1);
-        assert!(a == [7,2,3,4]);
-        let mut a = [1,2,3,4,5];
-        let b = ~[5,6,7,8,9,0];
-        assert_eq!(a.mut_slice(2,4).move_from(b,1,6), 2);
-        assert!(a == [1,2,6,7,5]);
-    }
 
-    #[test]
-    fn test_copy_from() {
-        let mut a = [1,2,3,4,5];
-        let b = [6,7,8];
-        assert_eq!(a.copy_from(b), 3);
-        assert!(a == [6,7,8,4,5]);
-        let mut c = [7,2,8,1];
-        let d = [3,1,4,1,5,9];
-        assert_eq!(c.copy_from(d), 4);
-        assert!(c == [3,1,4,1]);
-    }
-
-    #[test]
-    fn test_reverse_part() {
-        let mut values = [1,2,3,4,5];
-        values.mut_slice(1, 4).reverse();
-        assert!(values == [1,4,3,2,5]);
-    }
-
-    #[test]
-    fn test_show() {
-        macro_rules! test_show_vec(
-            ($x:expr, $x_str:expr) => ({
-                let (x, x_str) = ($x, $x_str);
-                assert_eq!(format!("{}", x), x_str);
-                assert_eq!(format!("{}", x.as_slice()), x_str);
-            })
-        )
-        let empty: ~[int] = ~[];
-        test_show_vec!(empty, ~"[]");
-        test_show_vec!(~[1], ~"[1]");
-        test_show_vec!(~[1, 2, 3], ~"[1, 2, 3]");
-        test_show_vec!(~[~[], ~[1u], ~[1u, 1u]], ~"[[], [1], [1, 1]]");
-    }
-
-    #[test]
-    fn test_vec_default() {
-        use default::Default;
-        macro_rules! t (
-            ($ty:ty) => {{
-                let v: $ty = Default::default();
-                assert!(v.is_empty());
-            }}
-        );
-
-        t!(&[int]);
-        t!(~[int]);
-    }
-
-    #[test]
-    fn test_bytes_set_memory() {
-        use vec::bytes::MutableByteVector;
-        let mut values = [1u8,2,3,4,5];
-        values.mut_slice(0,5).set_memory(0xAB);
-        assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
-        values.mut_slice(2,4).set_memory(0xFF);
-        assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_overflow_does_not_cause_segfault() {
-        let mut v = ~[];
-        v.reserve_exact(-1);
-        v.push(1);
-        v.push(2);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_overflow_does_not_cause_segfault_managed() {
-        use rc::Rc;
-        let mut v = ~[Rc::new(1)];
-        v.reserve_exact(-1);
-        v.push(Rc::new(2));
-    }
-
-    #[test]
-    fn test_mut_split_at() {
-        let mut values = [1u8,2,3,4,5];
+        let mut count_x @ mut count_y = 0;
         {
-            let (left, right) = values.mut_split_at(2);
-            assert!(left.slice(0, left.len()) == [1, 2]);
-            for p in left.mut_iter() {
-                *p += 1;
-            }
-
-            assert!(right.slice(0, right.len()) == [3, 4, 5]);
-            for p in right.mut_iter() {
-                *p += 2;
-            }
-        }
-
-        assert!(values == [2, 3, 5, 6, 7]);
-    }
-
-    #[deriving(Clone, Eq)]
-    struct Foo;
-
-    #[test]
-    fn test_iter_zero_sized() {
-        let mut v = ~[Foo, Foo, Foo];
-        assert_eq!(v.len(), 3);
-        let mut cnt = 0;
-
-        for f in v.iter() {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 3);
-
-        for f in v.slice(1, 3).iter() {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 5);
-
-        for f in v.mut_iter() {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 8);
-
-        for f in v.move_iter() {
-            assert!(f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 11);
-
-        let xs = ~[Foo, Foo, Foo];
-        assert_eq!(format!("{:?}", xs.slice(0, 2).to_owned()),
-                   ~"~[vec::tests::Foo, vec::tests::Foo]");
-
-        let xs: [Foo, ..3] = [Foo, Foo, Foo];
-        assert_eq!(format!("{:?}", xs.slice(0, 2).to_owned()),
-                   ~"~[vec::tests::Foo, vec::tests::Foo]");
-        cnt = 0;
-        for f in xs.iter() {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert!(cnt == 3);
-    }
-
-    #[test]
-    fn test_shrink_to_fit() {
-        let mut xs = ~[0, 1, 2, 3];
-        for i in range(4, 100) {
-            xs.push(i)
-        }
-        assert_eq!(xs.capacity(), 128);
-        xs.shrink_to_fit();
-        assert_eq!(xs.capacity(), 100);
-        assert_eq!(xs, range(0, 100).to_owned_vec());
-    }
-
-    #[test]
-    fn test_starts_with() {
-        assert!(bytes!("foobar").starts_with(bytes!("foo")));
-        assert!(!bytes!("foobar").starts_with(bytes!("oob")));
-        assert!(!bytes!("foobar").starts_with(bytes!("bar")));
-        assert!(!bytes!("foo").starts_with(bytes!("foobar")));
-        assert!(!bytes!("bar").starts_with(bytes!("foobar")));
-        assert!(bytes!("foobar").starts_with(bytes!("foobar")));
-        let empty: &[u8] = [];
-        assert!(empty.starts_with(empty));
-        assert!(!empty.starts_with(bytes!("foo")));
-        assert!(bytes!("foobar").starts_with(empty));
-    }
-
-    #[test]
-    fn test_ends_with() {
-        assert!(bytes!("foobar").ends_with(bytes!("bar")));
-        assert!(!bytes!("foobar").ends_with(bytes!("oba")));
-        assert!(!bytes!("foobar").ends_with(bytes!("foo")));
-        assert!(!bytes!("foo").ends_with(bytes!("foobar")));
-        assert!(!bytes!("bar").ends_with(bytes!("foobar")));
-        assert!(bytes!("foobar").ends_with(bytes!("foobar")));
-        let empty: &[u8] = [];
-        assert!(empty.ends_with(empty));
-        assert!(!empty.ends_with(bytes!("foo")));
-        assert!(bytes!("foobar").ends_with(empty));
-    }
+            let mut tv = TwoVec {
+                x: Vec::new(),
+                y: Vec::new()
+            };
+            tv.x.push(DropCounter {count: &mut count_x});
+            tv.y.push(DropCounter {count: &mut count_y});
 
-    #[test]
-    fn test_shift_ref() {
-        let mut x: &[int] = [1, 2, 3, 4, 5];
-        let h = x.shift_ref();
-        assert_eq!(*h.unwrap(), 1);
-        assert_eq!(x.len(), 4);
-        assert_eq!(x[0], 2);
-        assert_eq!(x[3], 5);
-
-        let mut y: &[int] = [];
-        assert_eq!(y.shift_ref(), None);
-    }
+            // If Vec had a drop flag, here is where it would be zeroed.
+            // Instead, it should rely on its internal state to prevent
+            // doing anything significant when dropped multiple times.
+            drop(tv.x);
 
-    #[test]
-    fn test_pop_ref() {
-        let mut x: &[int] = [1, 2, 3, 4, 5];
-        let h = x.pop_ref();
-        assert_eq!(*h.unwrap(), 5);
-        assert_eq!(x.len(), 4);
-        assert_eq!(x[0], 1);
-        assert_eq!(x[3], 4);
-
-        let mut y: &[int] = [];
-        assert!(y.pop_ref().is_none());
-    }
-
-    #[test]
-    fn test_mut_splitator() {
-        let mut xs = [0,1,0,2,3,0,0,4,5,0];
-        assert_eq!(xs.mut_split(|x| *x == 0).len(), 6);
-        for slice in xs.mut_split(|x| *x == 0) {
-            slice.reverse();
+            // Here tv goes out of scope, tv.y should be dropped, but not tv.x.
         }
-        assert!(xs == [0,1,0,3,2,0,0,5,4,0]);
 
-        let mut xs = [0,1,0,2,3,0,0,4,5,0,6,7];
-        for slice in xs.mut_split(|x| *x == 0).take(5) {
-            slice.reverse();
-        }
-        assert!(xs == [0,1,0,3,2,0,0,5,4,0,6,7]);
+        assert_eq!(count_x, 1);
+        assert_eq!(count_y, 1);
     }
 
     #[test]
-    fn test_mut_splitator_rev() {
-        let mut xs = [1,2,0,3,4,0,0,5,6,0];
-        for slice in xs.mut_split(|x| *x == 0).rev().take(4) {
-            slice.reverse();
-        }
-        assert!(xs == [1,2,0,4,3,0,0,6,5,0]);
-    }
+    fn test_reserve_additional() {
+        let mut v = Vec::new();
+        assert_eq!(v.capacity(), 0);
 
-    #[test]
-    fn test_mut_chunks() {
-        let mut v = [0u8, 1, 2, 3, 4, 5, 6];
-        for (i, chunk) in v.mut_chunks(3).enumerate() {
-            for x in chunk.mut_iter() {
-                *x = i as u8;
-            }
-        }
-        let result = [0u8, 0, 0, 1, 1, 1, 2];
-        assert!(v == result);
-    }
+        v.reserve_additional(2);
+        assert!(v.capacity() >= 2);
 
-    #[test]
-    fn test_mut_chunks_rev() {
-        let mut v = [0u8, 1, 2, 3, 4, 5, 6];
-        for (i, chunk) in v.mut_chunks(3).rev().enumerate() {
-            for x in chunk.mut_iter() {
-                *x = i as u8;
-            }
+        for i in range(0, 16) {
+            v.push(i);
         }
-        let result = [2u8, 2, 2, 1, 1, 1, 0];
-        assert!(v == result);
-    }
 
-    #[test]
-    #[should_fail]
-    fn test_mut_chunks_0() {
-        let mut v = [1, 2, 3, 4];
-        let _it = v.mut_chunks(0);
-    }
+        assert!(v.capacity() >= 16);
+        v.reserve_additional(16);
+        assert!(v.capacity() >= 32);
 
-    #[test]
-    fn test_mut_shift_ref() {
-        let mut x: &mut [int] = [1, 2, 3, 4, 5];
-        let h = x.mut_shift_ref();
-        assert_eq!(*h.unwrap(), 1);
-        assert_eq!(x.len(), 4);
-        assert_eq!(x[0], 2);
-        assert_eq!(x[3], 5);
+        v.push(16);
 
-        let mut y: &mut [int] = [];
-        assert!(y.mut_shift_ref().is_none());
+        v.reserve_additional(16);
+        assert!(v.capacity() >= 33)
     }
 
     #[test]
-    fn test_mut_pop_ref() {
-        let mut x: &mut [int] = [1, 2, 3, 4, 5];
-        let h = x.mut_pop_ref();
-        assert_eq!(*h.unwrap(), 5);
-        assert_eq!(x.len(), 4);
-        assert_eq!(x[0], 1);
-        assert_eq!(x[3], 4);
+    fn test_extend() {
+        let mut v = Vec::new();
+        let mut w = Vec::new();
 
-        let mut y: &mut [int] = [];
-        assert!(y.mut_pop_ref().is_none());
-    }
+        v.extend(&mut range(0, 3));
+        for i in range(0, 3) { w.push(i) }
 
-    #[test]
-    fn test_mut_last() {
-        let mut x = [1, 2, 3, 4, 5];
-        let h = x.mut_last();
-        assert_eq!(*h.unwrap(), 5);
-
-        let y: &mut [int] = [];
-        assert!(y.mut_last().is_none());
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    extern crate test;
-    use self::test::BenchHarness;
-    use mem;
-    use prelude::*;
-    use ptr;
-    use rand::{weak_rng, Rng};
-    use vec;
+        assert_eq!(v, w);
 
-    #[bench]
-    fn iterator(bh: &mut BenchHarness) {
-        // peculiar numbers to stop LLVM from optimising the summation
-        // out.
-        let v = vec::from_fn(100, |i| i ^ (i << 1) ^ (i >> 1));
-
-        bh.iter(|| {
-            let mut sum = 0;
-            for x in v.iter() {
-                sum += *x;
-            }
-            // sum == 11806, to stop dead code elimination.
-            if sum == 0 {fail!()}
-        })
-    }
-
-    #[bench]
-    fn mut_iterator(bh: &mut BenchHarness) {
-        let mut v = vec::from_elem(100, 0);
-
-        bh.iter(|| {
-            let mut i = 0;
-            for x in v.mut_iter() {
-                *x = i;
-                i += 1;
-            }
-        })
-    }
-
-    #[bench]
-    fn add(bh: &mut BenchHarness) {
-        let xs: &[int] = [5, ..10];
-        let ys: &[int] = [5, ..10];
-        bh.iter(|| {
-            xs + ys;
-        });
-    }
-
-    #[bench]
-    fn concat(bh: &mut BenchHarness) {
-        let xss: &[~[uint]] = vec::from_fn(100, |i| range(0, i).collect());
-        bh.iter(|| {
-            let _ = xss.concat_vec();
-        });
-    }
-
-    #[bench]
-    fn connect(bh: &mut BenchHarness) {
-        let xss: &[~[uint]] = vec::from_fn(100, |i| range(0, i).collect());
-        bh.iter(|| {
-            let _ = xss.connect_vec(&0);
-        });
-    }
-
-    #[bench]
-    fn push(bh: &mut BenchHarness) {
-        let mut vec: ~[uint] = ~[0u];
-        bh.iter(|| {
-            vec.push(0);
-            &vec
-        })
-    }
-
-    #[bench]
-    fn starts_with_same_vector(bh: &mut BenchHarness) {
-        let vec: ~[uint] = vec::from_fn(100, |i| i);
-        bh.iter(|| {
-            vec.starts_with(vec)
-        })
-    }
-
-    #[bench]
-    fn starts_with_single_element(bh: &mut BenchHarness) {
-        let vec: ~[uint] = ~[0u];
-        bh.iter(|| {
-            vec.starts_with(vec)
-        })
-    }
-
-    #[bench]
-    fn starts_with_diff_one_element_at_end(bh: &mut BenchHarness) {
-        let vec: ~[uint] = vec::from_fn(100, |i| i);
-        let mut match_vec: ~[uint] = vec::from_fn(99, |i| i);
-        match_vec.push(0);
-        bh.iter(|| {
-            vec.starts_with(match_vec)
-        })
-    }
-
-    #[bench]
-    fn ends_with_same_vector(bh: &mut BenchHarness) {
-        let vec: ~[uint] = vec::from_fn(100, |i| i);
-        bh.iter(|| {
-            vec.ends_with(vec)
-        })
-    }
-
-    #[bench]
-    fn ends_with_single_element(bh: &mut BenchHarness) {
-        let vec: ~[uint] = ~[0u];
-        bh.iter(|| {
-            vec.ends_with(vec)
-        })
-    }
-
-    #[bench]
-    fn ends_with_diff_one_element_at_beginning(bh: &mut BenchHarness) {
-        let vec: ~[uint] = vec::from_fn(100, |i| i);
-        let mut match_vec: ~[uint] = vec::from_fn(100, |i| i);
-        match_vec[0] = 200;
-        bh.iter(|| {
-            vec.starts_with(match_vec)
-        })
-    }
-
-    #[bench]
-    fn contains_last_element(bh: &mut BenchHarness) {
-        let vec: ~[uint] = vec::from_fn(100, |i| i);
-        bh.iter(|| {
-            vec.contains(&99u)
-        })
-    }
-
-    #[bench]
-    fn zero_1kb_from_elem(bh: &mut BenchHarness) {
-        bh.iter(|| {
-            let _v: ~[u8] = vec::from_elem(1024, 0u8);
-        });
-    }
-
-    #[bench]
-    fn zero_1kb_set_memory(bh: &mut BenchHarness) {
-        bh.iter(|| {
-            let mut v: ~[u8] = vec::with_capacity(1024);
-            unsafe {
-                let vp = v.as_mut_ptr();
-                ptr::set_memory(vp, 0, 1024);
-                v.set_len(1024);
-            }
-            v
-        });
-    }
-
-    #[bench]
-    fn zero_1kb_fixed_repeat(bh: &mut BenchHarness) {
-        bh.iter(|| {
-            ~[0u8, ..1024]
-        });
-    }
-
-    #[bench]
-    fn zero_1kb_loop_set(bh: &mut BenchHarness) {
-        // Slower because the { len, cap, [0 x T] }* repr allows a pointer to the length
-        // field to be aliased (in theory) and prevents LLVM from optimizing loads away.
-        bh.iter(|| {
-            let mut v: ~[u8] = vec::with_capacity(1024);
-            unsafe {
-                v.set_len(1024);
-            }
-            for i in range(0, 1024) {
-                v[i] = 0;
-            }
-        });
-    }
-
-    #[bench]
-    fn zero_1kb_mut_iter(bh: &mut BenchHarness) {
-        bh.iter(|| {
-            let mut v: ~[u8] = vec::with_capacity(1024);
-            unsafe {
-                v.set_len(1024);
-            }
-            for x in v.mut_iter() {
-                *x = 0;
-            }
-            v
-        });
-    }
-
-    #[bench]
-    fn random_inserts(bh: &mut BenchHarness) {
-        let mut rng = weak_rng();
-        bh.iter(|| {
-                let mut v = vec::from_elem(30, (0u, 0u));
-                for _ in range(0, 100) {
-                    let l = v.len();
-                    v.insert(rng.gen::<uint>() % (l + 1),
-                             (1, 1));
-                }
-            })
-    }
-    #[bench]
-    fn random_removes(bh: &mut BenchHarness) {
-        let mut rng = weak_rng();
-        bh.iter(|| {
-                let mut v = vec::from_elem(130, (0u, 0u));
-                for _ in range(0, 100) {
-                    let l = v.len();
-                    v.remove(rng.gen::<uint>() % l);
-                }
-            })
-    }
-
-    #[bench]
-    fn sort_random_small(bh: &mut BenchHarness) {
-        let mut rng = weak_rng();
-        bh.iter(|| {
-            let mut v: ~[u64] = rng.gen_vec(5);
-            v.sort();
-        });
-        bh.bytes = 5 * mem::size_of::<u64>() as u64;
-    }
-
-    #[bench]
-    fn sort_random_medium(bh: &mut BenchHarness) {
-        let mut rng = weak_rng();
-        bh.iter(|| {
-            let mut v: ~[u64] = rng.gen_vec(100);
-            v.sort();
-        });
-        bh.bytes = 100 * mem::size_of::<u64>() as u64;
-    }
-
-    #[bench]
-    fn sort_random_large(bh: &mut BenchHarness) {
-        let mut rng = weak_rng();
-        bh.iter(|| {
-            let mut v: ~[u64] = rng.gen_vec(10000);
-            v.sort();
-        });
-        bh.bytes = 10000 * mem::size_of::<u64>() as u64;
-    }
-
-    #[bench]
-    fn sort_sorted(bh: &mut BenchHarness) {
-        let mut v = vec::from_fn(10000, |i| i);
-        bh.iter(|| {
-            v.sort();
-        });
-        bh.bytes = (v.len() * mem::size_of_val(&v[0])) as u64;
-    }
-
-    type BigSortable = (u64,u64,u64,u64);
-
-    #[bench]
-    fn sort_big_random_small(bh: &mut BenchHarness) {
-        let mut rng = weak_rng();
-        bh.iter(|| {
-            let mut v: ~[BigSortable] = rng.gen_vec(5);
-            v.sort();
-        });
-        bh.bytes = 5 * mem::size_of::<BigSortable>() as u64;
-    }
-
-    #[bench]
-    fn sort_big_random_medium(bh: &mut BenchHarness) {
-        let mut rng = weak_rng();
-        bh.iter(|| {
-            let mut v: ~[BigSortable] = rng.gen_vec(100);
-            v.sort();
-        });
-        bh.bytes = 100 * mem::size_of::<BigSortable>() as u64;
-    }
-
-    #[bench]
-    fn sort_big_random_large(bh: &mut BenchHarness) {
-        let mut rng = weak_rng();
-        bh.iter(|| {
-            let mut v: ~[BigSortable] = rng.gen_vec(10000);
-            v.sort();
-        });
-        bh.bytes = 10000 * mem::size_of::<BigSortable>() as u64;
-    }
+        v.extend(&mut range(3, 10));
+        for i in range(3, 10) { w.push(i) }
 
-    #[bench]
-    fn sort_big_sorted(bh: &mut BenchHarness) {
-        let mut v = vec::from_fn(10000u, |i| (i, i, i, i));
-        bh.iter(|| {
-            v.sort();
-        });
-        bh.bytes = (v.len() * mem::size_of_val(&v[0])) as u64;
+        assert_eq!(v, w);
     }
 }
diff --git a/src/libstd/vec_ng.rs b/src/libstd/vec_ng.rs
deleted file mode 100644
index 04e3ad920ec..00000000000
--- a/src/libstd/vec_ng.rs
+++ /dev/null
@@ -1,1353 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-//! A growable, owned vector
-
-use cast::{forget, transmute};
-use clone::Clone;
-use cmp::{Ord, Eq, Ordering, TotalEq, TotalOrd};
-use container::{Container, Mutable};
-use default::Default;
-use fmt;
-use iter::{DoubleEndedIterator, FromIterator, Extendable, Iterator};
-use libc::{free, c_void};
-use mem::{size_of, move_val_init};
-use mem;
-use num;
-use num::{CheckedMul, CheckedAdd};
-use ops::Drop;
-use option::{None, Option, Some};
-use ptr::RawPtr;
-use ptr;
-use rt::global_heap::{malloc_raw, realloc_raw};
-use raw::Slice;
-use vec::{ImmutableEqVector, ImmutableVector, Items, MutItems, MutableVector};
-use vec::{MutableTotalOrdVector};
-
-/// An owned, growable vector
-///
-/// `Vec<T>` is the replacement for the deprecated `~[T]` type. The API is
-/// largely the same. The `vec!` macro is provided to make initialization
-/// easier.
-///
-/// # Example
-///
-/// ```rust
-/// let mut vec = vec!(1, 2, 3);
-/// vec.push(4);
-/// println!("{}", vec); // prints [1, 2, 3, 4]
-/// ```
-#[unsafe_no_drop_flag]
-pub struct Vec<T> {
-    priv len: uint,
-    priv cap: uint,
-    priv ptr: *mut T
-}
-
-impl<T> Vec<T> {
-    /// Constructs a new, empty `Vec`.
-    ///
-    /// The vector will not allocate until elements are pushed onto it.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// # use std::vec_ng::Vec;
-    /// let mut vec: Vec<int> = Vec::new();
-    /// ```
-    #[inline]
-    pub fn new() -> Vec<T> {
-        Vec { len: 0, cap: 0, ptr: 0 as *mut T }
-    }
-
-    /// Constructs a new, empty `Vec` with the specified capacity.
-    ///
-    /// The vector will be able to hold exactly `capacity` elements without
-    /// reallocating. If `capacity` is 0, the vector will not allocate.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// # use std::vec_ng::Vec;
-    /// let vec: Vec<int> = Vec::with_capacity(10);
-    /// ```
-    pub fn with_capacity(capacity: uint) -> Vec<T> {
-        if capacity == 0 {
-            Vec::new()
-        } else {
-            let size = capacity.checked_mul(&size_of::<T>()).expect("capacity overflow");
-            let ptr = unsafe { malloc_raw(size) };
-            Vec { len: 0, cap: capacity, ptr: ptr as *mut T }
-        }
-    }
-
-
-    /// Creates and initializes a `Vec`.
-    ///
-    /// Creates a `Vec` of size `length` and initializes the elements to the
-    /// value returned by the closure `op`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// # use std::vec_ng::Vec;
-    /// let vec = Vec::from_fn(3, |idx| idx * 2);
-    /// assert_eq!(vec, vec!(0, 2, 4));
-    /// ```
-    pub fn from_fn(length: uint, op: |uint| -> T) -> Vec<T> {
-        unsafe {
-            let mut xs = Vec::with_capacity(length);
-            while xs.len < length {
-                move_val_init(xs.as_mut_slice().unsafe_mut_ref(xs.len), op(xs.len));
-                xs.len += 1;
-            }
-            xs
-        }
-    }
-
-    /// Consumes the `Vec`, partitioning it based on a predcate.
-    ///
-    /// Partitions the `Vec` into two `Vec`s `(A,B)`, where all elements of `A`
-    /// satisfy `f` and all elements of `B` do not. The order of elements is
-    /// preserved.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3, 4);
-    /// let (even, odd) = vec.partition(|&n| n % 2 == 0);
-    /// assert_eq!(even, vec!(2, 4));
-    /// assert_eq!(odd, vec!(1, 3));
-    /// ```
-    #[inline]
-    pub fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
-        let mut lefts  = Vec::new();
-        let mut rights = Vec::new();
-
-        for elt in self.move_iter() {
-            if f(&elt) {
-                lefts.push(elt);
-            } else {
-                rights.push(elt);
-            }
-        }
-
-        (lefts, rights)
-    }
-}
-
-impl<T: Clone> Vec<T> {
-    /// Constructs a `Vec` by cloning elements of a slice.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// # use std::vec_ng::Vec;
-    /// let slice = [1, 2, 3];
-    /// let vec = Vec::from_slice(slice);
-    /// ```
-    pub fn from_slice(values: &[T]) -> Vec<T> {
-        values.iter().map(|x| x.clone()).collect()
-    }
-
-    /// Constructs a `Vec` with copies of a value.
-    ///
-    /// Creates a `Vec` with `length` copies of `value`.
-    ///
-    /// # Example
-    /// ```rust
-    /// # use std::vec_ng::Vec;
-    /// let vec = Vec::from_elem(3, "hi");
-    /// println!("{}", vec); // prints [hi, hi, hi]
-    /// ```
-    pub fn from_elem(length: uint, value: T) -> Vec<T> {
-        unsafe {
-            let mut xs = Vec::with_capacity(length);
-            while xs.len < length {
-                move_val_init(xs.as_mut_slice().unsafe_mut_ref(xs.len), value.clone());
-                xs.len += 1;
-            }
-            xs
-        }
-    }
-
-    /// Appends all elements in a slice to the `Vec`.
-    ///
-    /// Iterates over the slice `other`, clones each element, and then appends
-    /// it to this `Vec`. The `other` vector is traversed in-order.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1);
-    /// vec.push_all([2, 3, 4]);
-    /// assert_eq!(vec, vec!(1, 2, 3, 4));
-    /// ```
-    #[inline]
-    pub fn push_all(&mut self, other: &[T]) {
-        for element in other.iter() {
-            self.push((*element).clone())
-        }
-    }
-
-    /// Grows the `Vec` in-place.
-    ///
-    /// Adds `n` copies of `value` to the `Vec`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!("hello");
-    /// vec.grow(2, & &"world");
-    /// assert_eq!(vec, vec!("hello", "world", "world"));
-    /// ```
-    pub fn grow(&mut self, n: uint, value: &T) {
-        let new_len = self.len() + n;
-        self.reserve(new_len);
-        let mut i: uint = 0u;
-
-        while i < n {
-            self.push((*value).clone());
-            i += 1u;
-        }
-    }
-
-    /// Sets the value of a vector element at a given index, growing the vector
-    /// as needed.
-    ///
-    /// Sets the element at position `index` to `value`. If `index` is past the
-    /// end of the vector, expands the vector by replicating `initval` to fill
-    /// the intervening space.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!("a", "b", "c");
-    /// vec.grow_set(1, & &"fill", "d");
-    /// vec.grow_set(4, & &"fill", "e");
-    /// assert_eq!(vec, vec!("a", "d", "c", "fill", "e"));
-    /// ```
-    pub fn grow_set(&mut self, index: uint, initval: &T, value: T) {
-        let l = self.len();
-        if index >= l {
-            self.grow(index - l + 1u, initval);
-        }
-        *self.get_mut(index) = value;
-    }
-
-    /// Partitions a vector based on a predcate.
-    ///
-    /// Clones the elements of the vector, partitioning them into two `Vec`s
-    /// `(A,B)`, where all elements of `A` satisfy `f` and all elements of `B`
-    /// do not. The order of elements is preserved.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3, 4);
-    /// let (even, odd) = vec.partitioned(|&n| n % 2 == 0);
-    /// assert_eq!(even, vec!(2, 4));
-    /// assert_eq!(odd, vec!(1, 3));
-    /// ```
-    pub fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
-        let mut lefts = Vec::new();
-        let mut rights = Vec::new();
-
-        for elt in self.iter() {
-            if f(elt) {
-                lefts.push(elt.clone());
-            } else {
-                rights.push(elt.clone());
-            }
-        }
-
-        (lefts, rights)
-    }
-}
-
-impl<T:Clone> Clone for Vec<T> {
-    fn clone(&self) -> Vec<T> {
-        let mut vector = Vec::with_capacity(self.len());
-        for element in self.iter() {
-            vector.push((*element).clone())
-        }
-        vector
-    }
-}
-
-impl<T> FromIterator<T> for Vec<T> {
-    fn from_iterator<I:Iterator<T>>(iterator: &mut I) -> Vec<T> {
-        let (lower, _) = iterator.size_hint();
-        let mut vector = Vec::with_capacity(lower);
-        for element in *iterator {
-            vector.push(element)
-        }
-        vector
-    }
-}
-
-impl<T> Extendable<T> for Vec<T> {
-    fn extend<I: Iterator<T>>(&mut self, iterator: &mut I) {
-        let (lower, _) = iterator.size_hint();
-        self.reserve_additional(lower);
-        for element in *iterator {
-            self.push(element)
-        }
-    }
-}
-
-impl<T: Eq> Eq for Vec<T> {
-    #[inline]
-    fn eq(&self, other: &Vec<T>) -> bool {
-        self.as_slice() == other.as_slice()
-    }
-}
-
-impl<T: Ord> Ord for Vec<T> {
-    #[inline]
-    fn lt(&self, other: &Vec<T>) -> bool {
-        self.as_slice() < other.as_slice()
-    }
-}
-
-impl<T: TotalEq> TotalEq for Vec<T> {
-    #[inline]
-    fn equals(&self, other: &Vec<T>) -> bool {
-        self.as_slice().equals(&other.as_slice())
-    }
-}
-
-impl<T: TotalOrd> TotalOrd for Vec<T> {
-    #[inline]
-    fn cmp(&self, other: &Vec<T>) -> Ordering {
-        self.as_slice().cmp(&other.as_slice())
-    }
-}
-
-impl<T> Container for Vec<T> {
-    #[inline]
-    fn len(&self) -> uint {
-        self.len
-    }
-}
-
-impl<T> Vec<T> {
-    /// Returns the number of elements the vector can hold without
-    /// reallocating.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// # use std::vec_ng::Vec;
-    /// let vec: Vec<int> = Vec::with_capacity(10);
-    /// assert_eq!(vec.capacity(), 10);
-    /// ```
-    #[inline]
-    pub fn capacity(&self) -> uint {
-        self.cap
-    }
-
-     /// Reserves capacity for at least `n` additional elements in the given
-     /// vector.
-     ///
-     /// # Failure
-     ///
-     /// Fails if the new capacity overflows `uint`.
-     ///
-     /// # Example
-     ///
-     /// ```rust
-     /// # use std::vec_ng::Vec;
-     /// let mut vec: Vec<int> = vec!(1);
-     /// vec.reserve_additional(10);
-     /// assert!(vec.capacity() >= 11);
-     /// ```
-    pub fn reserve_additional(&mut self, extra: uint) {
-        if self.cap - self.len < extra {
-            match self.len.checked_add(&extra) {
-                None => fail!("Vec::reserve_additional: `uint` overflow"),
-                Some(new_cap) => self.reserve(new_cap)
-            }
-        }
-    }
-
-    /// Reserves capacity for at least `n` elements in the given vector.
-    ///
-    /// This function will over-allocate in order to amortize the allocation
-    /// costs in scenarios where the caller may need to repeatedly reserve
-    /// additional space.
-    ///
-    /// If the capacity for `self` is already equal to or greater than the
-    /// requested capacity, then no action is taken.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// vec.reserve(10);
-    /// assert!(vec.capacity() >= 10);
-    /// ```
-    pub fn reserve(&mut self, capacity: uint) {
-        if capacity >= self.len {
-            self.reserve_exact(num::next_power_of_two(capacity))
-        }
-    }
-
-    /// Reserves capacity for exactly `capacity` elements in the given vector.
-    ///
-    /// If the capacity for `self` is already equal to or greater than the
-    /// requested capacity, then no action is taken.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// # use std::vec_ng::Vec;
-    /// let mut vec: Vec<int> = Vec::with_capacity(10);
-    /// vec.reserve_exact(11);
-    /// assert_eq!(vec.capacity(), 11);
-    /// ```
-    pub fn reserve_exact(&mut self, capacity: uint) {
-        if capacity >= self.len {
-            let size = capacity.checked_mul(&size_of::<T>()).expect("capacity overflow");
-            self.cap = capacity;
-            unsafe {
-                self.ptr = realloc_raw(self.ptr as *mut u8, size) as *mut T;
-            }
-        }
-    }
-
-    /// Shrink the capacity of the vector to match the length
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// vec.shrink_to_fit();
-    /// assert_eq!(vec.capacity(), vec.len());
-    /// ```
-    pub fn shrink_to_fit(&mut self) {
-        if self.len == 0 {
-            unsafe { free(self.ptr as *mut c_void) };
-            self.cap = 0;
-            self.ptr = 0 as *mut T;
-        } else {
-            unsafe {
-                // Overflow check is unnecessary as the vector is already at least this large.
-                self.ptr = realloc_raw(self.ptr as *mut u8, self.len * size_of::<T>()) as *mut T;
-            }
-            self.cap = self.len;
-        }
-    }
-
-    /// Remove the last element from a vector and return it, or `None` if it is
-    /// empty.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// assert_eq!(vec.pop(), Some(3));
-    /// assert_eq!(vec, vec!(1, 2));
-    /// ```
-    #[inline]
-    pub fn pop(&mut self) -> Option<T> {
-        if self.len == 0 {
-            None
-        } else {
-            unsafe {
-                self.len -= 1;
-                Some(ptr::read(self.as_slice().unsafe_ref(self.len())))
-            }
-        }
-    }
-
-    /// Append an element to a vector.
-    ///
-    /// # Failure
-    ///
-    /// Fails if the number of elements in the vector overflows a `uint`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2);
-    /// vec.push(3);
-    /// assert_eq!(vec, vec!(1, 2, 3));
-    /// ```
-    #[inline]
-    pub fn push(&mut self, value: T) {
-        if self.len == self.cap {
-            if self.cap == 0 { self.cap += 2 }
-            let old_size = self.cap * size_of::<T>();
-            self.cap = self.cap * 2;
-            let size = old_size * 2;
-            if old_size > size { fail!("capacity overflow") }
-            unsafe {
-                self.ptr = realloc_raw(self.ptr as *mut u8, size) as *mut T;
-            }
-        }
-
-        unsafe {
-            let end = (self.ptr as *T).offset(self.len as int) as *mut T;
-            move_val_init(&mut *end, value);
-            self.len += 1;
-        }
-    }
-
-    /// Shorten a vector, dropping excess elements.
-    ///
-    /// If `len` is greater than the vector's current length, this has no
-    /// effect.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3, 4);
-    /// vec.truncate(2);
-    /// assert_eq!(vec, vec!(1, 2));
-    /// ```
-    pub fn truncate(&mut self, len: uint) {
-        unsafe {
-            let mut i = len;
-            // drop any extra elements
-            while i < self.len {
-                ptr::read(self.as_slice().unsafe_ref(i));
-                i += 1;
-            }
-        }
-        self.len = len;
-    }
-
-    /// Work with `self` as a slice.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// fn foo(slice: &[int]) {}
-    ///
-    /// let vec = vec!(1, 2);
-    /// foo(vec.as_slice());
-    /// ```
-    #[inline]
-    pub fn as_slice<'a>(&'a self) -> &'a [T] {
-        let slice = Slice { data: self.ptr as *T, len: self.len };
-        unsafe { transmute(slice) }
-    }
-
-    /// Work with `self` as a mutable slice.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// fn foo(slice: &mut [int]) {}
-    ///
-    /// let mut vec = vec!(1, 2);
-    /// foo(vec.as_mut_slice());
-    /// ```
-    #[inline]
-    pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
-        let slice = Slice { data: self.ptr as *T, len: self.len };
-        unsafe { transmute(slice) }
-    }
-
-    /// Creates a consuming iterator, that is, one that moves each
-    /// value out of the vector (from start to end). The vector cannot
-    /// be used after calling this.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let v = vec!(~"a", ~"b");
-    /// for s in v.move_iter() {
-    ///     // s has type ~str, not &~str
-    ///     println!("{}", s);
-    /// }
-    /// ```
-    #[inline]
-    pub fn move_iter(self) -> MoveItems<T> {
-        unsafe {
-            let iter = transmute(self.as_slice().iter());
-            let ptr = self.ptr as *mut c_void;
-            forget(self);
-            MoveItems { allocation: ptr, iter: iter }
-        }
-    }
-
-
-    /// Sets the length of a vector.
-    ///
-    /// This will explicitly set the size of the vector, without actually
-    /// modifying its buffers, so it is up to the caller to ensure that the
-    /// vector is actually the specified size.
-    #[inline]
-    pub unsafe fn set_len(&mut self, len: uint) {
-        self.len = len;
-    }
-
-    /// Returns a reference to the value at index `index`.
-    ///
-    /// # Failure
-    ///
-    /// Fails if `index` is out of bounds
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3);
-    /// assert!(vec.get(1) == &2);
-    /// ```
-    #[inline]
-    pub fn get<'a>(&'a self, index: uint) -> &'a T {
-        &self.as_slice()[index]
-    }
-
-    /// Returns a mutable reference to the value at index `index`.
-    ///
-    /// # Failure
-    ///
-    /// Fails if `index` is out of bounds
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// *vec.get_mut(1) = 4;
-    /// assert_eq!(vec, vec!(1, 4, 3));
-    /// ```
-    #[inline]
-    pub fn get_mut<'a>(&'a mut self, index: uint) -> &'a mut T {
-        &mut self.as_mut_slice()[index]
-    }
-
-    /// Returns an iterator over references to the elements of the vector in
-    /// order.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3);
-    /// for num in vec.iter() {
-    ///     println!("{}", *num);
-    /// }
-    /// ```
-    #[inline]
-    pub fn iter<'a>(&'a self) -> Items<'a,T> {
-        self.as_slice().iter()
-    }
-
-
-    /// Returns an iterator over mutable references to the elements of the
-    /// vector in order.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// for num in vec.mut_iter() {
-    ///     *num = 0;
-    /// }
-    /// ```
-    #[inline]
-    pub fn mut_iter<'a>(&'a mut self) -> MutItems<'a,T> {
-        self.as_mut_slice().mut_iter()
-    }
-
-    /// Sort the vector, in place, using `compare` to compare elements.
-    ///
-    /// This sort is `O(n log n)` worst-case and stable, but allocates
-    /// approximately `2 * n`, where `n` is the length of `self`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut v = vec!(5i, 4, 1, 3, 2);
-    /// v.sort_by(|a, b| a.cmp(b));
-    /// assert_eq!(v, vec!(1, 2, 3, 4, 5));
-    ///
-    /// // reverse sorting
-    /// v.sort_by(|a, b| b.cmp(a));
-    /// assert_eq!(v, vec!(5, 4, 3, 2, 1));
-    /// ```
-    #[inline]
-    pub fn sort_by(&mut self, compare: |&T, &T| -> Ordering) {
-        self.as_mut_slice().sort_by(compare)
-    }
-
-    /// Returns a slice of `self` between `start` and `end`.
-    ///
-    /// # Failure
-    ///
-    /// Fails when `start` or `end` point outside the bounds of `self`, or when
-    /// `start` > `end`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3, 4);
-    /// assert!(vec.slice(0, 2) == [1, 2]);
-    /// ```
-    #[inline]
-    pub fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T] {
-        self.as_slice().slice(start, end)
-    }
-
-    /// Returns a slice containing all but the first element of the vector.
-    ///
-    /// # Failure
-    ///
-    /// Fails when the vector is empty.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3);
-    /// assert!(vec.tail() == [2, 3]);
-    /// ```
-    #[inline]
-    pub fn tail<'a>(&'a self) -> &'a [T] {
-        self.as_slice().tail()
-    }
-
-    /// Returns all but the first `n' elements of a vector.
-    ///
-    /// # Failure
-    ///
-    /// Fails when there are fewer than `n` elements in the vector.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3, 4);
-    /// assert!(vec.tailn(2) == [3, 4]);
-    /// ```
-    #[inline]
-    pub fn tailn<'a>(&'a self, n: uint) -> &'a [T] {
-        self.as_slice().tailn(n)
-    }
-
-    /// Returns a reference to the last element of a vector, or `None` if it is
-    /// empty.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3);
-    /// assert!(vec.last() == Some(&3));
-    /// ```
-    #[inline]
-    pub fn last<'a>(&'a self) -> Option<&'a T> {
-        self.as_slice().last()
-    }
-
-    /// Returns a mutable reference to the last element of a vector, or `None`
-    /// if it is empty.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// *vec.mut_last().unwrap() = 4;
-    /// assert_eq!(vec, vec!(1, 2, 4));
-    /// ```
-    #[inline]
-    pub fn mut_last<'a>(&'a mut self) -> Option<&'a mut T> {
-        self.as_mut_slice().mut_last()
-    }
-
-    /// Remove an element from anywhere in the vector and return it, replacing
-    /// it with the last element. This does not preserve ordering, but is O(1).
-    ///
-    /// Returns `None` if `index` is out of bounds.
-    ///
-    /// # Example
-    /// ```rust
-    /// let mut v = ~[~"foo", ~"bar", ~"baz", ~"qux"];
-    ///
-    /// assert_eq!(v.swap_remove(1), Some(~"bar"));
-    /// assert_eq!(v, ~[~"foo", ~"qux", ~"baz"]);
-    ///
-    /// assert_eq!(v.swap_remove(0), Some(~"foo"));
-    /// assert_eq!(v, ~[~"baz", ~"qux"]);
-    ///
-    /// assert_eq!(v.swap_remove(2), None);
-    /// ```
-    #[inline]
-    pub fn swap_remove(&mut self, index: uint) -> Option<T> {
-        let length = self.len();
-        if index < length - 1 {
-            self.as_mut_slice().swap(index, length - 1);
-        } else if index >= length {
-            return None
-        }
-        self.pop()
-    }
-
-    /// Prepend an element to the vector.
-    ///
-    /// # Warning
-    ///
-    /// This is an O(n) operation as it requires copying every element in the
-    /// vector.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// vec.unshift(4);
-    /// assert_eq!(vec, vec!(4, 1, 2, 3));
-    /// ```
-    #[inline]
-    pub fn unshift(&mut self, element: T) {
-        self.insert(0, element)
-    }
-
-    /// Removes the first element from a vector and returns it, or `None` if
-    /// the vector is empty.
-    ///
-    /// # Warning
-    ///
-    /// This is an O(n) operation as it requires copying every element in the
-    /// vector.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// assert!(vec.shift() == Some(1));
-    /// assert_eq!(vec, vec!(2, 3));
-    /// ```
-    #[inline]
-    pub fn shift(&mut self) -> Option<T> {
-        self.remove(0)
-    }
-
-    /// Insert an element at position `index` within the vector, shifting all
-    /// elements after position i one position to the right.
-    ///
-    /// # Failure
-    ///
-    /// Fails if `index` is out of bounds of the vector.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// vec.insert(1, 4);
-    /// assert_eq!(vec, vec!(1, 4, 2, 3));
-    /// ```
-    pub fn insert(&mut self, index: uint, element: T) {
-        let len = self.len();
-        assert!(index <= len);
-        // space for the new element
-        self.reserve(len + 1);
-
-        unsafe { // infallible
-            // The spot to put the new value
-            {
-                let p = self.as_mut_ptr().offset(index as int);
-                // Shift everything over to make space. (Duplicating the
-                // `index`th element into two consecutive places.)
-                ptr::copy_memory(p.offset(1), &*p, len - index);
-                // Write it in, overwriting the first copy of the `index`th
-                // element.
-                move_val_init(&mut *p, element);
-            }
-            self.set_len(len + 1);
-        }
-    }
-
-    /// Remove and return the element at position `index` within the vector,
-    /// shifting all elements after position `index` one position to the left.
-    /// Returns `None` if `i` is out of bounds.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut v = ~[1, 2, 3];
-    /// assert_eq!(v.remove(1), Some(2));
-    /// assert_eq!(v, ~[1, 3]);
-    ///
-    /// assert_eq!(v.remove(4), None);
-    /// // v is unchanged:
-    /// assert_eq!(v, ~[1, 3]);
-    /// ```
-    pub fn remove(&mut self, index: uint) -> Option<T> {
-        let len = self.len();
-        if index < len {
-            unsafe { // infallible
-                let ret;
-                {
-                    // the place we are taking from.
-                    let ptr = self.as_mut_ptr().offset(index as int);
-                    // copy it out, unsafely having a copy of the value on
-                    // the stack and in the vector at the same time.
-                    ret = Some(ptr::read(ptr as *T));
-
-                    // Shift everything down to fill in that spot.
-                    ptr::copy_memory(ptr, &*ptr.offset(1), len - index - 1);
-                }
-                self.set_len(len - 1);
-                ret
-            }
-        } else {
-            None
-        }
-    }
-
-    ///Apply a function to each element of a vector and return the results.
-    #[inline]
-    #[deprecated="Use `xs.iter().map(closure)` instead."]
-    pub fn map<U>(&self, f: |t: &T| -> U) -> Vec<U> {
-        self.iter().map(f).collect()
-    }
-
-    /// Takes ownership of the vector `other`, moving all elements into
-    /// the current vector. This does not copy any elements, and it is
-    /// illegal to use the `other` vector after calling this method
-    /// (because it is moved here).
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(~1);
-    /// vec.push_all_move(vec!(~2, ~3, ~4));
-    /// assert_eq!(vec, vec!(~1, ~2, ~3, ~4));
-    /// ```
-    pub fn push_all_move(&mut self, other: Vec<T>) {
-        for element in other.move_iter() {
-            self.push(element)
-        }
-    }
-
-    /// Returns a mutable slice of `self` between `start` and `end`.
-    ///
-    /// # Failure
-    ///
-    /// Fails when `start` or `end` point outside the bounds of `self`, or when
-    /// `start` > `end`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3, 4);
-    /// assert!(vec.mut_slice(0, 2) == [1, 2]);
-    /// ```
-    #[inline]
-    pub fn mut_slice<'a>(&'a mut self, start: uint, end: uint)
-                         -> &'a mut [T] {
-        self.as_mut_slice().mut_slice(start, end)
-    }
-
-    /// Reverse the order of elements in a vector, in place.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut v = vec!(1, 2, 3);
-    /// v.reverse();
-    /// assert_eq!(v, vec!(3, 2, 1));
-    /// ```
-    #[inline]
-    pub fn reverse(&mut self) {
-        self.as_mut_slice().reverse()
-    }
-
-    /// Returns a slice of `self` from `start` to the end of the vec.
-    ///
-    /// # Failure
-    ///
-    /// Fails when `start` points outside the bounds of self.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3);
-    /// assert!(vec.slice_from(1) == [2, 3]);
-    /// ```
-    #[inline]
-    pub fn slice_from<'a>(&'a self, start: uint) -> &'a [T] {
-        self.as_slice().slice_from(start)
-    }
-
-    /// Returns a slice of self from the start of the vec to `end`.
-    ///
-    /// # Failure
-    ///
-    /// Fails when `end` points outside the bounds of self.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3);
-    /// assert!(vec.slice_to(2) == [1, 2]);
-    /// ```
-    #[inline]
-    pub fn slice_to<'a>(&'a self, end: uint) -> &'a [T] {
-        self.as_slice().slice_to(end)
-    }
-
-    /// Returns a slice containing all but the last element of the vector.
-    ///
-    /// # Failure
-    ///
-    /// Fails if the vector is empty
-    #[inline]
-    pub fn init<'a>(&'a self) -> &'a [T] {
-        self.slice(0, self.len() - 1)
-    }
-
-
-    /// Returns an unsafe pointer to the vector's buffer.
-    ///
-    /// The caller must ensure that the vector outlives the pointer this
-    /// function returns, or else it will end up pointing to garbage.
-    ///
-    /// Modifying the vector may cause its buffer to be reallocated, which
-    /// would also make any pointers to it invalid.
-    #[inline]
-    pub fn as_ptr(&self) -> *T {
-        self.as_slice().as_ptr()
-    }
-
-    /// Returns a mutable unsafe pointer to the vector's buffer.
-    ///
-    /// The caller must ensure that the vector outlives the pointer this
-    /// function returns, or else it will end up pointing to garbage.
-    ///
-    /// Modifying the vector may cause its buffer to be reallocated, which
-    /// would also make any pointers to it invalid.
-    #[inline]
-    pub fn as_mut_ptr(&mut self) -> *mut T {
-        self.as_mut_slice().as_mut_ptr()
-    }
-}
-
-impl<T:TotalOrd> Vec<T> {
-    /// Sorts the vector in place.
-    ///
-    /// This sort is `O(n log n)` worst-case and stable, but allocates
-    /// approximately `2 * n`, where `n` is the length of `self`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(3i, 1, 2);
-    /// vec.sort();
-    /// assert_eq!(vec, vec!(1, 2, 3));
-    /// ```
-    pub fn sort(&mut self) {
-        self.as_mut_slice().sort()
-    }
-}
-
-impl<T> Mutable for Vec<T> {
-    #[inline]
-    fn clear(&mut self) {
-        self.truncate(0)
-    }
-}
-
-impl<T:Eq> Vec<T> {
-    /// Return true if a vector contains an element with the given value
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3);
-    /// assert!(vec.contains(&1));
-    /// ```
-    pub fn contains(&self, x: &T) -> bool {
-        self.as_slice().contains(x)
-    }
-
-    /// Remove consecutive repeated elements in the vector.
-    ///
-    /// If the vector is sorted, this removes all duplicates.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 2, 3, 2);
-    /// vec.dedup();
-    /// assert_eq!(vec, vec!(1, 2, 3, 2));
-    /// ```
-    pub fn dedup(&mut self) {
-        unsafe {
-            // Although we have a mutable reference to `self`, we cannot make
-            // *arbitrary* changes. The `Eq` comparisons could fail, so we
-            // must ensure that the vector is in a valid state at all time.
-            //
-            // The way that we handle this is by using swaps; we iterate
-            // over all the elements, swapping as we go so that at the end
-            // the elements we wish to keep are in the front, and those we
-            // wish to reject are at the back. We can then truncate the
-            // vector. This operation is still O(n).
-            //
-            // Example: We start in this state, where `r` represents "next
-            // read" and `w` represents "next_write`.
-            //
-            //           r
-            //     +---+---+---+---+---+---+
-            //     | 0 | 1 | 1 | 2 | 3 | 3 |
-            //     +---+---+---+---+---+---+
-            //           w
-            //
-            // Comparing self[r] against self[w-1], tis is not a duplicate, so
-            // we swap self[r] and self[w] (no effect as r==w) and then increment both
-            // r and w, leaving us with:
-            //
-            //               r
-            //     +---+---+---+---+---+---+
-            //     | 0 | 1 | 1 | 2 | 3 | 3 |
-            //     +---+---+---+---+---+---+
-            //               w
-            //
-            // Comparing self[r] against self[w-1], this value is a duplicate,
-            // so we increment `r` but leave everything else unchanged:
-            //
-            //                   r
-            //     +---+---+---+---+---+---+
-            //     | 0 | 1 | 1 | 2 | 3 | 3 |
-            //     +---+---+---+---+---+---+
-            //               w
-            //
-            // Comparing self[r] against self[w-1], this is not a duplicate,
-            // so swap self[r] and self[w] and advance r and w:
-            //
-            //                       r
-            //     +---+---+---+---+---+---+
-            //     | 0 | 1 | 2 | 1 | 3 | 3 |
-            //     +---+---+---+---+---+---+
-            //                   w
-            //
-            // Not a duplicate, repeat:
-            //
-            //                           r
-            //     +---+---+---+---+---+---+
-            //     | 0 | 1 | 2 | 3 | 1 | 3 |
-            //     +---+---+---+---+---+---+
-            //                       w
-            //
-            // Duplicate, advance r. End of vec. Truncate to w.
-
-            let ln = self.len();
-            if ln < 1 { return; }
-
-            // Avoid bounds checks by using unsafe pointers.
-            let p = self.as_mut_slice().as_mut_ptr();
-            let mut r = 1;
-            let mut w = 1;
-
-            while r < ln {
-                let p_r = p.offset(r as int);
-                let p_wm1 = p.offset((w - 1) as int);
-                if *p_r != *p_wm1 {
-                    if r != w {
-                        let p_w = p_wm1.offset(1);
-                        mem::swap(&mut *p_r, &mut *p_w);
-                    }
-                    w += 1;
-                }
-                r += 1;
-            }
-
-            self.truncate(w);
-        }
-    }
-}
-
-/// Iterates over the `second` vector, copying each element and appending it to
-/// the `first`. Afterwards, the `first` is then returned for use again.
-///
-/// # Example
-///
-/// ```rust
-/// let vec = vec!(1, 2);
-/// let vec = std::vec_ng::append(vec, [3, 4]);
-/// assert_eq!(vec, vec!(1, 2, 3, 4));
-/// ```
-#[inline]
-pub fn append<T:Clone>(mut first: Vec<T>, second: &[T]) -> Vec<T> {
-    first.push_all(second);
-    first
-}
-
-/// Appends one element to the vector provided. The vector itself is then
-/// returned for use again.
-///
-/// # Example
-///
-/// ```rust
-/// let vec = vec!(1, 2);
-/// let vec = std::vec_ng::append_one(vec, 3);
-/// assert_eq!(vec, vec!(1, 2, 3));
-/// ```
-#[inline]
-pub fn append_one<T>(mut lhs: Vec<T>, x: T) -> Vec<T> {
-    lhs.push(x);
-    lhs
-}
-
-#[unsafe_destructor]
-impl<T> Drop for Vec<T> {
-    fn drop(&mut self) {
-        // This is (and should always remain) a no-op if the fields are
-        // zeroed (when moving out, because of #[unsafe_no_drop_flag]).
-        unsafe {
-            for x in self.as_mut_slice().iter() {
-                ptr::read(x);
-            }
-            free(self.ptr as *mut c_void)
-        }
-    }
-}
-
-impl<T> Default for Vec<T> {
-    fn default() -> Vec<T> {
-        Vec::new()
-    }
-}
-
-impl<T:fmt::Show> fmt::Show for Vec<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.as_slice().fmt(f)
-    }
-}
-
-/// An iterator that moves out of a vector.
-pub struct MoveItems<T> {
-    priv allocation: *mut c_void, // the block of memory allocated for the vector
-    priv iter: Items<'static, T>
-}
-
-impl<T> Iterator<T> for MoveItems<T> {
-    #[inline]
-    fn next(&mut self) -> Option<T> {
-        unsafe {
-            self.iter.next().map(|x| ptr::read(x))
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        self.iter.size_hint()
-    }
-}
-
-impl<T> DoubleEndedIterator<T> for MoveItems<T> {
-    #[inline]
-    fn next_back(&mut self) -> Option<T> {
-        unsafe {
-            self.iter.next_back().map(|x| ptr::read(x))
-        }
-    }
-}
-
-#[unsafe_destructor]
-impl<T> Drop for MoveItems<T> {
-    fn drop(&mut self) {
-        // destroy the remaining elements
-        for _x in *self {}
-        unsafe {
-            free(self.allocation)
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::Vec;
-    use iter::{Iterator, range, Extendable};
-    use mem::{drop, size_of};
-    use ops::Drop;
-    use option::{Some, None};
-    use ptr;
-
-    #[test]
-    fn test_small_vec_struct() {
-        assert!(size_of::<Vec<u8>>() == size_of::<uint>() * 3);
-    }
-
-    #[test]
-    fn test_double_drop() {
-        struct TwoVec<T> {
-            x: Vec<T>,
-            y: Vec<T>
-        }
-
-        struct DropCounter<'a> {
-            count: &'a mut int
-        }
-
-        #[unsafe_destructor]
-        impl<'a> Drop for DropCounter<'a> {
-            fn drop(&mut self) {
-                *self.count += 1;
-            }
-        }
-
-        let mut count_x @ mut count_y = 0;
-        {
-            let mut tv = TwoVec {
-                x: Vec::new(),
-                y: Vec::new()
-            };
-            tv.x.push(DropCounter {count: &mut count_x});
-            tv.y.push(DropCounter {count: &mut count_y});
-
-            // If Vec had a drop flag, here is where it would be zeroed.
-            // Instead, it should rely on its internal state to prevent
-            // doing anything significant when dropped multiple times.
-            drop(tv.x);
-
-            // Here tv goes out of scope, tv.y should be dropped, but not tv.x.
-        }
-
-        assert_eq!(count_x, 1);
-        assert_eq!(count_y, 1);
-    }
-
-    #[test]
-    fn test_reserve_additional() {
-        let mut v = Vec::new();
-        assert_eq!(v.capacity(), 0);
-
-        v.reserve_additional(2);
-        assert!(v.capacity() >= 2);
-
-        for i in range(0, 16) {
-            v.push(i);
-        }
-
-        assert!(v.capacity() >= 16);
-        v.reserve_additional(16);
-        assert!(v.capacity() >= 32);
-
-        v.push(16);
-
-        v.reserve_additional(16);
-        assert!(v.capacity() >= 33)
-    }
-
-    #[test]
-    fn test_extend() {
-        let mut v = Vec::new();
-        let mut w = Vec::new();
-
-        v.extend(&mut range(0, 3));
-        for i in range(0, 3) { w.push(i) }
-
-        assert_eq!(v, w);
-
-        v.extend(&mut range(3, 10));
-        for i in range(3, 10) { w.push(i) }
-
-        assert_eq!(v, w);
-    }
-}
diff --git a/src/libsync/arc.rs b/src/libsync/arc.rs
index faa7a9de542..71adab71734 100644
--- a/src/libsync/arc.rs
+++ b/src/libsync/arc.rs
@@ -21,11 +21,11 @@
  * extern crate sync;
  * extern crate rand;
  *
- * use std::vec;
+ * use std::slice;
  * use sync::Arc;
  *
  * fn main() {
- *     let numbers = vec::from_fn(100, |i| (i as f32) * rand::random());
+ *     let numbers = slice::from_fn(100, |i| (i as f32) * rand::random());
  *     let shared_numbers = Arc::new(numbers);
  *
  *     for _ in range(0, 10) {
@@ -54,6 +54,9 @@ use std::kinds::marker;
 use std::sync::arc::UnsafeArc;
 use std::task;
 
+#[cfg(stage0)]
+use std::kinds::Share;
+
 /// As sync::condvar, a mechanism for unlock-and-descheduling and
 /// signaling, for use with the Arc types.
 pub struct ArcCondvar<'a> {
@@ -122,7 +125,7 @@ pub struct Arc<T> { priv x: UnsafeArc<T> }
  * Access the underlying data in an atomically reference counted
  * wrapper.
  */
-impl<T:Freeze+Send> Arc<T> {
+impl<T: Share + Send> Arc<T> {
     /// Create an atomically reference counted wrapper.
     #[inline]
     pub fn new(data: T) -> Arc<T> {
@@ -135,7 +138,7 @@ impl<T:Freeze+Send> Arc<T> {
     }
 }
 
-impl<T:Freeze + Send> Clone for Arc<T> {
+impl<T: Share + Send> Clone for Arc<T> {
     /**
     * Duplicate an atomically reference counted wrapper.
     *
@@ -295,19 +298,21 @@ struct RWArcInner<T> { lock: RWLock, failed: bool, data: T }
 pub struct RWArc<T> {
     priv x: UnsafeArc<RWArcInner<T>>,
     priv marker: marker::NoFreeze,
+    priv marker1: marker::NoShare,
 }
 
-impl<T:Freeze + Send> Clone for RWArc<T> {
+impl<T: Share + Send> Clone for RWArc<T> {
     /// Duplicate a rwlock-protected Arc. See arc::clone for more details.
     #[inline]
     fn clone(&self) -> RWArc<T> {
         RWArc { x: self.x.clone(),
-                marker: marker::NoFreeze, }
+                marker: marker::NoFreeze,
+                marker1: marker::NoShare, }
     }
 
 }
 
-impl<T:Freeze + Send> RWArc<T> {
+impl<T: Share + Send> RWArc<T> {
     /// Create a reader/writer Arc with the supplied data.
     pub fn new(user_data: T) -> RWArc<T> {
         RWArc::new_with_condvars(user_data, 1)
@@ -323,7 +328,8 @@ impl<T:Freeze + Send> RWArc<T> {
             failed: false, data: user_data
         };
         RWArc { x: UnsafeArc::new(data),
-                marker: marker::NoFreeze, }
+                marker: marker::NoFreeze,
+                marker1: marker::NoShare, }
     }
 
     /**
@@ -454,7 +460,7 @@ impl<T:Freeze + Send> RWArc<T> {
 // lock it. This wraps the unsafety, with the justification that the 'lock'
 // field is never overwritten; only 'failed' and 'data'.
 #[doc(hidden)]
-fn borrow_rwlock<T:Freeze + Send>(state: *mut RWArcInner<T>) -> *RWLock {
+fn borrow_rwlock<T: Share + Send>(state: *mut RWArcInner<T>) -> *RWLock {
     unsafe { cast::transmute(&(*state).lock) }
 }
 
@@ -471,7 +477,7 @@ pub struct RWReadMode<'a, T> {
     priv token: sync::RWLockReadMode<'a>,
 }
 
-impl<'a, T:Freeze + Send> RWWriteMode<'a, T> {
+impl<'a, T: Share + Send> RWWriteMode<'a, T> {
     /// Access the pre-downgrade RWArc in write mode.
     pub fn write<U>(&mut self, blk: |x: &mut T| -> U) -> U {
         match *self {
@@ -510,7 +516,7 @@ impl<'a, T:Freeze + Send> RWWriteMode<'a, T> {
     }
 }
 
-impl<'a, T:Freeze + Send> RWReadMode<'a, T> {
+impl<'a, T: Share + Send> RWReadMode<'a, T> {
     /// Access the post-downgrade rwlock in read mode.
     pub fn read<U>(&self, blk: |x: &T| -> U) -> U {
         match *self {
@@ -534,7 +540,7 @@ pub struct CowArc<T> { priv x: UnsafeArc<T> }
 /// mutation of the contents if there is only a single reference to
 /// the data. If there are multiple references the data is automatically
 /// cloned and the task modifies the cloned data in place of the shared data.
-impl<T:Clone+Send+Freeze> CowArc<T> {
+impl<T: Clone + Send + Share> CowArc<T> {
     /// Create a copy-on-write atomically reference counted wrapper
     #[inline]
     pub fn new(data: T) -> CowArc<T> {
@@ -558,7 +564,7 @@ impl<T:Clone+Send+Freeze> CowArc<T> {
     }
 }
 
-impl<T:Clone+Send+Freeze> Clone for CowArc<T> {
+impl<T: Clone + Send + Share> Clone for CowArc<T> {
     /// Duplicate a Copy-on-write Arc. See arc::clone for more details.
     fn clone(&self) -> CowArc<T> {
         CowArc { x: self.x.clone() }
diff --git a/src/libsync/task_pool.rs b/src/libsync/task_pool.rs
index 93487827200..7670e9cf50a 100644
--- a/src/libsync/task_pool.rs
+++ b/src/libsync/task_pool.rs
@@ -13,9 +13,8 @@
 /// A task pool abstraction. Useful for achieving predictable CPU
 /// parallelism.
 
-
 use std::task;
-use std::vec;
+use std::slice;
 
 enum Msg<T> {
     Execute(proc(&T)),
@@ -47,7 +46,7 @@ impl<T> TaskPool<T> {
                -> TaskPool<T> {
         assert!(n_tasks >= 1);
 
-        let channels = vec::from_fn(n_tasks, |i| {
+        let channels = slice::from_fn(n_tasks, |i| {
             let (tx, rx) = channel::<Msg<T>>();
             let init_fn = init_fn_factory();
 
diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs
index a06415bc083..0547b374edb 100644
--- a/src/libsyntax/abi.rs
+++ b/src/libsyntax/abi.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use std::fmt;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use std::fmt::Show;
 
 #[deriving(Eq)]
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 4ef46573e23..fce9ddcc2ee 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -21,7 +21,7 @@ use std::fmt;
 use std::fmt::Show;
 use std::option::Option;
 use std::rc::Rc;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
 /// A pointer abstraction. FIXME(eddyb) #10676 use Rc<T> in the future.
@@ -520,7 +520,7 @@ pub enum Expr_ {
     ExprIndex(@Expr, @Expr),
 
     /// Expression that looks like a "name". For example,
-    /// `std::vec::from_elem::<uint>` is an ExprPath that's the "name" part
+    /// `std::slice::from_elem::<uint>` is an ExprPath that's the "name" part
     /// of a function call.
     ExprPath(Path),
 
@@ -1157,15 +1157,7 @@ mod test {
     use codemap::*;
     use super::*;
 
-    use std::vec_ng::Vec;
-
-    fn is_freeze<T: Freeze>() {}
-
-    // Assert that the AST remains Freeze (#10693).
-    #[test]
-    fn ast_is_freeze() {
-        is_freeze::<Item>();
-    }
+    use std::vec::Vec;
 
     // are ASTs encodable?
     #[test]
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index f7983933990..d1b13d93856 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -20,9 +20,9 @@ use util::small_vector::SmallVector;
 
 use std::cell::RefCell;
 use std::iter;
-use std::vec;
+use std::slice;
 use std::fmt;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 #[deriving(Clone, Eq)]
 pub enum PathElem {
@@ -65,9 +65,9 @@ impl<'a> Iterator<PathElem> for LinkedPath<'a> {
     }
 }
 
-// HACK(eddyb) move this into libstd (value wrapper for vec::Items).
+// HACK(eddyb) move this into libstd (value wrapper for slice::Items).
 #[deriving(Clone)]
-pub struct Values<'a, T>(vec::Items<'a, T>);
+pub struct Values<'a, T>(slice::Items<'a, T>);
 
 impl<'a, T: Pod> Iterator<T> for Values<'a, T> {
     fn next(&mut self) -> Option<T> {
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index da6278aaae9..b75a49b2097 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -22,7 +22,7 @@ use visit;
 use std::cell::Cell;
 use std::cmp;
 use std::u32;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn path_name_i(idents: &[Ident]) -> ~str {
     // FIXME: Bad copies (#2543 -- same for everything else that says "bad")
@@ -711,7 +711,7 @@ mod test {
     use ast::*;
     use super::*;
     use opt_vec;
-    use std::vec_ng::Vec;
+    use std::vec::Vec;
 
     fn ident_to_segment(id : &Ident) -> PathSegment {
         PathSegment {identifier:id.clone(),
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index 65a0f473db2..8c6079b4d1a 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -21,7 +21,7 @@ use parse::token;
 use crateid::CrateId;
 
 use collections::HashSet;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub trait AttrMetaMethods {
     // This could be changed to `fn check_name(&self, name: InternedString) ->
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index d93b5803eac..a52fbbe0c50 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -24,7 +24,7 @@ source code snippets, etc.
 use std::cell::RefCell;
 use std::cmp;
 use std::rc::Rc;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
 pub trait Pos {
diff --git a/src/libsyntax/crateid.rs b/src/libsyntax/crateid.rs
index e5136b7081b..20463612886 100644
--- a/src/libsyntax/crateid.rs
+++ b/src/libsyntax/crateid.rs
@@ -19,7 +19,7 @@ use std::fmt;
 /// to be `0.0`.
 
 use std::from_str::FromStr;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 #[deriving(Clone, Eq)]
 pub struct CrateId {
diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs
index 8c1e27d8b01..b8a4b6d34f4 100644
--- a/src/libsyntax/ext/asm.rs
+++ b/src/libsyntax/ext/asm.rs
@@ -20,7 +20,7 @@ use parse;
 use parse::token::InternedString;
 use parse::token;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 enum State {
     Asm,
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index df2c265e6eb..e456b62e5e7 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -20,7 +20,7 @@ use parse::token::{InternedString, intern, str_to_ident};
 use util::small_vector::SmallVector;
 
 use collections::HashMap;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 // new-style macro! tt code:
 //
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 7c42476bc01..7cf27e81ca0 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -21,7 +21,7 @@ use opt_vec::OptVec;
 use parse::token::special_idents;
 use parse::token;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub struct Field {
     ident: ast::Ident,
@@ -585,7 +585,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     fn expr_vec_ng(&self, sp: Span) -> @ast::Expr {
         self.expr_call_global(sp,
                               vec!(self.ident_of("std"),
-                                   self.ident_of("vec_ng"),
+                                   self.ident_of("vec"),
                                    self.ident_of("Vec"),
                                    self.ident_of("new")),
                               Vec::new())
diff --git a/src/libsyntax/ext/bytes.rs b/src/libsyntax/ext/bytes.rs
index 6123fd4d3d4..174f36146aa 100644
--- a/src/libsyntax/ext/bytes.rs
+++ b/src/libsyntax/ext/bytes.rs
@@ -17,7 +17,7 @@ use ext::base;
 use ext::build::AstBuilder;
 
 use std::char;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> base::MacResult {
     // Gather all argument expressions
diff --git a/src/libsyntax/ext/cfg.rs b/src/libsyntax/ext/cfg.rs
index 5d11a0d1e2f..e885119118c 100644
--- a/src/libsyntax/ext/cfg.rs
+++ b/src/libsyntax/ext/cfg.rs
@@ -26,7 +26,7 @@ use parse::token::InternedString;
 use parse::token;
 use parse;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_cfg(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) -> base::MacResult {
     let mut p = parse::new_parser_from_tts(cx.parse_sess(),
diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs
index ee3adb7aad8..2aeda30695e 100644
--- a/src/libsyntax/ext/concat_idents.rs
+++ b/src/libsyntax/ext/concat_idents.rs
@@ -15,7 +15,7 @@ use ext::base;
 use opt_vec;
 use parse::token;
 use parse::token::{str_to_ident};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     -> base::MacResult {
diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs
index e63363c608b..a0aa1bb3710 100644
--- a/src/libsyntax/ext/deriving/clone.rs
+++ b/src/libsyntax/ext/deriving/clone.rs
@@ -14,7 +14,7 @@ use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_deriving_clone(cx: &mut ExtCtxt,
                              span: Span,
diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs
index 1e7199ccc95..80e56f0e407 100644
--- a/src/libsyntax/ext/deriving/cmp/eq.rs
+++ b/src/libsyntax/ext/deriving/cmp/eq.rs
@@ -14,7 +14,7 @@ use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_deriving_eq(cx: &mut ExtCtxt,
                           span: Span,
diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs
index 66f45988239..caad6772b19 100644
--- a/src/libsyntax/ext/deriving/cmp/ord.rs
+++ b/src/libsyntax/ext/deriving/cmp/ord.rs
@@ -15,7 +15,7 @@ use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_deriving_ord(cx: &mut ExtCtxt,
                            span: Span,
diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs
index 2b3c0b9ea69..3292246bf0b 100644
--- a/src/libsyntax/ext/deriving/cmp/totaleq.rs
+++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs
@@ -14,7 +14,7 @@ use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_deriving_totaleq(cx: &mut ExtCtxt,
                                span: Span,
diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs
index 89a344bdb7b..d8c2eea9896 100644
--- a/src/libsyntax/ext/deriving/cmp/totalord.rs
+++ b/src/libsyntax/ext/deriving/cmp/totalord.rs
@@ -16,7 +16,7 @@ use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 
 use std::cmp::{Ordering, Equal, Less, Greater};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_deriving_totalord(cx: &mut ExtCtxt,
                                 span: Span,
diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs
index bc6d69c7cca..e5e11ce878c 100644
--- a/src/libsyntax/ext/deriving/decodable.rs
+++ b/src/libsyntax/ext/deriving/decodable.rs
@@ -21,7 +21,7 @@ use ext::deriving::generic::*;
 use parse::token::InternedString;
 use parse::token;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_deriving_decodable(cx: &mut ExtCtxt,
                                  span: Span,
diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs
index 8259459f57a..2015aa99717 100644
--- a/src/libsyntax/ext/deriving/default.rs
+++ b/src/libsyntax/ext/deriving/default.rs
@@ -14,7 +14,7 @@ use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_deriving_default(cx: &mut ExtCtxt,
                             span: Span,
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index 091ff7b9c90..0550e64bef8 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -89,7 +89,7 @@ use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use parse::token;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
                                  span: Span,
diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs
index d24bb2802c6..dce777aaaae 100644
--- a/src/libsyntax/ext/deriving/generic.rs
+++ b/src/libsyntax/ext/deriving/generic.rs
@@ -187,8 +187,8 @@ use codemap::Span;
 use opt_vec;
 use parse::token::InternedString;
 
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 
 pub use self::ty::*;
 mod ty;
@@ -407,7 +407,7 @@ impl<'a> TraitDef<'a> {
         cx.item(
             self.span,
             ident,
-            vec_ng::append(vec!(attr), self.attributes.as_slice()),
+            vec::append(vec!(attr), self.attributes.as_slice()),
             ast::ItemImpl(trait_generics, opt_trait_ref,
                           self_type, methods.map(|x| *x)))
     }
diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs
index a94feee9d37..366647cc371 100644
--- a/src/libsyntax/ext/deriving/hash.rs
+++ b/src/libsyntax/ext/deriving/hash.rs
@@ -14,7 +14,7 @@ use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_deriving_hash(cx: &mut ExtCtxt,
                             span: Span,
diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs
index 190f009103f..35c1437a176 100644
--- a/src/libsyntax/ext/deriving/primitive.rs
+++ b/src/libsyntax/ext/deriving/primitive.rs
@@ -16,7 +16,7 @@ use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 use parse::token::InternedString;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_deriving_from_primitive(cx: &mut ExtCtxt,
                                       span: Span,
diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs
index b8ef9d98b29..4ae140406c3 100644
--- a/src/libsyntax/ext/deriving/rand.rs
+++ b/src/libsyntax/ext/deriving/rand.rs
@@ -15,7 +15,7 @@ use ext::base::ExtCtxt;
 use ext::build::{AstBuilder};
 use ext::deriving::generic::*;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_deriving_rand(cx: &mut ExtCtxt,
                             span: Span,
diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs
index 51399d8efab..d86fff5a4aa 100644
--- a/src/libsyntax/ext/deriving/show.rs
+++ b/src/libsyntax/ext/deriving/show.rs
@@ -19,7 +19,7 @@ use ext::deriving::generic::*;
 use parse::token;
 
 use collections::HashMap;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_deriving_show(cx: &mut ExtCtxt,
                             span: Span,
diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs
index 60166f30f1e..22d91956552 100644
--- a/src/libsyntax/ext/deriving/ty.rs
+++ b/src/libsyntax/ext/deriving/ty.rs
@@ -20,7 +20,7 @@ use ext::build::AstBuilder;
 use codemap::{Span,respan};
 use opt_vec;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 /// The types of pointers
 pub enum PtrTy<'a> {
diff --git a/src/libsyntax/ext/deriving/zero.rs b/src/libsyntax/ext/deriving/zero.rs
index 98c0ec9d072..d788bafc9b2 100644
--- a/src/libsyntax/ext/deriving/zero.rs
+++ b/src/libsyntax/ext/deriving/zero.rs
@@ -14,7 +14,7 @@ use ext::base::ExtCtxt;
 use ext::build::AstBuilder;
 use ext::deriving::generic::*;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_deriving_zero(cx: &mut ExtCtxt,
                             span: Span,
diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs
index 0c7b92d0373..bb9e5afaed4 100644
--- a/src/libsyntax/ext/env.rs
+++ b/src/libsyntax/ext/env.rs
@@ -22,7 +22,7 @@ use ext::build::AstBuilder;
 use parse::token;
 
 use std::os;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_option_env(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     -> base::MacResult {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 49058917e30..4134b23125e 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -32,7 +32,7 @@ use util::small_vector::SmallVector;
 use std::cast;
 use std::unstable::dynamic_lib::DynamicLibrary;
 use std::os;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr {
     match e.node {
@@ -979,7 +979,7 @@ mod test {
     use visit;
     use visit::Visitor;
 
-    use std::vec_ng::Vec;
+    use std::vec::Vec;
 
     // a visitor that extracts the paths
     // from a given thingy and puts them in a mutable
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs
index e79e584ed5c..743fe798480 100644
--- a/src/libsyntax/ext/format.rs
+++ b/src/libsyntax/ext/format.rs
@@ -20,8 +20,8 @@ use rsparse = parse;
 
 use std::fmt::parse;
 use collections::{HashMap, HashSet};
-use std::vec;
-use std::vec_ng::Vec;
+use std::slice;
+use std::vec::Vec;
 
 #[deriving(Eq)]
 enum ArgumentType {
@@ -610,7 +610,7 @@ impl<'a, 'b> Context<'a, 'b> {
     fn to_expr(&self, extra: @ast::Expr) -> @ast::Expr {
         let mut lets = Vec::new();
         let mut locals = Vec::new();
-        let mut names = vec::from_fn(self.name_positions.len(), |_| None);
+        let mut names = slice::from_fn(self.name_positions.len(), |_| None);
         let mut pats = Vec::new();
         let mut heads = Vec::new();
 
diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs
index 4d96dd75990..ab5f3fbf3a6 100644
--- a/src/libsyntax/ext/mtwt.rs
+++ b/src/libsyntax/ext/mtwt.rs
@@ -20,7 +20,7 @@ use ast::{Ident, Mrk, Name, SyntaxContext};
 use std::cell::RefCell;
 use std::local_data;
 use std::rc::Rc;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 use collections::HashMap;
 
@@ -126,6 +126,15 @@ pub fn display_sctable(table: &SCTable) {
     }
 }
 
+/// Clear the tables from TLD to reclaim memory.
+pub fn clear_tables() {
+    with_sctable(|table| {
+        *table.table.borrow_mut().get() = Vec::new();
+        *table.mark_memo.borrow_mut().get() = HashMap::new();
+        *table.rename_memo.borrow_mut().get() = HashMap::new();
+    });
+    with_resolve_table_mut(|table| *table = HashMap::new());
+}
 
 // Add a value to the end of a vec, return its index
 fn idx_push<T>(vec: &mut Vec<T> , val: T) -> u32 {
@@ -272,7 +281,7 @@ mod tests {
     use super::{resolve, xorPush, new_mark_internal, new_sctable_internal};
     use super::{new_rename_internal, marksof_internal, resolve_internal};
     use super::{SCTable, EmptyCtxt, Mark, Rename, IllegalCtxt};
-    use std::vec_ng::Vec;
+    use std::vec::Vec;
     use collections::HashMap;
 
     #[test] fn xorpush_test () {
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index e96597d4159..5b66184b16c 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -17,7 +17,7 @@ use parse::token::*;
 use parse::token;
 use parse;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 /**
 *
@@ -37,7 +37,7 @@ pub mod rt {
     use parse;
     use print::pprust;
 
-    use std::vec_ng::Vec;
+    use std::vec::Vec;
 
     pub use ast::*;
     pub use parse::token::*;
diff --git a/src/libsyntax/ext/registrar.rs b/src/libsyntax/ext/registrar.rs
index d8bf726da79..db59388e24f 100644
--- a/src/libsyntax/ext/registrar.rs
+++ b/src/libsyntax/ext/registrar.rs
@@ -15,7 +15,7 @@ use diagnostic;
 use visit;
 use visit::Visitor;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 struct MacroRegistrarContext {
     registrars: Vec<(ast::NodeId, Span)> ,
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index 698bde4578c..f5c29840e48 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -22,7 +22,7 @@ use parse::token::{Token, EOF, Nonterminal};
 use parse::token;
 
 use collections::HashMap;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 /* This is an Earley-like parser, without support for in-grammar nonterminals,
 only by calling out to the main rust parser for named nonterminals (which it
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 3f4ed0b1e8e..d283d6d7142 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -28,7 +28,7 @@ use print;
 use util::small_vector::SmallVector;
 
 use std::cell::RefCell;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 struct ParserAnyMacro<'a> {
     parser: RefCell<Parser<'a>>,
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index e120f07742e..19af4eed4c3 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -18,7 +18,7 @@ use parse::token;
 use parse::lexer::TokenAndSpan;
 
 use std::cell::{Cell, RefCell};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 use collections::HashMap;
 
 ///an unzipping of `TokenTree`s
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index d9510ddad4b..a54c3b6af01 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -16,7 +16,7 @@ use parse::token;
 use opt_vec::OptVec;
 use util::small_vector::SmallVector;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 // We may eventually want to be able to fold over type parameters, too.
 pub trait Folder {
diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs
index ec81fff51c7..55261fd3267 100644
--- a/src/libsyntax/opt_vec.rs
+++ b/src/libsyntax/opt_vec.rs
@@ -16,8 +16,8 @@
  */
 
 use std::default::Default;
-use std::vec;
-use std::vec_ng::Vec;
+use std::slice;
+use std::vec::Vec;
 
 #[deriving(Clone, Encodable, Decodable, Hash)]
 pub enum OptVec<T> {
@@ -176,7 +176,7 @@ impl<T> Default for OptVec<T> {
 }
 
 pub struct Items<'a, T> {
-    priv iter: Option<vec::Items<'a, T>>
+    priv iter: Option<slice::Items<'a, T>>
 }
 
 impl<'a, T> Iterator<&'a T> for Items<'a, T> {
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index 399648ef1d8..e86f6f5be81 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -15,7 +15,7 @@ use parse::token;
 use parse::parser::Parser;
 use parse::token::INTERPOLATED;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 // a parser that can parse attributes.
 pub trait ParserAttr {
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index ed74fd416d1..9bc0fdd3078 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -20,7 +20,7 @@ use parse::token;
 use std::io;
 use std::str;
 use std::uint;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 #[deriving(Clone, Eq)]
 pub enum CommentStyle {
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index 546aefc1297..c34ef465dad 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -1005,7 +1005,7 @@ mod test {
     use parse::token;
     use parse::token::{str_to_ident};
     use std::io::util;
-    use std::vec_ng::Vec;
+    use std::vec::Vec;
 
     fn mk_sh() -> diagnostic::SpanHandler {
         let emitter = diagnostic::EmitterWriter::new(~util::NullWriter);
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 062bc100863..7e8ca77eb04 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -21,7 +21,7 @@ use std::cell::RefCell;
 use std::io::File;
 use std::rc::Rc;
 use std::str;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub mod lexer;
 pub mod parser;
@@ -279,7 +279,7 @@ mod test {
     use std::io;
     use std::io::MemWriter;
     use std::str;
-    use std::vec_ng::Vec;
+    use std::vec::Vec;
     use codemap::{Span, BytePos, Spanned};
     use opt_vec;
     use ast;
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index e1a02d5240f..0ded6abe146 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -82,8 +82,8 @@ use std::cell::Cell;
 use collections::HashSet;
 use std::kinds::marker;
 use std::mem::replace;
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 
 #[allow(non_camel_case_types)]
 #[deriving(Eq)]
@@ -271,7 +271,7 @@ fn maybe_append(lhs: Vec<Attribute> , rhs: Option<Vec<Attribute> >)
              -> Vec<Attribute> {
     match rhs {
         None => lhs,
-        Some(ref attrs) => vec_ng::append(lhs, attrs.as_slice())
+        Some(ref attrs) => vec::append(lhs, attrs.as_slice())
     }
 }
 
@@ -407,7 +407,7 @@ impl<'a> Parser<'a> {
         } else if inedible.contains(&self.token) {
             // leave it in the input
         } else {
-            let expected = vec_ng::append(edible.iter()
+            let expected = vec::append(edible.iter()
                                                 .map(|x| (*x).clone())
                                                 .collect(),
                                           inedible);
@@ -449,7 +449,7 @@ impl<'a> Parser<'a> {
         match e.node {
             ExprPath(..) => {
                 // might be unit-struct construction; check for recoverableinput error.
-                let expected = vec_ng::append(edible.iter()
+                let expected = vec::append(edible.iter()
                                                     .map(|x| (*x).clone())
                                                     .collect(),
                                               inedible);
@@ -472,7 +472,7 @@ impl<'a> Parser<'a> {
         debug!("commit_stmt {:?}", s);
         let _s = s; // unused, but future checks might want to inspect `s`.
         if self.last_token.as_ref().map_or(false, |t| is_ident_or_path(*t)) {
-            let expected = vec_ng::append(edible.iter()
+            let expected = vec::append(edible.iter()
                                                 .map(|x| (*x).clone())
                                                 .collect(),
                                           inedible.as_slice());
@@ -1113,7 +1113,7 @@ impl<'a> Parser<'a> {
                 debug!("parse_trait_methods(): parsing provided method");
                 let (inner_attrs, body) =
                     p.parse_inner_attrs_and_block();
-                let attrs = vec_ng::append(attrs, inner_attrs.as_slice());
+                let attrs = vec::append(attrs, inner_attrs.as_slice());
                 Provided(@ast::Method {
                     ident: ident,
                     attrs: attrs,
@@ -2781,7 +2781,6 @@ impl<'a> Parser<'a> {
                 break;
             }
 
-            let lo1 = self.last_span.lo;
             let bind_type = if self.eat_keyword(keywords::Mut) {
                 BindByValue(MutMutable)
             } else if self.eat_keyword(keywords::Ref) {
@@ -2791,11 +2790,8 @@ impl<'a> Parser<'a> {
             };
 
             let fieldname = self.parse_ident();
-            let hi1 = self.last_span.lo;
-            let fieldpath = ast_util::ident_to_path(mk_sp(lo1, hi1),
-                                                    fieldname);
-            let subpat;
-            if self.token == token::COLON {
+
+            let subpat = if self.token == token::COLON {
                 match bind_type {
                     BindByRef(..) | BindByValue(MutMutable) => {
                         let token_str = self.this_token_to_str();
@@ -2805,14 +2801,16 @@ impl<'a> Parser<'a> {
                 }
 
                 self.bump();
-                subpat = self.parse_pat();
+                self.parse_pat()
             } else {
-                subpat = @ast::Pat {
+                let fieldpath = ast_util::ident_to_path(self.last_span,
+                                                        fieldname);
+                @ast::Pat {
                     id: ast::DUMMY_NODE_ID,
                     node: PatIdent(bind_type, fieldpath, None),
                     span: self.last_span
-                };
-            }
+                }
+            };
             fields.push(ast::FieldPat { ident: fieldname, pat: subpat });
         }
         return (fields, etc);
@@ -3854,7 +3852,7 @@ impl<'a> Parser<'a> {
 
         let (inner_attrs, body) = self.parse_inner_attrs_and_block();
         let hi = body.span.hi;
-        let attrs = vec_ng::append(attrs, inner_attrs.as_slice());
+        let attrs = vec::append(attrs, inner_attrs.as_slice());
         @ast::Method {
             ident: ident,
             attrs: attrs,
@@ -4086,7 +4084,7 @@ impl<'a> Parser<'a> {
         while self.token != term {
             let mut attrs = self.parse_outer_attributes();
             if first {
-                attrs = vec_ng::append(attrs_remaining.clone(),
+                attrs = vec::append(attrs_remaining.clone(),
                                        attrs.as_slice());
                 first = false;
             }
@@ -4236,7 +4234,7 @@ impl<'a> Parser<'a> {
                                      &path,
                                      id_sp);
         let (inner, next) = p0.parse_inner_attrs_and_next();
-        let mod_attrs = vec_ng::append(outer_attrs, inner.as_slice());
+        let mod_attrs = vec::append(outer_attrs, inner.as_slice());
         let first_item_outer_attrs = next;
         let m0 = p0.parse_mod_items(token::EOF, first_item_outer_attrs);
         {
@@ -4561,7 +4559,7 @@ impl<'a> Parser<'a> {
         match self.token {
             INTERPOLATED(token::NtItem(item)) => {
                 self.bump();
-                let new_attrs = vec_ng::append(attrs, item.attrs.as_slice());
+                let new_attrs = vec::append(attrs, item.attrs.as_slice());
                 return IoviItem(@Item {
                     attrs: new_attrs,
                     ..(*item).clone()
@@ -4989,7 +4987,7 @@ impl<'a> Parser<'a> {
                                   mut extern_mod_allowed: bool,
                                   macros_allowed: bool)
                                   -> ParsedItemsAndViewItems {
-        let mut attrs = vec_ng::append(first_item_attrs,
+        let mut attrs = vec::append(first_item_attrs,
                                        self.parse_outer_attributes()
                                            .as_slice());
         // First, parse view items.
@@ -5071,7 +5069,7 @@ impl<'a> Parser<'a> {
     fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute> ,
                            macros_allowed: bool)
         -> ParsedItemsAndViewItems {
-        let mut attrs = vec_ng::append(first_item_attrs,
+        let mut attrs = vec::append(first_item_attrs,
                                        self.parse_outer_attributes()
                                            .as_slice());
         let mut foreign_items = Vec::new();
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index efadea16fe2..43d686dc6cb 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -22,7 +22,7 @@ use std::char;
 use std::fmt;
 use std::local_data;
 use std::path::BytesContainer;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 #[allow(non_camel_case_types)]
 #[deriving(Clone, Encodable, Decodable, Eq, Hash, Show)]
diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs
index 5540b26d9e7..c588e407e30 100644
--- a/src/libsyntax/print/pp.rs
+++ b/src/libsyntax/print/pp.rs
@@ -62,7 +62,7 @@
  */
 
 use std::io;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 #[deriving(Clone, Eq)]
 pub enum Breaks {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 2f96a71cc0f..5c23dd163d1 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -32,7 +32,7 @@ use std::char;
 use std::str;
 use std::io;
 use std::io::{IoResult, MemWriter};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 // The &mut State is stored here to prevent recursive type.
 pub enum AnnNode<'a> {
@@ -2392,7 +2392,7 @@ mod test {
     use codemap;
     use parse::token;
 
-    use std::vec_ng::Vec;
+    use std::vec::Vec;
 
     #[test]
     fn test_fun_to_str() {
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs
index 969c7cec87c..0406f5f5ba9 100644
--- a/src/libsyntax/util/interner.rs
+++ b/src/libsyntax/util/interner.rs
@@ -21,7 +21,7 @@ use std::cmp::Equiv;
 use std::fmt;
 use std::hash::Hash;
 use std::rc::Rc;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 pub struct Interner<T> {
     priv map: RefCell<HashMap<T, Name>>,
@@ -29,7 +29,7 @@ pub struct Interner<T> {
 }
 
 // when traits can extend traits, we should extend index<Name,T> to get []
-impl<T:Eq + Hash + Freeze + Clone + 'static> Interner<T> {
+impl<T: Eq + Hash + Clone + 'static> Interner<T> {
     pub fn new() -> Interner<T> {
         Interner {
             map: RefCell::new(HashMap::new()),
@@ -84,6 +84,11 @@ impl<T:Eq + Hash + Freeze + Clone + 'static> Interner<T> {
             None => None,
         }
     }
+
+    pub fn clear(&self) {
+        *self.map.borrow_mut().get() = HashMap::new();
+        *self.vect.borrow_mut().get() = Vec::new();
+    }
 }
 
 #[deriving(Clone, Eq, Hash, Ord)]
@@ -222,6 +227,11 @@ impl StrInterner {
             None => None,
         }
     }
+
+    pub fn clear(&self) {
+        *self.map.borrow_mut().get() = HashMap::new();
+        *self.vect.borrow_mut().get() = Vec::new();
+    }
 }
 
 #[cfg(test)]
diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs
index 658e9709750..13590542dac 100644
--- a/src/libsyntax/util/parser_testing.rs
+++ b/src/libsyntax/util/parser_testing.rs
@@ -15,7 +15,7 @@ use parse::{new_parser_from_source_str};
 use parse::parser::Parser;
 use parse::token;
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 // map a string to tts, using a made-up filename:
 pub fn string_to_tts(source_str: ~str) -> Vec<ast::TokenTree> {
diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs
index f15b7dd5563..72faaee64ff 100644
--- a/src/libsyntax/util/small_vector.rs
+++ b/src/libsyntax/util/small_vector.rs
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 use std::mem;
-use std::vec_ng::Vec;
-use std::vec_ng;
+use std::vec::Vec;
+use std::vec;
 
 /// A vector type optimized for cases where the size is almost always 0 or 1
 pub enum SmallVector<T> {
@@ -114,7 +114,7 @@ impl<T> SmallVector<T> {
 pub enum MoveItems<T> {
     priv ZeroIterator,
     priv OneIterator(T),
-    priv ManyIterator(vec_ng::MoveItems<T>),
+    priv ManyIterator(vec::MoveItems<T>),
 }
 
 impl<T> Iterator<T> for MoveItems<T> {
@@ -146,7 +146,7 @@ impl<T> Iterator<T> for MoveItems<T> {
 mod test {
     use super::*;
 
-    use std::vec_ng::Vec;
+    use std::vec::Vec;
 
     #[test]
     fn test_len() {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 880fce58083..408c9d635b6 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -15,7 +15,7 @@ use codemap::Span;
 use parse;
 use opt_vec;
 use opt_vec::OptVec;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 // Context-passing AST walker. Each overridden visit method has full control
 // over what happens with its node, it can do its own traversal of the node's
diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs
index dfb6d6b1a88..ee14b90fbfd 100644
--- a/src/libterm/terminfo/parm.rs
+++ b/src/libterm/terminfo/parm.rs
@@ -10,7 +10,7 @@
 
 //! Parameterized string expansion
 
-use std::{char, vec};
+use std::{char, slice};
 use std::mem::replace;
 
 #[deriving(Eq)]
@@ -93,7 +93,7 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
     let mut state = Nothing;
 
     // expanded cap will only rarely be larger than the cap itself
-    let mut output = vec::with_capacity(cap.len());
+    let mut output = slice::with_capacity(cap.len());
 
     let mut stack: ~[Param] = ~[];
 
@@ -488,7 +488,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<~[u8],~str> {
                 (FormatString, _)    => return Err(~"non-number on stack with %s"),
             };
             if flags.precision > s.len() {
-                let mut s_ = vec::with_capacity(flags.precision);
+                let mut s_ = slice::with_capacity(flags.precision);
                 let n = flags.precision - s.len();
                 s_.grow(n, &('0' as u8));
                 s_.push_all_move(s);
@@ -543,7 +543,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<~[u8],~str> {
         if flags.left {
             s.grow(n, &(' ' as u8));
         } else {
-            let mut s_ = vec::with_capacity(flags.width);
+            let mut s_ = slice::with_capacity(flags.width);
             s_.grow(n, &(' ' as u8));
             s_.push_all_move(s);
             s = s_;
diff --git a/src/libterm/terminfo/parser/compiled.rs b/src/libterm/terminfo/parser/compiled.rs
index 8ba3ad53121..cc97e54709c 100644
--- a/src/libterm/terminfo/parser/compiled.rs
+++ b/src/libterm/terminfo/parser/compiled.rs
@@ -13,7 +13,7 @@
 /// ncurses-compatible compiled terminfo format parsing (term(5))
 
 
-use std::{vec, str};
+use std::{slice, str};
 use std::io;
 use collections::HashMap;
 use super::super::TermInfo;
@@ -246,7 +246,7 @@ pub fn parse(file: &mut io::Reader,
     let mut string_map = HashMap::new();
 
     if string_offsets_count != 0 {
-        let mut string_offsets = vec::with_capacity(10);
+        let mut string_offsets = slice::with_capacity(10);
         for _ in range(0, string_offsets_count) {
             string_offsets.push(try!(file.read_le_u16()));
         }
diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs
index b3fd06bd6ad..120b790d467 100644
--- a/src/libtest/stats.rs
+++ b/src/libtest/stats.rs
@@ -1035,7 +1035,7 @@ mod tests {
 #[cfg(test)]
 mod bench {
     use BenchHarness;
-    use std::vec;
+    use std::slice;
     use stats::Stats;
 
     #[bench]
@@ -1047,7 +1047,7 @@ mod bench {
     #[bench]
     pub fn sum_many_f64(bh: &mut BenchHarness) {
         let nums = [-1e30, 1e60, 1e30, 1.0, -1e60];
-        let v = vec::from_fn(500, |i| nums[i%5]);
+        let v = slice::from_fn(500, |i| nums[i%5]);
 
         bh.iter(|| {
             v.sum();
diff --git a/src/liburl/lib.rs b/src/liburl/lib.rs
index 067479753ea..9a24e8ecfa9 100644
--- a/src/liburl/lib.rs
+++ b/src/liburl/lib.rs
@@ -28,7 +28,7 @@ use std::hash::Hash;
 use std::io::BufReader;
 use std::from_str::FromStr;
 use std::uint;
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 use collections::HashMap;
 
diff --git a/src/libuuid/lib.rs b/src/libuuid/lib.rs
index 98c5f413973..7aed4cd3d9b 100644
--- a/src/libuuid/lib.rs
+++ b/src/libuuid/lib.rs
@@ -85,7 +85,7 @@ use std::from_str::FromStr;
 use std::hash::Hash;
 use std::num::FromStrRadix;
 use std::str;
-use std::vec;
+use std::slice;
 
 use rand::Rng;
 
@@ -202,7 +202,7 @@ impl Uuid {
     pub fn new_v4() -> Uuid {
         let ub = rand::task_rng().gen_vec(16);
         let mut uuid = Uuid{ bytes: [0, .. 16] };
-        vec::bytes::copy_memory(uuid.bytes, ub);
+        slice::bytes::copy_memory(uuid.bytes, ub);
         uuid.set_variant(VariantRFC4122);
         uuid.set_version(Version4Random);
         uuid
@@ -229,7 +229,7 @@ impl Uuid {
         fields.data1 = to_be32(d1 as i32) as u32;
         fields.data2 = to_be16(d2 as i16) as u16;
         fields.data3 = to_be16(d3 as i16) as u16;
-        vec::bytes::copy_memory(fields.data4, d4);
+        slice::bytes::copy_memory(fields.data4, d4);
 
         unsafe {
             transmute(fields)
@@ -246,7 +246,7 @@ impl Uuid {
         }
 
         let mut uuid = Uuid{ bytes: [0, .. 16] };
-        vec::bytes::copy_memory(uuid.bytes, b);
+        slice::bytes::copy_memory(uuid.bytes, b);
         Some(uuid)
     }
 
@@ -329,7 +329,7 @@ impl Uuid {
     ///
     /// Example: `936DA01F9ABD4d9d80C702AF85C822A8`
     pub fn to_simple_str(&self) -> ~str {
-        let mut s: ~[u8] = vec::from_elem(32, 0u8);
+        let mut s: ~[u8] = slice::from_elem(32, 0u8);
         for i in range(0u, 16u) {
             let digit = format!("{:02x}", self.bytes[i] as uint);
             s[i*2+0] = digit[0];
@@ -523,7 +523,7 @@ impl rand::Rand for Uuid {
     fn rand<R: rand::Rng>(rng: &mut R) -> Uuid {
         let ub = rng.gen_vec(16);
         let mut uuid = Uuid{ bytes: [0, .. 16] };
-        vec::bytes::copy_memory(uuid.bytes, ub);
+        slice::bytes::copy_memory(uuid.bytes, ub);
         uuid.set_variant(VariantRFC4122);
         uuid.set_version(Version4Random);
         uuid
diff --git a/src/rt/rust_test_helpers.c b/src/rt/rust_test_helpers.c
index ee328e6cdb5..4d5b95155ca 100644
--- a/src/rt/rust_test_helpers.c
+++ b/src/rt/rust_test_helpers.c
@@ -126,6 +126,29 @@ rust_dbg_extern_identity_TwoDoubles(struct TwoDoubles u) {
     return u;
 }
 
+struct ManyInts {
+    int8_t arg1;
+    int16_t arg2;
+    int32_t arg3;
+    int16_t arg4;
+    int8_t arg5;
+    struct TwoU8s arg6;
+};
+
+struct Empty {
+};
+
+void
+rust_dbg_extern_empty_struct(struct ManyInts v1, struct Empty e, struct ManyInts v2) {
+    assert(v1.arg1 == v2.arg1 + 1);
+    assert(v1.arg2 == v2.arg2 + 1);
+    assert(v1.arg3 == v2.arg3 + 1);
+    assert(v1.arg4 == v2.arg4 + 1);
+    assert(v1.arg5 == v2.arg5 + 1);
+    assert(v1.arg6.one == v2.arg6.one + 1);
+    assert(v1.arg6.two == v2.arg6.two + 1);
+}
+
 intptr_t
 rust_get_test_int() {
   return 1;
diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs
index ef5c141a3d5..51bbb59b77e 100644
--- a/src/test/auxiliary/issue-2526.rs
+++ b/src/test/auxiliary/issue-2526.rs
@@ -16,17 +16,17 @@ struct arc_destruct<T> {
 }
 
 #[unsafe_destructor]
-impl<T:Freeze> Drop for arc_destruct<T> {
+impl<T: Share> Drop for arc_destruct<T> {
     fn drop(&mut self) {}
 }
 
-fn arc_destruct<T:Freeze>(data: int) -> arc_destruct<T> {
+fn arc_destruct<T: Share>(data: int) -> arc_destruct<T> {
     arc_destruct {
         _data: data
     }
 }
 
-fn arc<T:Freeze>(_data: T) -> arc_destruct<T> {
+fn arc<T: Share>(_data: T) -> arc_destruct<T> {
     arc_destruct(0)
 }
 
diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs
index fcea5222e10..9f91284a413 100644
--- a/src/test/bench/core-map.rs
+++ b/src/test/bench/core-map.rs
@@ -16,7 +16,7 @@ use collections::{TrieMap, TreeMap, HashMap, HashSet};
 use std::os;
 use rand::{Rng, IsaacRng, SeedableRng};
 use std::uint;
-use std::vec;
+use std::slice;
 
 fn timed(label: &str, f: ||) {
     let start = time::precise_time_s();
@@ -99,7 +99,7 @@ fn main() {
         }
     };
 
-    let mut rand = vec::with_capacity(n_keys);
+    let mut rand = slice::with_capacity(n_keys);
 
     {
         let mut rng: IsaacRng = SeedableRng::from_seed(&[1, 1, 1, 1, 1, 1, 1]);
diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs
index 120caa53293..6bf145e7976 100644
--- a/src/test/bench/core-std.rs
+++ b/src/test/bench/core-std.rs
@@ -20,7 +20,7 @@ use rand::Rng;
 use std::mem::swap;
 use std::os;
 use std::str;
-use std::vec;
+use std::slice;
 use std::io::File;
 
 macro_rules! bench (
@@ -61,7 +61,7 @@ fn maybe_run_test(argv: &[~str], name: ~str, test: ||) {
 }
 
 fn shift_push() {
-    let mut v1 = vec::from_elem(30000, 1);
+    let mut v1 = slice::from_elem(30000, 1);
     let mut v2 = ~[];
 
     while v1.len() > 0 {
@@ -88,7 +88,7 @@ fn vec_plus() {
     let mut v = ~[];
     let mut i = 0;
     while i < 1500 {
-        let rv = vec::from_elem(r.gen_range(0u, i + 1), i);
+        let rv = slice::from_elem(r.gen_range(0u, i + 1), i);
         if r.gen() {
             v.push_all_move(rv);
         } else {
@@ -104,12 +104,12 @@ fn vec_append() {
     let mut v = ~[];
     let mut i = 0;
     while i < 1500 {
-        let rv = vec::from_elem(r.gen_range(0u, i + 1), i);
+        let rv = slice::from_elem(r.gen_range(0u, i + 1), i);
         if r.gen() {
-            v = vec::append(v, rv);
+            v = slice::append(v, rv);
         }
         else {
-            v = vec::append(rv, v);
+            v = slice::append(rv, v);
         }
         i += 1;
     }
@@ -120,7 +120,7 @@ fn vec_push_all() {
 
     let mut v = ~[];
     for i in range(0u, 1500) {
-        let mut rv = vec::from_elem(r.gen_range(0u, i + 1), i);
+        let mut rv = slice::from_elem(r.gen_range(0u, i + 1), i);
         if r.gen() {
             v.push_all(rv);
         }
diff --git a/src/test/bench/shootout-fannkuch-redux.rs b/src/test/bench/shootout-fannkuch-redux.rs
index 2f637030802..8d860206d0c 100644
--- a/src/test/bench/shootout-fannkuch-redux.rs
+++ b/src/test/bench/shootout-fannkuch-redux.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use std::os;
-use std::vec;
+use std::slice;
 
 fn max(a: i32, b: i32) -> i32 {
     if a > b {
@@ -20,9 +20,9 @@ fn max(a: i32, b: i32) -> i32 {
 }
 
 fn fannkuch_redux(n: i32) -> i32 {
-    let mut perm = vec::from_elem(n as uint, 0i32);
-    let mut perm1 = vec::from_fn(n as uint, |i| i as i32);
-    let mut count = vec::from_elem(n as uint, 0i32);
+    let mut perm = slice::from_elem(n as uint, 0i32);
+    let mut perm1 = slice::from_fn(n as uint, |i| i as i32);
+    let mut count = slice::from_elem(n as uint, 0i32);
     let mut max_flips_count = 0i32;
     let mut perm_count = 0i32;
     let mut checksum = 0i32;
diff --git a/src/test/bench/shootout-fasta-redux.rs b/src/test/bench/shootout-fasta-redux.rs
index 532bc714d31..fead298bc86 100644
--- a/src/test/bench/shootout-fasta-redux.rs
+++ b/src/test/bench/shootout-fasta-redux.rs
@@ -11,8 +11,8 @@
 use std::cmp::min;
 use std::io::{stdout, IoResult};
 use std::os;
-use std::vec::bytes::copy_memory;
-use std::vec;
+use std::slice::bytes::copy_memory;
+use std::slice;
 
 static LINE_LEN: uint = 60;
 static LOOKUP_SIZE: uint = 4 * 1024;
@@ -89,7 +89,7 @@ impl<'a, W: Writer> RepeatFasta<'a, W> {
 
     fn make(&mut self, n: uint) -> IoResult<()> {
         let alu_len = self.alu.len();
-        let mut buf = vec::from_elem(alu_len + LINE_LEN, 0u8);
+        let mut buf = slice::from_elem(alu_len + LINE_LEN, 0u8);
         let alu: &[u8] = self.alu.as_bytes();
 
         copy_memory(buf, alu);
diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs
index 2ddcd2b5bfd..0b5a19aaec8 100644
--- a/src/test/bench/shootout-k-nucleotide-pipes.rs
+++ b/src/test/bench/shootout-k-nucleotide-pipes.rs
@@ -24,7 +24,7 @@ use std::os;
 use std::io;
 use std::str;
 use std::task;
-use std::vec;
+use std::slice;
 
 fn f64_cmp(x: f64, y: f64) -> Ordering {
     // arbitrarily decide that NaNs are larger than everything.
@@ -157,7 +157,7 @@ fn main() {
 
     // initialize each sequence sorter
     let sizes = ~[1u,2,3,4,6,12,18];
-    let mut streams = vec::from_fn(sizes.len(), |_| Some(channel::<~str>()));
+    let mut streams = slice::from_fn(sizes.len(), |_| Some(channel::<~str>()));
     let mut from_child = ~[];
     let to_child  = sizes.iter().zip(streams.mut_iter()).map(|(sz, stream_ref)| {
         let sz = *sz;
diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs
index 2ddea19b4c9..1a981480ebe 100644
--- a/src/test/bench/shootout-k-nucleotide.rs
+++ b/src/test/bench/shootout-k-nucleotide.rs
@@ -11,7 +11,7 @@
 // ignore-pretty
 
 use std::str;
-use std::vec;
+use std::slice;
 
 static TABLE: [u8, ..4] = [ 'A' as u8, 'C' as u8, 'G' as u8, 'T' as u8 ];
 static TABLE_SIZE: uint = 2 << 16;
@@ -97,14 +97,14 @@ struct Table {
 
 struct Items<'a> {
     cur: Option<&'a Entry>,
-    items: vec::Items<'a, Option<~Entry>>,
+    items: slice::Items<'a, Option<~Entry>>,
 }
 
 impl Table {
     fn new() -> Table {
         Table {
             count: 0,
-            items: vec::from_fn(TABLE_SIZE, |_| None),
+            items: slice::from_fn(TABLE_SIZE, |_| None),
         }
     }
 
diff --git a/src/test/bench/shootout-meteor.rs b/src/test/bench/shootout-meteor.rs
index 496e09b4651..97f2c887515 100644
--- a/src/test/bench/shootout-meteor.rs
+++ b/src/test/bench/shootout-meteor.rs
@@ -180,7 +180,7 @@ fn get_id(m: u64) -> u8 {
 
 // Converts a list of mask to a ~str.
 fn to_utf8(raw_sol: &List<u64>) -> ~str {
-    let mut sol: ~[u8] = std::vec::from_elem(50, '.' as u8);
+    let mut sol: ~[u8] = std::slice::from_elem(50, '.' as u8);
     for &m in raw_sol.iter() {
         let id = get_id(m);
         for i in range(0, 50) {
diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs
index 87b58023c69..ea8253f6e42 100644
--- a/src/test/bench/shootout-spectralnorm.rs
+++ b/src/test/bench/shootout-spectralnorm.rs
@@ -14,7 +14,7 @@ use std::from_str::FromStr;
 use std::iter::count;
 use std::cmp::min;
 use std::os;
-use std::vec::from_elem;
+use std::slice::from_elem;
 use sync::RWArc;
 
 fn A(i: uint, j: uint) -> f64 {
diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs
index e69ede619de..ba94290bd03 100644
--- a/src/test/bench/sudoku.rs
+++ b/src/test/bench/sudoku.rs
@@ -17,7 +17,7 @@ use std::io::stdio::StdReader;
 use std::io::BufferedReader;
 use std::os;
 use std::intrinsics::cttz16;
-use std::vec;
+use std::slice;
 
 // Computes a single solution to a given 9x9 sudoku
 //
@@ -48,8 +48,8 @@ impl Sudoku {
     }
 
     pub fn from_vec(vec: &[[u8, ..9], ..9]) -> Sudoku {
-        let g = vec::from_fn(9u, |i| {
-            vec::from_fn(9u, |j| { vec[i][j] })
+        let g = slice::from_fn(9u, |i| {
+            slice::from_fn(9u, |j| { vec[i][j] })
         });
         return Sudoku::new(g)
     }
@@ -68,7 +68,7 @@ impl Sudoku {
     pub fn read(mut reader: BufferedReader<StdReader>) -> Sudoku {
         assert!(reader.read_line().unwrap() == ~"9,9"); /* assert first line is exactly "9,9" */
 
-        let mut g = vec::from_fn(10u, { |_i| ~[0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8] });
+        let mut g = slice::from_fn(10u, { |_i| ~[0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8] });
         for line in reader.lines() {
             let comps: ~[&str] = line.unwrap().trim().split(',').collect();
 
diff --git a/src/test/bench/task-perf-one-million.rs b/src/test/bench/task-perf-one-million.rs
index c3c255b2dc8..75975b76ecb 100644
--- a/src/test/bench/task-perf-one-million.rs
+++ b/src/test/bench/task-perf-one-million.rs
@@ -15,11 +15,11 @@
 use std::os;
 use std::task;
 use std::uint;
-use std::vec;
+use std::slice;
 
 fn calc(children: uint, parent_wait_chan: &Sender<Sender<Sender<int>>>) {
 
-    let wait_ports: ~[Receiver<Sender<Sender<int>>>] = vec::from_fn(children, |_| {
+    let wait_ports: ~[Receiver<Sender<Sender<int>>>] = slice::from_fn(children, |_| {
         let (wait_port, wait_chan) = stream::<Sender<Sender<int>>>();
         task::spawn(proc() {
             calc(children / 2, &wait_chan);
diff --git a/src/test/compile-fail/borrowck-forbid-static-unsafe-interior.rs b/src/test/compile-fail/borrowck-forbid-static-unsafe-interior.rs
new file mode 100644
index 00000000000..c790a040a91
--- /dev/null
+++ b/src/test/compile-fail/borrowck-forbid-static-unsafe-interior.rs
@@ -0,0 +1,47 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Verify that it is not possible to take the address of
+// static items with usnafe interior.
+
+use std::kinds::marker;
+use std::ty::Unsafe;
+
+struct MyUnsafe<T> {
+    value: Unsafe<T>
+}
+
+impl<T> MyUnsafe<T> {
+    fn forbidden(&self) {}
+}
+
+enum UnsafeEnum<T> {
+    VariantSafe,
+    VariantUnsafe(Unsafe<T>)
+}
+
+static STATIC1: UnsafeEnum<int> = VariantSafe;
+
+static STATIC2: Unsafe<int> = Unsafe{value: 1, marker1: marker::InvariantType};
+static STATIC3: MyUnsafe<int> = MyUnsafe{value: STATIC2};
+
+static STATIC4: &'static Unsafe<int> = &'static STATIC2;
+//~^ ERROR borrow of immutable static items with unsafe interior is not allowed
+
+
+fn main() {
+    let a = &STATIC1;
+    //~^ ERROR borrow of immutable static items with unsafe interior is not allowed
+
+    STATIC3.forbidden()
+    //~^ ERROR borrow of immutable static items with unsafe interior is not allowed
+}
+
+
diff --git a/src/test/compile-fail/builtin-superkinds-double-superkind.rs b/src/test/compile-fail/builtin-superkinds-double-superkind.rs
index 15fa0b66433..7de38e6173b 100644
--- a/src/test/compile-fail/builtin-superkinds-double-superkind.rs
+++ b/src/test/compile-fail/builtin-superkinds-double-superkind.rs
@@ -11,12 +11,12 @@
 // Test for traits that inherit from multiple builtin kinds at once,
 // testing that all such kinds must be present on implementing types.
 
-trait Foo : Send+Freeze { }
+trait Foo : Send+Share { }
 
-impl <T: Freeze> Foo for (T,) { } //~ ERROR cannot implement this trait
+impl <T: Share> Foo for (T,) { } //~ ERROR cannot implement this trait
 
 impl <T: Send> Foo for (T,T) { } //~ ERROR cannot implement this trait
 
-impl <T: Send+Freeze> Foo for (T,T,T) { } // (ok)
+impl <T: Send+Share> Foo for (T,T,T) { } // (ok)
 
 fn main() { }
diff --git a/src/test/compile-fail/builtin-superkinds-self-type.rs b/src/test/compile-fail/builtin-superkinds-self-type.rs
index 074c5d7bb76..0d5a71559e8 100644
--- a/src/test/compile-fail/builtin-superkinds-self-type.rs
+++ b/src/test/compile-fail/builtin-superkinds-self-type.rs
@@ -11,13 +11,13 @@
 // Tests (negatively) the ability for the Self type in default methods
 // to use capabilities granted by builtin kinds as supertraits.
 
-trait Foo : Freeze {
+trait Foo : Share {
     fn foo(self, mut chan: Sender<Self>) {
         chan.send(self); //~ ERROR does not fulfill `Send`
     }
 }
 
-impl <T: Freeze> Foo for T { }
+impl <T: Share> Foo for T { }
 
 fn main() {
     let (tx, rx) = channel();
diff --git a/src/test/compile-fail/builtin-superkinds-typaram-not-send.rs b/src/test/compile-fail/builtin-superkinds-typaram-not-send.rs
index 2a3d3c7df61..bc0ad6dbb29 100644
--- a/src/test/compile-fail/builtin-superkinds-typaram-not-send.rs
+++ b/src/test/compile-fail/builtin-superkinds-typaram-not-send.rs
@@ -12,6 +12,6 @@
 
 trait Foo : Send { }
 
-impl <T: Freeze> Foo for T { } //~ ERROR cannot implement this trait
+impl <T: Share> Foo for T { } //~ ERROR cannot implement this trait
 
 fn main() { }
diff --git a/src/test/compile-fail/cant-implement-builtin-kinds.rs b/src/test/compile-fail/cant-implement-builtin-kinds.rs
index c35ca098372..6bedac6d12d 100644
--- a/src/test/compile-fail/cant-implement-builtin-kinds.rs
+++ b/src/test/compile-fail/cant-implement-builtin-kinds.rs
@@ -14,6 +14,6 @@ struct X<T>(T);
 
 impl <T> Send for X<T> { } //~ ERROR cannot provide an explicit implementation for a builtin kind
 impl <T> Sized for X<T> { } //~ ERROR cannot provide an explicit implementation for a builtin kind
-impl <T> Freeze for X<T> { } //~ ERROR cannot provide an explicit implementation for a builtin kind
+impl <T> Share for X<T> { } //~ ERROR cannot provide an explicit implementation for a builtin kind
 
 fn main() { }
diff --git a/src/test/compile-fail/check-static-values-constraints.rs b/src/test/compile-fail/check-static-values-constraints.rs
index 852b06d00a6..8ae40a74af1 100644
--- a/src/test/compile-fail/check-static-values-constraints.rs
+++ b/src/test/compile-fail/check-static-values-constraints.rs
@@ -124,30 +124,6 @@ static STATIC18: @SafeStruct = @SafeStruct{field1: Variant1, field2: Variant2(0)
 static STATIC19: ~int = box 3;
 //~^ ERROR static items are not allowed to have owned pointers
 
-
-struct StructNoFreeze<'a> {
-    nf: &'a int
-}
-
-enum EnumNoFreeze<'a> {
-    FreezableVariant,
-    NonFreezableVariant(StructNoFreeze<'a>)
-}
-
-static STATIC20: StructNoFreeze<'static> = StructNoFreeze{nf: &'static mut 4};
-//~^ ERROR immutable static items must be `Freeze`
-
-static STATIC21: EnumNoFreeze<'static> = FreezableVariant;
-static STATIC22: EnumNoFreeze<'static> = NonFreezableVariant(StructNoFreeze{nf: &'static mut 4});
-//~^ ERROR immutable static items must be `Freeze`
-
-struct NFMarker {
-    nf: marker::NoFreeze
-}
-
-static STATIC23: NFMarker = NFMarker{nf: marker::NoFreeze};
-//~^ ERROR immutable static items must be `Freeze`
-
 pub fn main() {
     let y = { static x: ~int = ~3; x };
     //~^ ERROR static items are not allowed to have owned pointers
diff --git a/src/test/compile-fail/comm-not-freeze.rs b/src/test/compile-fail/comm-not-freeze.rs
index b7b87b28264..3550922dc14 100644
--- a/src/test/compile-fail/comm-not-freeze.rs
+++ b/src/test/compile-fail/comm-not-freeze.rs
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn test<T: Freeze>() {}
+fn test<T: Share>() {}
 
 fn main() {
-    test::<Sender<int>>();        //~ ERROR: does not fulfill `Freeze`
-    test::<Receiver<int>>();        //~ ERROR: does not fulfill `Freeze`
-    test::<Sender<int>>();  //~ ERROR: does not fulfill `Freeze`
+    test::<Sender<int>>();        //~ ERROR: does not fulfill `Share`
+    test::<Receiver<int>>();        //~ ERROR: does not fulfill `Share`
+    test::<Sender<int>>();  //~ ERROR: does not fulfill `Share`
 }
diff --git a/src/test/compile-fail/issue-11873.rs b/src/test/compile-fail/issue-11873.rs
index 49b226b882e..1ae887a8332 100644
--- a/src/test/compile-fail/issue-11873.rs
+++ b/src/test/compile-fail/issue-11873.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 fn main() {
     let mut v = vec!(1);
diff --git a/src/test/compile-fail/issue-2611-4.rs b/src/test/compile-fail/issue-2611-4.rs
index c62c2874525..b159337765e 100644
--- a/src/test/compile-fail/issue-2611-4.rs
+++ b/src/test/compile-fail/issue-2611-4.rs
@@ -20,7 +20,7 @@ struct E {
 }
 
 impl A for E {
-  fn b<F:Freeze,G>(_x: F) -> F { fail!() } //~ ERROR type parameter 0 requires `Freeze`
+  fn b<F: Share, G>(_x: F) -> F { fail!() } //~ ERROR type parameter 0 requires `Share`
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/lint-deprecated-owned-vector.rs b/src/test/compile-fail/lint-deprecated-owned-vector.rs
index c21ca87e244..e73e1eacc7c 100644
--- a/src/test/compile-fail/lint-deprecated-owned-vector.rs
+++ b/src/test/compile-fail/lint-deprecated-owned-vector.rs
@@ -13,5 +13,5 @@
 fn main() {
     ~[1]; //~ ERROR use of deprecated `~[]`
     //~^ ERROR use of deprecated `~[]`
-    std::vec::with_capacity::<int>(10); //~ ERROR use of deprecated `~[]`
+    std::slice::with_capacity::<int>(10); //~ ERROR use of deprecated `~[]`
 }
diff --git a/src/test/compile-fail/lint-unused-imports.rs b/src/test/compile-fail/lint-unused-imports.rs
index c20546d8590..e4d9048ca8d 100644
--- a/src/test/compile-fail/lint-unused-imports.rs
+++ b/src/test/compile-fail/lint-unused-imports.rs
@@ -29,7 +29,7 @@ use test::B;
 
 // Make sure this import is warned about when at least one of its imported names
 // is unused
-use std::vec::{from_fn, from_elem};   //~ ERROR unused import
+use std::slice::{from_fn, from_elem};   //~ ERROR unused import
 
 mod test {
     pub trait A { fn a(&self) {} }
diff --git a/src/test/compile-fail/liveness-issue-2163.rs b/src/test/compile-fail/liveness-issue-2163.rs
index fbb6d03b220..05a6c0f6bbd 100644
--- a/src/test/compile-fail/liveness-issue-2163.rs
+++ b/src/test/compile-fail/liveness-issue-2163.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::vec;
+use std::slice;
 
 fn main() {
     let a: ~[int] = ~[];
diff --git a/src/test/compile-fail/marker-no-freeze.rs b/src/test/compile-fail/marker-no-share.rs
index 85f4f4fefd4..84e856f5ac9 100644
--- a/src/test/compile-fail/marker-no-freeze.rs
+++ b/src/test/compile-fail/marker-no-share.rs
@@ -10,9 +10,9 @@
 
 use std::kinds::marker;
 
-fn foo<P:Freeze>(p: P) { }
+fn foo<P: Share>(p: P) { }
 
 fn main()
 {
-    foo(marker::NoFreeze); //~ ERROR does not fulfill `Freeze`
+    foo(marker::NoShare); //~ ERROR does not fulfill `Share`
 }
diff --git a/src/test/compile-fail/mut-not-freeze.rs b/src/test/compile-fail/mut-not-freeze.rs
index 97fe49ca087..f1e7ef216c3 100644
--- a/src/test/compile-fail/mut-not-freeze.rs
+++ b/src/test/compile-fail/mut-not-freeze.rs
@@ -10,9 +10,9 @@
 
 use std::cell::RefCell;
 
-fn f<T: Freeze>(_: T) {}
+fn f<T: Share>(_: T) {}
 
 fn main() {
     let x = RefCell::new(0);
-    f(x); //~ ERROR: which does not fulfill `Freeze`
+    f(x); //~ ERROR: which does not fulfill `Share`
 }
diff --git a/src/test/compile-fail/no_freeze-enum.rs b/src/test/compile-fail/no_share-enum.rs
index e27b9dd85b4..e68274fcb79 100644
--- a/src/test/compile-fail/no_freeze-enum.rs
+++ b/src/test/compile-fail/no_share-enum.rs
@@ -10,13 +10,13 @@
 
 use std::kinds::marker;
 
-enum Foo { A(marker::NoFreeze) }
+enum Foo { A(marker::NoShare) }
 
-fn bar<T: Freeze>(_: T) {}
+fn bar<T: Share>(_: T) {}
 
 fn main() {
-    let x = A(marker::NoFreeze);
+    let x = A(marker::NoShare);
     bar(x);
     //~^ ERROR instantiating a type parameter with an incompatible type `Foo`,
-    //         which does not fulfill `Freeze`
+    //         which does not fulfill `Share`
 }
diff --git a/src/test/compile-fail/no_freeze-rc.rs b/src/test/compile-fail/no_share-rc.rs
index b814a71dcbe..ad79d038212 100644
--- a/src/test/compile-fail/no_freeze-rc.rs
+++ b/src/test/compile-fail/no_share-rc.rs
@@ -11,11 +11,11 @@
 use std::rc::Rc;
 use std::cell::RefCell;
 
-fn bar<T: Freeze>(_: T) {}
+fn bar<T: Share>(_: T) {}
 
 fn main() {
     let x = Rc::new(RefCell::new(5));
     bar(x);
     //~^ ERROR instantiating a type parameter with an incompatible type
-    //         `std::rc::Rc<std::cell::RefCell<int>>`, which does not fulfill `Freeze`
+    //         `std::rc::Rc<std::cell::RefCell<int>>`, which does not fulfill `Share`
 }
diff --git a/src/test/compile-fail/no_freeze-struct.rs b/src/test/compile-fail/no_share-struct.rs
index c85574438ba..7bb7d86e8d8 100644
--- a/src/test/compile-fail/no_freeze-struct.rs
+++ b/src/test/compile-fail/no_share-struct.rs
@@ -10,13 +10,13 @@
 
 use std::kinds::marker;
 
-struct Foo { a: int, m: marker::NoFreeze }
+struct Foo { a: int, m: marker::NoShare }
 
-fn bar<T: Freeze>(_: T) {}
+fn bar<T: Share>(_: T) {}
 
 fn main() {
-    let x = Foo { a: 5, m: marker::NoFreeze };
+    let x = Foo { a: 5, m: marker::NoShare };
     bar(x);
     //~^ ERROR instantiating a type parameter with an incompatible type `Foo`,
-    //         which does not fulfill `Freeze`
+    //         which does not fulfill `Share`
 }
diff --git a/src/test/run-pass/const-bound.rs b/src/test/run-pass/const-bound.rs
index 635ae704e41..c8c2a11d8d6 100644
--- a/src/test/run-pass/const-bound.rs
+++ b/src/test/run-pass/const-bound.rs
@@ -12,7 +12,7 @@
 // are const.
 
 
-fn foo<T:Freeze>(x: T) -> T { x }
+fn foo<T: Share>(x: T) -> T { x }
 
 struct F { field: int }
 
diff --git a/src/test/run-pass/extern-pass-TwoU16s.rs b/src/test/run-pass/extern-pass-TwoU16s.rs
index 2cbf9a37ca1..0eb7eabe747 100644
--- a/src/test/run-pass/extern-pass-TwoU16s.rs
+++ b/src/test/run-pass/extern-pass-TwoU16s.rs
@@ -8,12 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-test #5744 fails on 32 bit
-
 // Test a foreign function that accepts and returns a struct
 // by value.
 
-#[deriving(Eq)]
+#[deriving(Eq, Show)]
 struct TwoU16s {
     one: u16, two: u16
 }
diff --git a/src/test/run-pass/extern-pass-TwoU8s.rs b/src/test/run-pass/extern-pass-TwoU8s.rs
index 7ca351994bf..b5c99d55a8e 100644
--- a/src/test/run-pass/extern-pass-TwoU8s.rs
+++ b/src/test/run-pass/extern-pass-TwoU8s.rs
@@ -8,12 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// ignore-test #5744 fails on 32 bit
-
 // Test a foreign function that accepts and returns a struct
 // by value.
 
-#[deriving(Eq)]
+#[deriving(Eq, Show)]
 struct TwoU8s {
     one: u8, two: u8
 }
diff --git a/src/test/run-pass/extern-pass-empty.rs b/src/test/run-pass/extern-pass-empty.rs
new file mode 100644
index 00000000000..4c343fdb1a2
--- /dev/null
+++ b/src/test/run-pass/extern-pass-empty.rs
@@ -0,0 +1,55 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test a foreign function that accepts empty struct.
+
+struct TwoU8s {
+    one: u8,
+    two: u8,
+}
+
+struct ManyInts {
+    arg1: i8,
+    arg2: i16,
+    arg3: i32,
+    arg4: i16,
+    arg5: i8,
+    arg6: TwoU8s,
+}
+
+struct Empty;
+
+#[link(name = "rustrt")]
+extern {
+    fn rust_dbg_extern_empty_struct(v1: ManyInts, e: Empty, v2: ManyInts);
+}
+
+pub fn main() {
+    unsafe {
+        let x = ManyInts {
+            arg1: 2,
+            arg2: 3,
+            arg3: 4,
+            arg4: 5,
+            arg5: 6,
+            arg6: TwoU8s { one: 7, two: 8, }
+        };
+        let y = ManyInts {
+            arg1: 1,
+            arg2: 2,
+            arg3: 3,
+            arg4: 4,
+            arg5: 5,
+            arg6: TwoU8s { one: 6, two: 7, }
+        };
+        let empty = Empty;
+        rust_dbg_extern_empty_struct(x, empty, y);
+    }
+}
diff --git a/src/test/run-pass/import-glob-crate.rs b/src/test/run-pass/import-glob-crate.rs
index 3ba8f5eace5..dc66c888402 100644
--- a/src/test/run-pass/import-glob-crate.rs
+++ b/src/test/run-pass/import-glob-crate.rs
@@ -13,7 +13,7 @@
 #[feature(globs)];
 #[allow(dead_assignment)];
 
-use std::vec::*;
+use std::slice::*;
 
 pub fn main() {
     let mut v = from_elem(0u, 0);
diff --git a/src/test/run-pass/issue-2611-3.rs b/src/test/run-pass/issue-2611-3.rs
index a3d51bb9014..f48a49a15eb 100644
--- a/src/test/run-pass/issue-2611-3.rs
+++ b/src/test/run-pass/issue-2611-3.rs
@@ -12,7 +12,7 @@
 // than the traits require.
 
 trait A {
-  fn b<C:Freeze,D>(x: C) -> C;
+  fn b<C:Share,D>(x: C) -> C;
 }
 
 struct E {
diff --git a/src/test/run-pass/issue-2989.rs b/src/test/run-pass/issue-2989.rs
index b603759380e..bfb9f54b967 100644
--- a/src/test/run-pass/issue-2989.rs
+++ b/src/test/run-pass/issue-2989.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::vec;
+use std::slice;
 
 trait methods {
     fn to_bytes(&self) -> ~[u8];
@@ -16,14 +16,14 @@ trait methods {
 
 impl methods for () {
     fn to_bytes(&self) -> ~[u8] {
-        vec::from_elem(0, 0u8)
+        slice::from_elem(0, 0u8)
     }
 }
 
 // the position of this function is significant! - if it comes before methods
 // then it works, if it comes after it then it doesn't!
 fn to_bools(bitv: Storage) -> ~[bool] {
-    vec::from_fn(8, |i| {
+    slice::from_fn(8, |i| {
         let w = i / 64;
         let b = i % 64;
         let x = 1u64 & (bitv.storage[w] >> b);
diff --git a/src/test/run-pass/issue-3563-3.rs b/src/test/run-pass/issue-3563-3.rs
index 7d051e378ab..d06d00a130e 100644
--- a/src/test/run-pass/issue-3563-3.rs
+++ b/src/test/run-pass/issue-3563-3.rs
@@ -20,7 +20,7 @@
 // Extern mod controls linkage. Use controls the visibility of names to modules that are
 // already linked in. Using WriterUtil allows us to use the write_line method.
 use std::str;
-use std::vec;
+use std::slice;
 use std::fmt;
 
 // Represents a position on a canvas.
@@ -62,8 +62,8 @@ impl Drop for AsciiArt {
 fn AsciiArt(width: uint, height: uint, fill: char) -> AsciiArt {
     // Use an anonymous function to build a vector of vectors containing
     // blank characters for each position in our canvas.
-    let lines = vec::build(Some(height), |push| {
-        for _ in range(0, height) { push(vec::from_elem(width, '.')); }
+    let lines = slice::build(Some(height), |push| {
+        for _ in range(0, height) { push(slice::from_elem(width, '.')); }
     });
 
     // Rust code often returns values by omitting the trailing semi-colon
diff --git a/src/test/run-pass/mod-view-items.rs b/src/test/run-pass/mod-view-items.rs
index d3f79b9815e..e9fb74b4e6e 100644
--- a/src/test/run-pass/mod-view-items.rs
+++ b/src/test/run-pass/mod-view-items.rs
@@ -17,8 +17,8 @@
 // begin failing.
 
 mod m {
-    use std::vec;
-    pub fn f() -> ~[int] { vec::from_elem(1u, 0) }
+    use std::slice;
+    pub fn f() -> ~[int] { slice::from_elem(1u, 0) }
 }
 
 pub fn main() { let _x = m::f(); }
diff --git a/src/test/run-pass/overloaded-autoderef-count.rs b/src/test/run-pass/overloaded-autoderef-count.rs
index 10ee06473c8..1243ba1ce16 100644
--- a/src/test/run-pass/overloaded-autoderef-count.rs
+++ b/src/test/run-pass/overloaded-autoderef-count.rs
@@ -10,7 +10,7 @@
 
 use std::cell::Cell;
 use std::ops::{Deref, DerefMut};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 #[deriving(Eq)]
 struct DerefCounter<T> {
diff --git a/src/test/run-pass/overloaded-deref-count.rs b/src/test/run-pass/overloaded-deref-count.rs
index 28ac70c47c5..24dde8ada18 100644
--- a/src/test/run-pass/overloaded-deref-count.rs
+++ b/src/test/run-pass/overloaded-deref-count.rs
@@ -10,7 +10,7 @@
 
 use std::cell::Cell;
 use std::ops::{Deref, DerefMut};
-use std::vec_ng::Vec;
+use std::vec::Vec;
 
 struct DerefCounter<T> {
     count_imm: Cell<uint>,
diff --git a/src/test/run-pass/trait-bounds-in-arc.rs b/src/test/run-pass/trait-bounds-in-arc.rs
index f157f8ea95c..0ed4fdb2c05 100644
--- a/src/test/run-pass/trait-bounds-in-arc.rs
+++ b/src/test/run-pass/trait-bounds-in-arc.rs
@@ -65,10 +65,10 @@ pub fn main() {
     let dogge1 = Dogge { bark_decibels: 100, tricks_known: 42, name: ~"alan_turing" };
     let dogge2 = Dogge { bark_decibels: 55,  tricks_known: 11, name: ~"albert_einstein" };
     let fishe = Goldfyshe { swim_speed: 998, name: ~"alec_guinness" };
-    let arc = Arc::new(~[~catte  as ~Pet:Freeze+Send,
-                         ~dogge1 as ~Pet:Freeze+Send,
-                         ~fishe  as ~Pet:Freeze+Send,
-                         ~dogge2 as ~Pet:Freeze+Send]);
+    let arc = Arc::new(~[~catte  as ~Pet:Share+Send,
+                         ~dogge1 as ~Pet:Share+Send,
+                         ~fishe  as ~Pet:Share+Send,
+                         ~dogge2 as ~Pet:Share+Send]);
     let (tx1, rx1) = channel();
     let arc1 = arc.clone();
     task::spawn(proc() { check_legs(arc1); tx1.send(()); });
@@ -83,21 +83,21 @@ pub fn main() {
     rx3.recv();
 }
 
-fn check_legs(arc: Arc<~[~Pet:Freeze+Send]>) {
+fn check_legs(arc: Arc<~[~Pet:Share+Send]>) {
     let mut legs = 0;
     for pet in arc.get().iter() {
         legs += pet.num_legs();
     }
     assert!(legs == 12);
 }
-fn check_names(arc: Arc<~[~Pet:Freeze+Send]>) {
+fn check_names(arc: Arc<~[~Pet:Share+Send]>) {
     for pet in arc.get().iter() {
         pet.name(|name| {
             assert!(name[0] == 'a' as u8 && name[1] == 'l' as u8);
         })
     }
 }
-fn check_pedigree(arc: Arc<~[~Pet:Freeze+Send]>) {
+fn check_pedigree(arc: Arc<~[~Pet:Share+Send]>) {
     for pet in arc.get().iter() {
         assert!(pet.of_good_pedigree());
     }
diff --git a/src/test/run-pass/typeck_type_placeholder_1.rs b/src/test/run-pass/typeck_type_placeholder_1.rs
index 789a95dd6e5..e75bcb8b89e 100644
--- a/src/test/run-pass/typeck_type_placeholder_1.rs
+++ b/src/test/run-pass/typeck_type_placeholder_1.rs
@@ -14,7 +14,7 @@
 static CONSTEXPR: *int = &'static 413 as *_;
 
 pub fn main() {
-    use std::vec_ng::Vec;
+    use std::vec::Vec;
 
     let x: Vec<_> = range(0u, 5).collect();
     assert_eq!(x.as_slice(), &[0u,1,2,3,4]);
diff --git a/src/test/run-pass/uninit-empty-types.rs b/src/test/run-pass/uninit-empty-types.rs
index df24a399f4a..54791ddd419 100644
--- a/src/test/run-pass/uninit-empty-types.rs
+++ b/src/test/run-pass/uninit-empty-types.rs
@@ -10,7 +10,6 @@
 
 // Test the uninit() construct returning various empty types.
 
-use std::vec;
 use std::mem;
 
 #[deriving(Clone)]