about summary refs log tree commit diff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure9
-rw-r--r--mk/dist.mk1
-rw-r--r--mk/main.mk1
-rw-r--r--mk/target.mk3
-rw-r--r--mk/tests.mk7
-rw-r--r--src/compiletest/compiletest.rs1
-rw-r--r--src/doc/intro.md2
-rw-r--r--src/doc/reference.md8
-rw-r--r--src/doc/trpl/closures.md2
-rw-r--r--src/doc/trpl/concurrency.md2
-rw-r--r--src/doc/trpl/method-syntax.md8
-rw-r--r--src/liballoc/heap.rs2
-rw-r--r--src/liballoc/rc.rs3
-rw-r--r--src/libarena/lib.rs1
-rw-r--r--src/libcollections/binary_heap.rs220
-rw-r--r--src/libcollections/bit.rs1180
-rw-r--r--src/libcollections/btree/map.rs310
-rw-r--r--src/libcollections/btree/node.rs17
-rw-r--r--src/libcollections/btree/set.rs181
-rw-r--r--src/libcollections/enum_set.rs243
-rw-r--r--src/libcollections/fmt.rs12
-rw-r--r--src/libcollections/lib.rs41
-rw-r--r--src/libcollections/linked_list.rs398
-rw-r--r--src/libcollections/macros.rs55
-rw-r--r--src/libcollections/slice.rs2583
-rw-r--r--src/libcollections/str.rs2604
-rw-r--r--src/libcollections/string.rs487
-rw-r--r--src/libcollections/vec.rs1015
-rw-r--r--src/libcollections/vec_deque.rs888
-rw-r--r--src/libcollections/vec_map.rs507
-rw-r--r--src/libcollectionstest/bench.rs (renamed from src/libcollections/bench.rs)4
-rw-r--r--src/libcollectionstest/binary_heap.rs219
-rw-r--r--src/libcollectionstest/bit/mod.rs12
-rw-r--r--src/libcollectionstest/bit/set.rs441
-rw-r--r--src/libcollectionstest/bit/vec.rs729
-rw-r--r--src/libcollectionstest/btree/map.rs299
-rw-r--r--src/libcollectionstest/btree/mod.rs12
-rw-r--r--src/libcollectionstest/btree/set.rs180
-rw-r--r--src/libcollectionstest/enum_set.rs244
-rw-r--r--src/libcollectionstest/fmt.rs17
-rw-r--r--src/libcollectionstest/lib.rs43
-rw-r--r--src/libcollectionstest/linked_list.rs397
-rw-r--r--src/libcollectionstest/slice.rs1571
-rw-r--r--src/libcollectionstest/str.rs1668
-rw-r--r--src/libcollectionstest/string.rs453
-rw-r--r--src/libcollectionstest/vec.rs994
-rw-r--r--src/libcollectionstest/vec_deque.rs888
-rw-r--r--src/libcollectionstest/vec_map.rs510
-rw-r--r--src/libcore/iter.rs182
-rw-r--r--src/libcore/num/mod.rs990
-rw-r--r--src/libcore/panicking.rs8
-rw-r--r--src/libcore/prelude.rs2
-rw-r--r--src/libcore/ptr.rs118
-rw-r--r--src/libcore/slice.rs42
-rw-r--r--src/libcore/str/mod.rs1
-rw-r--r--src/libcore/tuple.rs174
-rw-r--r--src/libcoretest/iter.rs12
-rw-r--r--src/libflate/lib.rs68
-rw-r--r--src/liblibc/lib.rs4
-rw-r--r--src/liblog/lib.rs1
-rw-r--r--src/librand/distributions/mod.rs4
-rw-r--r--src/librustc/metadata/loader.rs4
-rw-r--r--src/librustc/middle/check_match.rs9
-rw-r--r--src/librustc/middle/dead.rs28
-rw-r--r--src/librustc/middle/infer/combine.rs2
-rw-r--r--src/librustc/middle/lang_items.rs18
-rw-r--r--src/librustc/middle/pat_util.rs24
-rw-r--r--src/librustc/middle/ty.rs23
-rw-r--r--src/librustc/session/search_paths.rs4
-rw-r--r--src/librustc_back/lib.rs1
-rw-r--r--src/librustc_back/svh.rs3
-rw-r--r--src/librustc_driver/lib.rs2
-rw-r--r--src/librustc_lint/builtin.rs2
-rw-r--r--src/librustc_llvm/archive_ro.rs8
-rw-r--r--src/librustc_llvm/lib.rs8
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs41
-rw-r--r--src/librustc_resolve/diagnostics.rs4
-rw-r--r--src/librustc_resolve/lib.rs1141
-rw-r--r--src/librustc_resolve/record_exports.rs13
-rw-r--r--src/librustc_resolve/resolve_imports.rs1021
-rw-r--r--src/librustc_trans/back/link.rs7
-rw-r--r--src/librustc_trans/back/lto.rs12
-rw-r--r--src/librustc_trans/trans/base.rs5
-rw-r--r--src/librustc_trans/trans/tvec.rs8
-rw-r--r--src/librustc_typeck/check/method/probe.rs76
-rw-r--r--src/librustc_typeck/coherence/orphan.rs137
-rw-r--r--src/librustdoc/html/render.rs127
-rw-r--r--src/librustdoc/html/static/main.js37
-rw-r--r--src/librustdoc/lib.rs2
-rw-r--r--src/libserialize/json.rs2
-rw-r--r--src/libstd/ascii.rs4
-rw-r--r--src/libstd/collections/hash/map.rs6
-rw-r--r--src/libstd/collections/hash/set.rs6
-rw-r--r--src/libstd/collections/hash/table.rs4
-rw-r--r--src/libstd/dynamic_lib.rs2
-rw-r--r--src/libstd/env.rs2
-rw-r--r--src/libstd/ffi/c_str.rs4
-rw-r--r--src/libstd/fs/mod.rs44
-rw-r--r--src/libstd/io/mod.rs17
-rw-r--r--src/libstd/io/stdio.rs79
-rw-r--r--src/libstd/macros.rs15
-rw-r--r--src/libstd/net/addr.rs395
-rw-r--r--src/libstd/net/ip.rs67
-rw-r--r--src/libstd/net/mod.rs20
-rw-r--r--src/libstd/net/parser.rs26
-rw-r--r--src/libstd/net/tcp.rs39
-rw-r--r--src/libstd/net/test.rs11
-rw-r--r--src/libstd/net/udp.rs30
-rw-r--r--src/libstd/num/f32.rs1230
-rw-r--r--src/libstd/num/f64.rs1229
-rw-r--r--src/libstd/num/float_macros.rs10
-rw-r--r--src/libstd/num/mod.rs3
-rw-r--r--src/libstd/num/strconv.rs5
-rw-r--r--src/libstd/old_io/buffered.rs1
-rw-r--r--src/libstd/old_io/comm_adapters.rs3
-rw-r--r--src/libstd/old_io/extensions.rs3
-rw-r--r--src/libstd/old_io/fs.rs1
-rw-r--r--src/libstd/old_io/mem.rs5
-rw-r--r--src/libstd/old_io/mod.rs16
-rw-r--r--src/libstd/old_io/net/ip.rs4
-rw-r--r--src/libstd/old_io/process.rs2
-rw-r--r--src/libstd/old_io/stdio.rs16
-rw-r--r--src/libstd/old_io/tempfile.rs1
-rw-r--r--src/libstd/old_path/mod.rs2
-rw-r--r--src/libstd/old_path/posix.rs10
-rw-r--r--src/libstd/old_path/windows.rs9
-rw-r--r--src/libstd/os.rs16
-rw-r--r--src/libstd/path.rs31
-rw-r--r--src/libstd/prelude/v1.rs11
-rw-r--r--src/libstd/process.rs18
-rw-r--r--src/libstd/rand/os.rs3
-rw-r--r--src/libstd/rand/reader.rs1
-rw-r--r--src/libstd/rt/at_exit_imp.rs1
-rw-r--r--src/libstd/sys/common/net2.rs32
-rw-r--r--src/libstd/sys/common/wtf8.rs30
-rw-r--r--src/libstd/sys/unix/backtrace.rs2
-rw-r--r--src/libstd/sys/unix/ext.rs375
-rw-r--r--src/libstd/sys/unix/net.rs8
-rw-r--r--src/libstd/sys/unix/os.rs10
-rw-r--r--src/libstd/sys/unix/os_str.rs1
-rw-r--r--src/libstd/sys/unix/process2.rs2
-rw-r--r--src/libstd/sys/unix/tty.rs14
-rw-r--r--src/libstd/sys/windows/ext.rs320
-rw-r--r--src/libstd/sys/windows/mod.rs2
-rw-r--r--src/libstd/sys/windows/net.rs8
-rw-r--r--src/libstd/sys/windows/os.rs3
-rw-r--r--src/libstd/sys/windows/process2.rs3
-rw-r--r--src/libstd/thread.rs12
-rw-r--r--src/libsyntax/ext/quote.rs12
-rw-r--r--src/libsyntax/ext/source_util.rs2
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs7
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs19
-rw-r--r--src/libsyntax/lib.rs1
-rw-r--r--src/libsyntax/parse/attr.rs58
-rw-r--r--src/libsyntax/parse/mod.rs14
-rw-r--r--src/libsyntax/parse/parser.rs715
-rw-r--r--src/libsyntax/test.rs18
-rw-r--r--src/libsyntax/util/parser_testing.rs4
-rw-r--r--src/libterm/lib.rs1
-rw-r--r--src/libtest/lib.rs13
-rw-r--r--src/libtest/stats.rs19
-rw-r--r--src/libunicode/char.rs372
-rw-r--r--src/libunicode/lib.rs1
-rw-r--r--src/libunicode/u_str.rs1
-rw-r--r--src/rustllvm/RustWrapper.cpp120
-rw-r--r--src/test/auxiliary/privacy_reexport.rs2
-rw-r--r--src/test/auxiliary/pub_static_array.rs11
-rw-r--r--src/test/compile-fail/associated-types-eq-expr-path.rs2
-rw-r--r--src/test/compile-fail/integral-indexing.rs8
-rw-r--r--src/test/compile-fail/issue-13407.rs19
-rw-r--r--src/test/compile-fail/issue-16922.rs20
-rw-r--r--src/test/compile-fail/issue-18919.rs17
-rw-r--r--src/test/compile-fail/issue-19982.rs17
-rw-r--r--src/test/compile-fail/issue-20225.rs22
-rw-r--r--src/test/compile-fail/issue-20261.rs17
-rw-r--r--src/test/compile-fail/issue-20714.rs15
-rw-r--r--src/test/compile-fail/issue-7950.rs17
-rw-r--r--src/test/compile-fail/lint-dead-code-3.rs2
-rw-r--r--src/test/compile-fail/lint-non-camel-case-types.rs3
-rw-r--r--src/test/compile-fail/manual-link-bad-search-path.rs15
-rw-r--r--src/test/compile-fail/match-ref-ice.rs (renamed from src/test/compile-fail/lint-dead-code-variant.rs)38
-rw-r--r--src/test/compile-fail/method-suggestion-no-duplication.rs2
-rw-r--r--src/test/compile-fail/privacy1.rs16
-rw-r--r--src/test/compile-fail/single-primitive-inherent-impl.rs24
-rw-r--r--src/test/compile-fail/static-array-across-crate.rs20
-rw-r--r--src/test/compile-fail/trait-bounds-not-on-bare-trait.rs2
-rw-r--r--src/test/parse-fail/column-offset-1-based.rs2
-rw-r--r--src/test/parse-fail/issue-1655.rs2
-rw-r--r--src/test/run-fail/issue-23354-2.rs17
-rw-r--r--src/test/run-fail/issue-23354.rs16
-rw-r--r--src/test/run-pass-fulldeps/quote-tokens.rs2
-rw-r--r--src/test/run-pass/issue-11820.rs19
-rw-r--r--src/test/run-pass/issue-16597.rs2
-rw-r--r--src/test/run-pass/issue-16922.rs18
-rw-r--r--src/test/run-pass/issue-19982.rs22
-rw-r--r--src/test/run-pass/issue-20396.rs23
-rw-r--r--src/test/run-pass/issue-20823.rs2
-rw-r--r--src/test/run-pass/issue-22577.rs5
-rw-r--r--src/test/run-pass/issue-5950.rs2
-rw-r--r--src/test/run-pass/issue-9951.rs28
-rw-r--r--src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs9
-rw-r--r--src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs4
-rw-r--r--src/test/run-pass/test-should-fail-good-message.rs4
-rw-r--r--src/test/run-pass/unsized3.rs19
204 files changed, 18502 insertions, 11431 deletions
diff --git a/configure b/configure
index 73e09158539..fdc28eee8c8 100755
--- a/configure
+++ b/configure
@@ -461,7 +461,10 @@ case $CFG_CPUTYPE in
         CFG_CPUTYPE=aarch64
         ;;
 
-    powerpc)
+    # At some point, when ppc64[le] support happens, this will need to do
+    # something clever. For now it's safe to assume that we're only ever
+    # interested in building 32 bit.
+    powerpc | ppc | ppc64)
         CFG_CPUTYPE=powerpc
         ;;
 
@@ -823,11 +826,11 @@ then
     LLVM_VERSION=$($LLVM_CONFIG --version)
 
     case $LLVM_VERSION in
-        (3.[2-6]*)
+        (3.[5-6]*)
             msg "found ok version of LLVM: $LLVM_VERSION"
             ;;
         (*)
-            err "bad LLVM version: $LLVM_VERSION, need >=3.0svn"
+            err "bad LLVM version: $LLVM_VERSION, need >=3.5"
             ;;
     esac
 fi
diff --git a/mk/dist.mk b/mk/dist.mk
index 831225556f3..57adaee5198 100644
--- a/mk/dist.mk
+++ b/mk/dist.mk
@@ -53,6 +53,7 @@ PKG_FILES := \
       driver                                   \
       etc                                      \
       $(foreach crate,$(CRATES),lib$(crate))   \
+      libcollectionstest                       \
       libcoretest                              \
       libbacktrace                             \
       rt                                       \
diff --git a/mk/main.mk b/mk/main.mk
index ad9d0d0ca5e..b9f2cf1cce8 100644
--- a/mk/main.mk
+++ b/mk/main.mk
@@ -290,6 +290,7 @@ LLVM_VERSION_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --version)
 LLVM_BINDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --bindir)
 LLVM_INCDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --includedir)
 LLVM_LIBDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --libdir)
+LLVM_LIBDIR_RUSTFLAGS_$(1)=-L "$$(LLVM_LIBDIR_$(1))"
 LLVM_LIBS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --libs $$(LLVM_COMPONENTS))
 LLVM_LDFLAGS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --ldflags)
 # On FreeBSD, it may search wrong headers (that are for pre-installed LLVM),
diff --git a/mk/target.mk b/mk/target.mk
index 4182ec81a7e..da18a9a4392 100644
--- a/mk/target.mk
+++ b/mk/target.mk
@@ -72,6 +72,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): CFG_COMPILER_HOST_TRIPLE = $(2)
 $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
 		$$(CRATEFILE_$(4)) \
 		$$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4)) \
+		$$(LLVM_CONFIG_$(2)) \
 		$$(TSREQ$(1)_T_$(2)_H_$(3)) \
 		| $$(TLIB$(1)_T_$(2)_H_$(3))/
 	@$$(call E, rustc: $$(@D)/lib$(4))
@@ -84,7 +85,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
 	    $$(subst @,,$$(STAGE$(1)_T_$(2)_H_$(3))) \
 		$$(RUST_LIB_FLAGS_ST$(1)) \
 		-L "$$(RT_OUTPUT_DIR_$(2))" \
-		-L "$$(LLVM_LIBDIR_$(2))" \
+		$$(LLVM_LIBDIR_RUSTFLAGS_$(2)) \
 		$$(LLVM_STDCPP_RUSTFLAGS_$(2)) \
 		$$(RUSTFLAGS_$(4)) \
 		--out-dir $$(@D) \
diff --git a/mk/tests.mk b/mk/tests.mk
index 78f5ac11f06..2fb33eb7db8 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -19,7 +19,10 @@
 DEPS_coretest :=
 $(eval $(call RUST_CRATE,coretest))
 
-TEST_TARGET_CRATES = $(filter-out core unicode,$(TARGET_CRATES)) coretest
+DEPS_collectionstest :=
+$(eval $(call RUST_CRATE,collectionstest))
+
+TEST_TARGET_CRATES = $(filter-out core unicode,$(TARGET_CRATES)) collectionstest coretest
 TEST_DOC_CRATES = $(DOC_CRATES)
 TEST_HOST_CRATES = $(filter-out rustc_typeck rustc_borrowck rustc_resolve rustc_trans rustc_lint,\
                      $(HOST_CRATES))
@@ -372,7 +375,7 @@ $(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2)): \
 	$(Q)CFG_LLVM_LINKAGE_FILE=$$(LLVM_LINKAGE_PATH_$(3)) \
 	    $$(subst @,,$$(STAGE$(1)_T_$(2)_H_$(3))) -o $$@ $$< --test \
 		-L "$$(RT_OUTPUT_DIR_$(2))" \
-		-L "$$(LLVM_LIBDIR_$(2))" \
+		$$(LLVM_LIBDIR_RUSTFLAGS_$(2)) \
 		$$(RUSTFLAGS_$(4))
 
 endef
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs
index 50e74a13ee2..5ef93cb569e 100644
--- a/src/compiletest/compiletest.rs
+++ b/src/compiletest/compiletest.rs
@@ -20,7 +20,6 @@
 #![feature(std_misc)]
 #![feature(test)]
 #![feature(core)]
-#![feature(net)]
 #![feature(path_ext)]
 
 #![deny(warnings)]
diff --git a/src/doc/intro.md b/src/doc/intro.md
index 9e575abeee2..51280e58854 100644
--- a/src/doc/intro.md
+++ b/src/doc/intro.md
@@ -140,7 +140,7 @@ right at home if you've used tools like [Bundler](http://bundler.io/),
 [npm](https://www.npmjs.org/), or [pip](https://pip.pypa.io/en/latest/).
 There's no `Makefile`s or endless `autotools` output here. (Rust's tooling does
 [play nice with external libraries written in those
-tools](http://crates.io/native-build.html), if you need to.)
+tools](http://doc.crates.io/build-script.html), if you need to.)
 
 Enough about tools, let's talk code!
 
diff --git a/src/doc/reference.md b/src/doc/reference.md
index c4c122463a7..3fae49bfc6d 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -1961,16 +1961,18 @@ module through the rules above. It essentially allows public access into the
 re-exported item. For example, this program is valid:
 
 ```
-pub use self::implementation as api;
+pub use self::implementation::api;
 
 mod implementation {
-    pub fn f() {}
+    pub mod api {
+        pub fn f() {}
+    }
 }
 
 # fn main() {}
 ```
 
-This means that any external crate referencing `implementation::f` would
+This means that any external crate referencing `implementation::api::f` would
 receive a privacy violation, while the path `api::f` would be allowed.
 
 When re-exporting a private item, it can be thought of as allowing the "privacy
diff --git a/src/doc/trpl/closures.md b/src/doc/trpl/closures.md
index 8cc6be7387c..bf4c2d90357 100644
--- a/src/doc/trpl/closures.md
+++ b/src/doc/trpl/closures.md
@@ -68,7 +68,7 @@ is that a moving closure always takes ownership of all variables that
 it uses. Ordinary closures, in contrast, just create a reference into
 the enclosing stack frame. Moving closures are most useful with Rust's
 concurrency features, and so we'll just leave it at this for
-now. We'll talk about them more in the "Threads" section of the guide.
+now. We'll talk about them more in the "Concurrency" chapter of the book.
 
 ## Accepting closures as arguments
 
diff --git a/src/doc/trpl/concurrency.md b/src/doc/trpl/concurrency.md
index 9b6d6ca67f6..4a16db63950 100644
--- a/src/doc/trpl/concurrency.md
+++ b/src/doc/trpl/concurrency.md
@@ -339,7 +339,7 @@ fn main() {
         });
     }
 
-   rx.recv().ok().expect("Could not recieve answer");
+   rx.recv().ok().expect("Could not receive answer");
 }
 ```
 
diff --git a/src/doc/trpl/method-syntax.md b/src/doc/trpl/method-syntax.md
index 0625d649e30..59be8c6704f 100644
--- a/src/doc/trpl/method-syntax.md
+++ b/src/doc/trpl/method-syntax.md
@@ -187,13 +187,13 @@ impl CircleBuilder {
     }
 
     fn coordinate(&mut self, coordinate: f64) -> &mut CircleBuilder {
-	self.coordinate = coordinate;
-	self
+        self.coordinate = coordinate;
+        self
     }
 
     fn radius(&mut self, radius: f64) -> &mut CircleBuilder {
-	self.radius = radius;
-	self
+        self.radius = radius;
+        self
     }
 
     fn finalize(&self) -> Circle {
diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs
index f9936b7a16a..25c6bda5f39 100644
--- a/src/liballoc/heap.rs
+++ b/src/liballoc/heap.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(stage0)]
 #[cfg(not(test))]
 use core::ptr::PtrExt;
 
@@ -387,7 +388,6 @@ mod imp {
 mod test {
     extern crate test;
     use self::test::Bencher;
-    use core::ptr::PtrExt;
     use boxed::Box;
     use heap;
 
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 115acd4a0ef..3692149db44 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -159,7 +159,10 @@ use core::nonzero::NonZero;
 use core::ops::{Deref, Drop};
 use core::option::Option;
 use core::option::Option::{Some, None};
+#[cfg(stage0)]
 use core::ptr::{self, PtrExt};
+#[cfg(not(stage0))]
+use core::ptr;
 use core::result::Result;
 use core::result::Result::{Ok, Err};
 use core::intrinsics::assume;
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index d08c9b3257a..029d9d03835 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -46,6 +46,7 @@ use std::intrinsics::{TyDesc, get_tydesc};
 use std::intrinsics;
 use std::marker;
 use std::mem;
+#[cfg(stage0)]
 use std::num::{Int, UnsignedInt};
 use std::ptr;
 use std::rc::Rc;
diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs
index 2e575ddb00a..11c8656c994 100644
--- a/src/libcollections/binary_heap.rs
+++ b/src/libcollections/binary_heap.rs
@@ -163,6 +163,11 @@ use vec::{self, Vec};
 /// A priority queue implemented with a binary heap.
 ///
 /// This will be a max-heap.
+///
+/// It is a logic error for an item to be modified in such a way that the
+/// item's ordering relative to any other item, as determined by the `Ord`
+/// trait, changes while it is in the heap. This is normally only possible
+/// through `Cell`, `RefCell`, global state, I/O, or unsafe code.
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct BinaryHeap<T> {
@@ -688,218 +693,3 @@ impl<T: Ord> Extend<T> for BinaryHeap<T> {
         }
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-
-    use super::BinaryHeap;
-
-    #[test]
-    fn test_iterator() {
-        let data = vec![5, 9, 3];
-        let iterout = [9, 5, 3];
-        let heap = BinaryHeap::from_vec(data);
-        let mut i = 0;
-        for el in &heap {
-            assert_eq!(*el, iterout[i]);
-            i += 1;
-        }
-    }
-
-    #[test]
-    fn test_iterator_reverse() {
-        let data = vec![5, 9, 3];
-        let iterout = vec![3, 5, 9];
-        let pq = BinaryHeap::from_vec(data);
-
-        let v: Vec<_> = pq.iter().rev().cloned().collect();
-        assert_eq!(v, iterout);
-    }
-
-    #[test]
-    fn test_move_iter() {
-        let data = vec![5, 9, 3];
-        let iterout = vec![9, 5, 3];
-        let pq = BinaryHeap::from_vec(data);
-
-        let v: Vec<_> = pq.into_iter().collect();
-        assert_eq!(v, iterout);
-    }
-
-    #[test]
-    fn test_move_iter_size_hint() {
-        let data = vec![5, 9];
-        let pq = BinaryHeap::from_vec(data);
-
-        let mut it = pq.into_iter();
-
-        assert_eq!(it.size_hint(), (2, Some(2)));
-        assert_eq!(it.next(), Some(9));
-
-        assert_eq!(it.size_hint(), (1, Some(1)));
-        assert_eq!(it.next(), Some(5));
-
-        assert_eq!(it.size_hint(), (0, Some(0)));
-        assert_eq!(it.next(), None);
-    }
-
-    #[test]
-    fn test_move_iter_reverse() {
-        let data = vec![5, 9, 3];
-        let iterout = vec![3, 5, 9];
-        let pq = BinaryHeap::from_vec(data);
-
-        let v: Vec<_> = pq.into_iter().rev().collect();
-        assert_eq!(v, iterout);
-    }
-
-    #[test]
-    fn test_peek_and_pop() {
-        let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
-        let mut sorted = data.clone();
-        sorted.sort();
-        let mut heap = BinaryHeap::from_vec(data);
-        while !heap.is_empty() {
-            assert_eq!(heap.peek().unwrap(), sorted.last().unwrap());
-            assert_eq!(heap.pop().unwrap(), sorted.pop().unwrap());
-        }
-    }
-
-    #[test]
-    fn test_push() {
-        let mut heap = BinaryHeap::from_vec(vec![2, 4, 9]);
-        assert_eq!(heap.len(), 3);
-        assert!(*heap.peek().unwrap() == 9);
-        heap.push(11);
-        assert_eq!(heap.len(), 4);
-        assert!(*heap.peek().unwrap() == 11);
-        heap.push(5);
-        assert_eq!(heap.len(), 5);
-        assert!(*heap.peek().unwrap() == 11);
-        heap.push(27);
-        assert_eq!(heap.len(), 6);
-        assert!(*heap.peek().unwrap() == 27);
-        heap.push(3);
-        assert_eq!(heap.len(), 7);
-        assert!(*heap.peek().unwrap() == 27);
-        heap.push(103);
-        assert_eq!(heap.len(), 8);
-        assert!(*heap.peek().unwrap() == 103);
-    }
-
-    #[test]
-    fn test_push_unique() {
-        let mut heap = BinaryHeap::<Box<_>>::from_vec(vec![box 2, box 4, box 9]);
-        assert_eq!(heap.len(), 3);
-        assert!(*heap.peek().unwrap() == box 9);
-        heap.push(box 11);
-        assert_eq!(heap.len(), 4);
-        assert!(*heap.peek().unwrap() == box 11);
-        heap.push(box 5);
-        assert_eq!(heap.len(), 5);
-        assert!(*heap.peek().unwrap() == box 11);
-        heap.push(box 27);
-        assert_eq!(heap.len(), 6);
-        assert!(*heap.peek().unwrap() == box 27);
-        heap.push(box 3);
-        assert_eq!(heap.len(), 7);
-        assert!(*heap.peek().unwrap() == box 27);
-        heap.push(box 103);
-        assert_eq!(heap.len(), 8);
-        assert!(*heap.peek().unwrap() == box 103);
-    }
-
-    #[test]
-    fn test_push_pop() {
-        let mut heap = BinaryHeap::from_vec(vec![5, 5, 2, 1, 3]);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.push_pop(6), 6);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.push_pop(0), 5);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.push_pop(4), 5);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.push_pop(1), 4);
-        assert_eq!(heap.len(), 5);
-    }
-
-    #[test]
-    fn test_replace() {
-        let mut heap = BinaryHeap::from_vec(vec![5, 5, 2, 1, 3]);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.replace(6).unwrap(), 5);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.replace(0).unwrap(), 6);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.replace(4).unwrap(), 5);
-        assert_eq!(heap.len(), 5);
-        assert_eq!(heap.replace(1).unwrap(), 4);
-        assert_eq!(heap.len(), 5);
-    }
-
-    fn check_to_vec(mut data: Vec<i32>) {
-        let heap = BinaryHeap::from_vec(data.clone());
-        let mut v = heap.clone().into_vec();
-        v.sort();
-        data.sort();
-
-        assert_eq!(v, data);
-        assert_eq!(heap.into_sorted_vec(), data);
-    }
-
-    #[test]
-    fn test_to_vec() {
-        check_to_vec(vec![]);
-        check_to_vec(vec![5]);
-        check_to_vec(vec![3, 2]);
-        check_to_vec(vec![2, 3]);
-        check_to_vec(vec![5, 1, 2]);
-        check_to_vec(vec![1, 100, 2, 3]);
-        check_to_vec(vec![1, 3, 5, 7, 9, 2, 4, 6, 8, 0]);
-        check_to_vec(vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
-        check_to_vec(vec![9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0]);
-        check_to_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
-        check_to_vec(vec![10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]);
-        check_to_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2]);
-        check_to_vec(vec![5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
-    }
-
-    #[test]
-    fn test_empty_pop() {
-        let mut heap = BinaryHeap::<i32>::new();
-        assert!(heap.pop().is_none());
-    }
-
-    #[test]
-    fn test_empty_peek() {
-        let empty = BinaryHeap::<i32>::new();
-        assert!(empty.peek().is_none());
-    }
-
-    #[test]
-    fn test_empty_replace() {
-        let mut heap = BinaryHeap::new();
-        assert!(heap.replace(5).is_none());
-    }
-
-    #[test]
-    fn test_from_iter() {
-        let xs = vec![9, 8, 7, 6, 5, 4, 3, 2, 1];
-
-        let mut q: BinaryHeap<_> = xs.iter().rev().cloned().collect();
-
-        for &x in &xs {
-            assert_eq!(q.pop().unwrap(), x);
-        }
-    }
-
-    #[test]
-    fn test_drain() {
-        let mut q: BinaryHeap<_> = [9, 8, 7, 6, 5, 4, 3, 2, 1].iter().cloned().collect();
-
-        assert_eq!(q.drain().take(5).count(), 5);
-
-        assert!(q.is_empty());
-    }
-}
diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs
index 500322ab243..90fbe04d348 100644
--- a/src/libcollections/bit.rs
+++ b/src/libcollections/bit.rs
@@ -1903,1183 +1903,3 @@ impl<'a> IntoIterator for &'a BitSet {
         self.iter()
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use core::u32;
-
-    use super::BitVec;
-
-    #[test]
-    fn test_to_str() {
-        let zerolen = BitVec::new();
-        assert_eq!(format!("{:?}", zerolen), "");
-
-        let eightbits = BitVec::from_elem(8, false);
-        assert_eq!(format!("{:?}", eightbits), "00000000")
-    }
-
-    #[test]
-    fn test_0_elements() {
-        let act = BitVec::new();
-        let exp = Vec::new();
-        assert!(act.eq_vec(&exp));
-        assert!(act.none() && act.all());
-    }
-
-    #[test]
-    fn test_1_element() {
-        let mut act = BitVec::from_elem(1, false);
-        assert!(act.eq_vec(&[false]));
-        assert!(act.none() && !act.all());
-        act = BitVec::from_elem(1, true);
-        assert!(act.eq_vec(&[true]));
-        assert!(!act.none() && act.all());
-    }
-
-    #[test]
-    fn test_2_elements() {
-        let mut b = BitVec::from_elem(2, false);
-        b.set(0, true);
-        b.set(1, false);
-        assert_eq!(format!("{:?}", b), "10");
-        assert!(!b.none() && !b.all());
-    }
-
-    #[test]
-    fn test_10_elements() {
-        let mut act;
-        // all 0
-
-        act = BitVec::from_elem(10, false);
-        assert!((act.eq_vec(
-                    &[false, false, false, false, false, false, false, false, false, false])));
-        assert!(act.none() && !act.all());
-        // all 1
-
-        act = BitVec::from_elem(10, true);
-        assert!((act.eq_vec(&[true, true, true, true, true, true, true, true, true, true])));
-        assert!(!act.none() && act.all());
-        // mixed
-
-        act = BitVec::from_elem(10, false);
-        act.set(0, true);
-        act.set(1, true);
-        act.set(2, true);
-        act.set(3, true);
-        act.set(4, true);
-        assert!((act.eq_vec(&[true, true, true, true, true, false, false, false, false, false])));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(10, false);
-        act.set(5, true);
-        act.set(6, true);
-        act.set(7, true);
-        act.set(8, true);
-        act.set(9, true);
-        assert!((act.eq_vec(&[false, false, false, false, false, true, true, true, true, true])));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(10, false);
-        act.set(0, true);
-        act.set(3, true);
-        act.set(6, true);
-        act.set(9, true);
-        assert!((act.eq_vec(&[true, false, false, true, false, false, true, false, false, true])));
-        assert!(!act.none() && !act.all());
-    }
-
-    #[test]
-    fn test_31_elements() {
-        let mut act;
-        // all 0
-
-        act = BitVec::from_elem(31, false);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false]));
-        assert!(act.none() && !act.all());
-        // all 1
-
-        act = BitVec::from_elem(31, true);
-        assert!(act.eq_vec(
-                &[true, true, true, true, true, true, true, true, true, true, true, true, true,
-                  true, true, true, true, true, true, true, true, true, true, true, true, true,
-                  true, true, true, true, true]));
-        assert!(!act.none() && act.all());
-        // mixed
-
-        act = BitVec::from_elem(31, false);
-        act.set(0, true);
-        act.set(1, true);
-        act.set(2, true);
-        act.set(3, true);
-        act.set(4, true);
-        act.set(5, true);
-        act.set(6, true);
-        act.set(7, true);
-        assert!(act.eq_vec(
-                &[true, true, true, true, true, true, true, true, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(31, false);
-        act.set(16, true);
-        act.set(17, true);
-        act.set(18, true);
-        act.set(19, true);
-        act.set(20, true);
-        act.set(21, true);
-        act.set(22, true);
-        act.set(23, true);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, true, true, true, true, true, true, true, true,
-                  false, false, false, false, false, false, false]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(31, false);
-        act.set(24, true);
-        act.set(25, true);
-        act.set(26, true);
-        act.set(27, true);
-        act.set(28, true);
-        act.set(29, true);
-        act.set(30, true);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, true, true, true, true, true, true, true]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(31, false);
-        act.set(3, true);
-        act.set(17, true);
-        act.set(30, true);
-        assert!(act.eq_vec(
-                &[false, false, false, true, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, true, false, false, false, false, false, false,
-                  false, false, false, false, false, false, true]));
-        assert!(!act.none() && !act.all());
-    }
-
-    #[test]
-    fn test_32_elements() {
-        let mut act;
-        // all 0
-
-        act = BitVec::from_elem(32, false);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false]));
-        assert!(act.none() && !act.all());
-        // all 1
-
-        act = BitVec::from_elem(32, true);
-        assert!(act.eq_vec(
-                &[true, true, true, true, true, true, true, true, true, true, true, true, true,
-                  true, true, true, true, true, true, true, true, true, true, true, true, true,
-                  true, true, true, true, true, true]));
-        assert!(!act.none() && act.all());
-        // mixed
-
-        act = BitVec::from_elem(32, false);
-        act.set(0, true);
-        act.set(1, true);
-        act.set(2, true);
-        act.set(3, true);
-        act.set(4, true);
-        act.set(5, true);
-        act.set(6, true);
-        act.set(7, true);
-        assert!(act.eq_vec(
-                &[true, true, true, true, true, true, true, true, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(32, false);
-        act.set(16, true);
-        act.set(17, true);
-        act.set(18, true);
-        act.set(19, true);
-        act.set(20, true);
-        act.set(21, true);
-        act.set(22, true);
-        act.set(23, true);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, true, true, true, true, true, true, true, true,
-                  false, false, false, false, false, false, false, false]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(32, false);
-        act.set(24, true);
-        act.set(25, true);
-        act.set(26, true);
-        act.set(27, true);
-        act.set(28, true);
-        act.set(29, true);
-        act.set(30, true);
-        act.set(31, true);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, true, true, true, true, true, true, true, true]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(32, false);
-        act.set(3, true);
-        act.set(17, true);
-        act.set(30, true);
-        act.set(31, true);
-        assert!(act.eq_vec(
-                &[false, false, false, true, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, true, false, false, false, false, false, false,
-                  false, false, false, false, false, false, true, true]));
-        assert!(!act.none() && !act.all());
-    }
-
-    #[test]
-    fn test_33_elements() {
-        let mut act;
-        // all 0
-
-        act = BitVec::from_elem(33, false);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false]));
-        assert!(act.none() && !act.all());
-        // all 1
-
-        act = BitVec::from_elem(33, true);
-        assert!(act.eq_vec(
-                &[true, true, true, true, true, true, true, true, true, true, true, true, true,
-                  true, true, true, true, true, true, true, true, true, true, true, true, true,
-                  true, true, true, true, true, true, true]));
-        assert!(!act.none() && act.all());
-        // mixed
-
-        act = BitVec::from_elem(33, false);
-        act.set(0, true);
-        act.set(1, true);
-        act.set(2, true);
-        act.set(3, true);
-        act.set(4, true);
-        act.set(5, true);
-        act.set(6, true);
-        act.set(7, true);
-        assert!(act.eq_vec(
-                &[true, true, true, true, true, true, true, true, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(33, false);
-        act.set(16, true);
-        act.set(17, true);
-        act.set(18, true);
-        act.set(19, true);
-        act.set(20, true);
-        act.set(21, true);
-        act.set(22, true);
-        act.set(23, true);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, true, true, true, true, true, true, true, true,
-                  false, false, false, false, false, false, false, false, false]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(33, false);
-        act.set(24, true);
-        act.set(25, true);
-        act.set(26, true);
-        act.set(27, true);
-        act.set(28, true);
-        act.set(29, true);
-        act.set(30, true);
-        act.set(31, true);
-        assert!(act.eq_vec(
-                &[false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, false, false, false, false, false, false,
-                  false, false, true, true, true, true, true, true, true, true, false]));
-        assert!(!act.none() && !act.all());
-        // mixed
-
-        act = BitVec::from_elem(33, false);
-        act.set(3, true);
-        act.set(17, true);
-        act.set(30, true);
-        act.set(31, true);
-        act.set(32, true);
-        assert!(act.eq_vec(
-                &[false, false, false, true, false, false, false, false, false, false, false, false,
-                  false, false, false, false, false, true, false, false, false, false, false, false,
-                  false, false, false, false, false, false, true, true, true]));
-        assert!(!act.none() && !act.all());
-    }
-
-    #[test]
-    fn test_equal_differing_sizes() {
-        let v0 = BitVec::from_elem(10, false);
-        let v1 = BitVec::from_elem(11, false);
-        assert!(v0 != v1);
-    }
-
-    #[test]
-    fn test_equal_greatly_differing_sizes() {
-        let v0 = BitVec::from_elem(10, false);
-        let v1 = BitVec::from_elem(110, false);
-        assert!(v0 != v1);
-    }
-
-    #[test]
-    fn test_equal_sneaky_small() {
-        let mut a = BitVec::from_elem(1, false);
-        a.set(0, true);
-
-        let mut b = BitVec::from_elem(1, true);
-        b.set(0, true);
-
-        assert_eq!(a, b);
-    }
-
-    #[test]
-    fn test_equal_sneaky_big() {
-        let mut a = BitVec::from_elem(100, false);
-        for i in 0..100 {
-            a.set(i, true);
-        }
-
-        let mut b = BitVec::from_elem(100, true);
-        for i in 0..100 {
-            b.set(i, true);
-        }
-
-        assert_eq!(a, b);
-    }
-
-    #[test]
-    fn test_from_bytes() {
-        let bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
-        let str = concat!("10110110", "00000000", "11111111");
-        assert_eq!(format!("{:?}", bit_vec), str);
-    }
-
-    #[test]
-    fn test_to_bytes() {
-        let mut bv = BitVec::from_elem(3, true);
-        bv.set(1, false);
-        assert_eq!(bv.to_bytes(), [0b10100000]);
-
-        let mut bv = BitVec::from_elem(9, false);
-        bv.set(2, true);
-        bv.set(8, true);
-        assert_eq!(bv.to_bytes(), [0b00100000, 0b10000000]);
-    }
-
-    #[test]
-    fn test_from_bools() {
-        let bools = vec![true, false, true, true];
-        let bit_vec: BitVec = bools.iter().map(|n| *n).collect();
-        assert_eq!(format!("{:?}", bit_vec), "1011");
-    }
-
-    #[test]
-    fn test_to_bools() {
-        let bools = vec![false, false, true, false, false, true, true, false];
-        assert_eq!(BitVec::from_bytes(&[0b00100110]).iter().collect::<Vec<bool>>(), bools);
-    }
-
-    #[test]
-    fn test_bit_vec_iterator() {
-        let bools = vec![true, false, true, true];
-        let bit_vec: BitVec = bools.iter().map(|n| *n).collect();
-
-        assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), bools);
-
-        let long: Vec<_> = (0..10000).map(|i| i % 2 == 0).collect();
-        let bit_vec: BitVec = long.iter().map(|n| *n).collect();
-        assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), long)
-    }
-
-    #[test]
-    fn test_small_difference() {
-        let mut b1 = BitVec::from_elem(3, false);
-        let mut b2 = BitVec::from_elem(3, false);
-        b1.set(0, true);
-        b1.set(1, true);
-        b2.set(1, true);
-        b2.set(2, true);
-        assert!(b1.difference(&b2));
-        assert!(b1[0]);
-        assert!(!b1[1]);
-        assert!(!b1[2]);
-    }
-
-    #[test]
-    fn test_big_difference() {
-        let mut b1 = BitVec::from_elem(100, false);
-        let mut b2 = BitVec::from_elem(100, false);
-        b1.set(0, true);
-        b1.set(40, true);
-        b2.set(40, true);
-        b2.set(80, true);
-        assert!(b1.difference(&b2));
-        assert!(b1[0]);
-        assert!(!b1[40]);
-        assert!(!b1[80]);
-    }
-
-    #[test]
-    fn test_small_clear() {
-        let mut b = BitVec::from_elem(14, true);
-        assert!(!b.none() && b.all());
-        b.clear();
-        assert!(b.none() && !b.all());
-    }
-
-    #[test]
-    fn test_big_clear() {
-        let mut b = BitVec::from_elem(140, true);
-        assert!(!b.none() && b.all());
-        b.clear();
-        assert!(b.none() && !b.all());
-    }
-
-    #[test]
-    fn test_bit_vec_lt() {
-        let mut a = BitVec::from_elem(5, false);
-        let mut b = BitVec::from_elem(5, false);
-
-        assert!(!(a < b) && !(b < a));
-        b.set(2, true);
-        assert!(a < b);
-        a.set(3, true);
-        assert!(a < b);
-        a.set(2, true);
-        assert!(!(a < b) && b < a);
-        b.set(0, true);
-        assert!(a < b);
-    }
-
-    #[test]
-    fn test_ord() {
-        let mut a = BitVec::from_elem(5, false);
-        let mut b = BitVec::from_elem(5, false);
-
-        assert!(a <= b && a >= b);
-        a.set(1, true);
-        assert!(a > b && a >= b);
-        assert!(b < a && b <= a);
-        b.set(1, true);
-        b.set(2, true);
-        assert!(b > a && b >= a);
-        assert!(a < b && a <= b);
-    }
-
-
-    #[test]
-    fn test_small_bit_vec_tests() {
-        let v = BitVec::from_bytes(&[0]);
-        assert!(!v.all());
-        assert!(!v.any());
-        assert!(v.none());
-
-        let v = BitVec::from_bytes(&[0b00010100]);
-        assert!(!v.all());
-        assert!(v.any());
-        assert!(!v.none());
-
-        let v = BitVec::from_bytes(&[0xFF]);
-        assert!(v.all());
-        assert!(v.any());
-        assert!(!v.none());
-    }
-
-    #[test]
-    fn test_big_bit_vec_tests() {
-        let v = BitVec::from_bytes(&[ // 88 bits
-            0, 0, 0, 0,
-            0, 0, 0, 0,
-            0, 0, 0]);
-        assert!(!v.all());
-        assert!(!v.any());
-        assert!(v.none());
-
-        let v = BitVec::from_bytes(&[ // 88 bits
-            0, 0, 0b00010100, 0,
-            0, 0, 0, 0b00110100,
-            0, 0, 0]);
-        assert!(!v.all());
-        assert!(v.any());
-        assert!(!v.none());
-
-        let v = BitVec::from_bytes(&[ // 88 bits
-            0xFF, 0xFF, 0xFF, 0xFF,
-            0xFF, 0xFF, 0xFF, 0xFF,
-            0xFF, 0xFF, 0xFF]);
-        assert!(v.all());
-        assert!(v.any());
-        assert!(!v.none());
-    }
-
-    #[test]
-    fn test_bit_vec_push_pop() {
-        let mut s = BitVec::from_elem(5 * u32::BITS as usize - 2, false);
-        assert_eq!(s.len(), 5 * u32::BITS as usize - 2);
-        assert_eq!(s[5 * u32::BITS as usize - 3], false);
-        s.push(true);
-        s.push(true);
-        assert_eq!(s[5 * u32::BITS as usize - 2], true);
-        assert_eq!(s[5 * u32::BITS as usize - 1], true);
-        // Here the internal vector will need to be extended
-        s.push(false);
-        assert_eq!(s[5 * u32::BITS as usize], false);
-        s.push(false);
-        assert_eq!(s[5 * u32::BITS as usize + 1], false);
-        assert_eq!(s.len(), 5 * u32::BITS as usize + 2);
-        // Pop it all off
-        assert_eq!(s.pop(), Some(false));
-        assert_eq!(s.pop(), Some(false));
-        assert_eq!(s.pop(), Some(true));
-        assert_eq!(s.pop(), Some(true));
-        assert_eq!(s.len(), 5 * u32::BITS as usize - 2);
-    }
-
-    #[test]
-    fn test_bit_vec_truncate() {
-        let mut s = BitVec::from_elem(5 * u32::BITS as usize, true);
-
-        assert_eq!(s, BitVec::from_elem(5 * u32::BITS as usize, true));
-        assert_eq!(s.len(), 5 * u32::BITS as usize);
-        s.truncate(4 * u32::BITS as usize);
-        assert_eq!(s, BitVec::from_elem(4 * u32::BITS as usize, true));
-        assert_eq!(s.len(), 4 * u32::BITS as usize);
-        // Truncating to a size > s.len() should be a noop
-        s.truncate(5 * u32::BITS as usize);
-        assert_eq!(s, BitVec::from_elem(4 * u32::BITS as usize, true));
-        assert_eq!(s.len(), 4 * u32::BITS as usize);
-        s.truncate(3 * u32::BITS as usize - 10);
-        assert_eq!(s, BitVec::from_elem(3 * u32::BITS as usize - 10, true));
-        assert_eq!(s.len(), 3 * u32::BITS as usize - 10);
-        s.truncate(0);
-        assert_eq!(s, BitVec::from_elem(0, true));
-        assert_eq!(s.len(), 0);
-    }
-
-    #[test]
-    fn test_bit_vec_reserve() {
-        let mut s = BitVec::from_elem(5 * u32::BITS as usize, true);
-        // Check capacity
-        assert!(s.capacity() >= 5 * u32::BITS as usize);
-        s.reserve(2 * u32::BITS as usize);
-        assert!(s.capacity() >= 7 * u32::BITS as usize);
-        s.reserve(7 * u32::BITS as usize);
-        assert!(s.capacity() >= 12 * u32::BITS as usize);
-        s.reserve_exact(7 * u32::BITS as usize);
-        assert!(s.capacity() >= 12 * u32::BITS as usize);
-        s.reserve(7 * u32::BITS as usize + 1);
-        assert!(s.capacity() >= 12 * u32::BITS as usize + 1);
-        // Check that length hasn't changed
-        assert_eq!(s.len(), 5 * u32::BITS as usize);
-        s.push(true);
-        s.push(false);
-        s.push(true);
-        assert_eq!(s[5 * u32::BITS as usize - 1], true);
-        assert_eq!(s[5 * u32::BITS as usize - 0], true);
-        assert_eq!(s[5 * u32::BITS as usize + 1], false);
-        assert_eq!(s[5 * u32::BITS as usize + 2], true);
-    }
-
-    #[test]
-    fn test_bit_vec_grow() {
-        let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010]);
-        bit_vec.grow(32, true);
-        assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
-                                     0xFF, 0xFF, 0xFF, 0xFF]));
-        bit_vec.grow(64, false);
-        assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
-                                     0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0]));
-        bit_vec.grow(16, true);
-        assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
-                                     0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]));
-    }
-
-    #[test]
-    fn test_bit_vec_extend() {
-        let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
-        let ext = BitVec::from_bytes(&[0b01001001, 0b10010010, 0b10111101]);
-        bit_vec.extend(ext.iter());
-        assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111,
-                                     0b01001001, 0b10010010, 0b10111101]));
-    }
-}
-
-
-
-
-#[cfg(test)]
-mod bit_vec_bench {
-    use std::prelude::v1::*;
-    use std::rand;
-    use std::rand::Rng;
-    use std::u32;
-    use test::{Bencher, black_box};
-
-    use super::BitVec;
-
-    const BENCH_BITS : usize = 1 << 14;
-
-    fn rng() -> rand::IsaacRng {
-        let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
-        rand::SeedableRng::from_seed(seed)
-    }
-
-    #[bench]
-    fn bench_usize_small(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bit_vec = 0 as usize;
-        b.iter(|| {
-            for _ in 0..100 {
-                bit_vec |= 1 << ((r.next_u32() as usize) % u32::BITS as usize);
-            }
-            black_box(&bit_vec);
-        });
-    }
-
-    #[bench]
-    fn bench_bit_set_big_fixed(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
-        b.iter(|| {
-            for _ in 0..100 {
-                bit_vec.set((r.next_u32() as usize) % BENCH_BITS, true);
-            }
-            black_box(&bit_vec);
-        });
-    }
-
-    #[bench]
-    fn bench_bit_set_big_variable(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
-        b.iter(|| {
-            for _ in 0..100 {
-                bit_vec.set((r.next_u32() as usize) % BENCH_BITS, r.gen());
-            }
-            black_box(&bit_vec);
-        });
-    }
-
-    #[bench]
-    fn bench_bit_set_small(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bit_vec = BitVec::from_elem(u32::BITS as usize, false);
-        b.iter(|| {
-            for _ in 0..100 {
-                bit_vec.set((r.next_u32() as usize) % u32::BITS as usize, true);
-            }
-            black_box(&bit_vec);
-        });
-    }
-
-    #[bench]
-    fn bench_bit_vec_big_union(b: &mut Bencher) {
-        let mut b1 = BitVec::from_elem(BENCH_BITS, false);
-        let b2 = BitVec::from_elem(BENCH_BITS, false);
-        b.iter(|| {
-            b1.union(&b2)
-        })
-    }
-
-    #[bench]
-    fn bench_bit_vec_small_iter(b: &mut Bencher) {
-        let bit_vec = BitVec::from_elem(u32::BITS as usize, false);
-        b.iter(|| {
-            let mut sum = 0;
-            for _ in 0..10 {
-                for pres in &bit_vec {
-                    sum += pres as usize;
-                }
-            }
-            sum
-        })
-    }
-
-    #[bench]
-    fn bench_bit_vec_big_iter(b: &mut Bencher) {
-        let bit_vec = BitVec::from_elem(BENCH_BITS, false);
-        b.iter(|| {
-            let mut sum = 0;
-            for pres in &bit_vec {
-                sum += pres as usize;
-            }
-            sum
-        })
-    }
-}
-
-
-
-
-
-
-
-#[cfg(test)]
-mod bit_set_test {
-    use prelude::*;
-    use std::iter::range_step;
-
-    use super::{BitVec, BitSet};
-
-    #[test]
-    fn test_bit_set_show() {
-        let mut s = BitSet::new();
-        s.insert(1);
-        s.insert(10);
-        s.insert(50);
-        s.insert(2);
-        assert_eq!("{1, 2, 10, 50}", format!("{:?}", s));
-    }
-
-    #[test]
-    fn test_bit_set_from_usizes() {
-        let usizes = vec![0, 2, 2, 3];
-        let a: BitSet = usizes.into_iter().collect();
-        let mut b = BitSet::new();
-        b.insert(0);
-        b.insert(2);
-        b.insert(3);
-        assert_eq!(a, b);
-    }
-
-    #[test]
-    fn test_bit_set_iterator() {
-        let usizes = vec![0, 2, 2, 3];
-        let bit_vec: BitSet = usizes.into_iter().collect();
-
-        let idxs: Vec<_> = bit_vec.iter().collect();
-        assert_eq!(idxs, [0, 2, 3]);
-
-        let long: BitSet = (0..10000).filter(|&n| n % 2 == 0).collect();
-        let real: Vec<_> = range_step(0, 10000, 2).collect();
-
-        let idxs: Vec<_> = long.iter().collect();
-        assert_eq!(idxs, real);
-    }
-
-    #[test]
-    fn test_bit_set_frombit_vec_init() {
-        let bools = [true, false];
-        let lengths = [10, 64, 100];
-        for &b in &bools {
-            for &l in &lengths {
-                let bitset = BitSet::from_bit_vec(BitVec::from_elem(l, b));
-                assert_eq!(bitset.contains(&1), b);
-                assert_eq!(bitset.contains(&(l-1)), b);
-                assert!(!bitset.contains(&l));
-            }
-        }
-    }
-
-    #[test]
-    fn test_bit_vec_masking() {
-        let b = BitVec::from_elem(140, true);
-        let mut bs = BitSet::from_bit_vec(b);
-        assert!(bs.contains(&139));
-        assert!(!bs.contains(&140));
-        assert!(bs.insert(150));
-        assert!(!bs.contains(&140));
-        assert!(!bs.contains(&149));
-        assert!(bs.contains(&150));
-        assert!(!bs.contains(&151));
-    }
-
-    #[test]
-    fn test_bit_set_basic() {
-        let mut b = BitSet::new();
-        assert!(b.insert(3));
-        assert!(!b.insert(3));
-        assert!(b.contains(&3));
-        assert!(b.insert(4));
-        assert!(!b.insert(4));
-        assert!(b.contains(&3));
-        assert!(b.insert(400));
-        assert!(!b.insert(400));
-        assert!(b.contains(&400));
-        assert_eq!(b.len(), 3);
-    }
-
-    #[test]
-    fn test_bit_set_intersection() {
-        let mut a = BitSet::new();
-        let mut b = BitSet::new();
-
-        assert!(a.insert(11));
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(77));
-        assert!(a.insert(103));
-        assert!(a.insert(5));
-
-        assert!(b.insert(2));
-        assert!(b.insert(11));
-        assert!(b.insert(77));
-        assert!(b.insert(5));
-        assert!(b.insert(3));
-
-        let expected = [3, 5, 11, 77];
-        let actual: Vec<_> = a.intersection(&b).collect();
-        assert_eq!(actual, expected);
-    }
-
-    #[test]
-    fn test_bit_set_difference() {
-        let mut a = BitSet::new();
-        let mut b = BitSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(5));
-        assert!(a.insert(200));
-        assert!(a.insert(500));
-
-        assert!(b.insert(3));
-        assert!(b.insert(200));
-
-        let expected = [1, 5, 500];
-        let actual: Vec<_> = a.difference(&b).collect();
-        assert_eq!(actual, expected);
-    }
-
-    #[test]
-    fn test_bit_set_symmetric_difference() {
-        let mut a = BitSet::new();
-        let mut b = BitSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(5));
-        assert!(a.insert(9));
-        assert!(a.insert(11));
-
-        assert!(b.insert(3));
-        assert!(b.insert(9));
-        assert!(b.insert(14));
-        assert!(b.insert(220));
-
-        let expected = [1, 5, 11, 14, 220];
-        let actual: Vec<_> = a.symmetric_difference(&b).collect();
-        assert_eq!(actual, expected);
-    }
-
-    #[test]
-    fn test_bit_set_union() {
-        let mut a = BitSet::new();
-        let mut b = BitSet::new();
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(5));
-        assert!(a.insert(9));
-        assert!(a.insert(11));
-        assert!(a.insert(160));
-        assert!(a.insert(19));
-        assert!(a.insert(24));
-        assert!(a.insert(200));
-
-        assert!(b.insert(1));
-        assert!(b.insert(5));
-        assert!(b.insert(9));
-        assert!(b.insert(13));
-        assert!(b.insert(19));
-
-        let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160, 200];
-        let actual: Vec<_> = a.union(&b).collect();
-        assert_eq!(actual, expected);
-    }
-
-    #[test]
-    fn test_bit_set_subset() {
-        let mut set1 = BitSet::new();
-        let mut set2 = BitSet::new();
-
-        assert!(set1.is_subset(&set2)); //  {}  {}
-        set2.insert(100);
-        assert!(set1.is_subset(&set2)); //  {}  { 1 }
-        set2.insert(200);
-        assert!(set1.is_subset(&set2)); //  {}  { 1, 2 }
-        set1.insert(200);
-        assert!(set1.is_subset(&set2)); //  { 2 }  { 1, 2 }
-        set1.insert(300);
-        assert!(!set1.is_subset(&set2)); // { 2, 3 }  { 1, 2 }
-        set2.insert(300);
-        assert!(set1.is_subset(&set2)); // { 2, 3 }  { 1, 2, 3 }
-        set2.insert(400);
-        assert!(set1.is_subset(&set2)); // { 2, 3 }  { 1, 2, 3, 4 }
-        set2.remove(&100);
-        assert!(set1.is_subset(&set2)); // { 2, 3 }  { 2, 3, 4 }
-        set2.remove(&300);
-        assert!(!set1.is_subset(&set2)); // { 2, 3 }  { 2, 4 }
-        set1.remove(&300);
-        assert!(set1.is_subset(&set2)); // { 2 }  { 2, 4 }
-    }
-
-    #[test]
-    fn test_bit_set_is_disjoint() {
-        let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01000000]));
-        let c = BitSet::new();
-        let d = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00110000]));
-
-        assert!(!a.is_disjoint(&d));
-        assert!(!d.is_disjoint(&a));
-
-        assert!(a.is_disjoint(&b));
-        assert!(a.is_disjoint(&c));
-        assert!(b.is_disjoint(&a));
-        assert!(b.is_disjoint(&c));
-        assert!(c.is_disjoint(&a));
-        assert!(c.is_disjoint(&b));
-    }
-
-    #[test]
-    fn test_bit_set_union_with() {
-        //a should grow to include larger elements
-        let mut a = BitSet::new();
-        a.insert(0);
-        let mut b = BitSet::new();
-        b.insert(5);
-        let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100]));
-        a.union_with(&b);
-        assert_eq!(a, expected);
-
-        // Standard
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
-        let c = a.clone();
-        a.union_with(&b);
-        b.union_with(&c);
-        assert_eq!(a.len(), 4);
-        assert_eq!(b.len(), 4);
-    }
-
-    #[test]
-    fn test_bit_set_intersect_with() {
-        // Explicitly 0'ed bits
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
-        let c = a.clone();
-        a.intersect_with(&b);
-        b.intersect_with(&c);
-        assert!(a.is_empty());
-        assert!(b.is_empty());
-
-        // Uninitialized bits should behave like 0's
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let mut b = BitSet::new();
-        let c = a.clone();
-        a.intersect_with(&b);
-        b.intersect_with(&c);
-        assert!(a.is_empty());
-        assert!(b.is_empty());
-
-        // Standard
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
-        let c = a.clone();
-        a.intersect_with(&b);
-        b.intersect_with(&c);
-        assert_eq!(a.len(), 2);
-        assert_eq!(b.len(), 2);
-    }
-
-    #[test]
-    fn test_bit_set_difference_with() {
-        // Explicitly 0'ed bits
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
-        let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        a.difference_with(&b);
-        assert!(a.is_empty());
-
-        // Uninitialized bits should behave like 0's
-        let mut a = BitSet::new();
-        let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11111111]));
-        a.difference_with(&b);
-        assert!(a.is_empty());
-
-        // Standard
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
-        let c = a.clone();
-        a.difference_with(&b);
-        b.difference_with(&c);
-        assert_eq!(a.len(), 1);
-        assert_eq!(b.len(), 1);
-    }
-
-    #[test]
-    fn test_bit_set_symmetric_difference_with() {
-        //a should grow to include larger elements
-        let mut a = BitSet::new();
-        a.insert(0);
-        a.insert(1);
-        let mut b = BitSet::new();
-        b.insert(1);
-        b.insert(5);
-        let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100]));
-        a.symmetric_difference_with(&b);
-        assert_eq!(a, expected);
-
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let b = BitSet::new();
-        let c = a.clone();
-        a.symmetric_difference_with(&b);
-        assert_eq!(a, c);
-
-        // Standard
-        let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11100010]));
-        let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101010]));
-        let c = a.clone();
-        a.symmetric_difference_with(&b);
-        b.symmetric_difference_with(&c);
-        assert_eq!(a.len(), 2);
-        assert_eq!(b.len(), 2);
-    }
-
-    #[test]
-    fn test_bit_set_eq() {
-        let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
-        let c = BitSet::new();
-
-        assert!(a == a);
-        assert!(a != b);
-        assert!(a != c);
-        assert!(b == b);
-        assert!(b == c);
-        assert!(c == c);
-    }
-
-    #[test]
-    fn test_bit_set_cmp() {
-        let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
-        let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
-        let c = BitSet::new();
-
-        assert_eq!(a.cmp(&b), Greater);
-        assert_eq!(a.cmp(&c), Greater);
-        assert_eq!(b.cmp(&a), Less);
-        assert_eq!(b.cmp(&c), Equal);
-        assert_eq!(c.cmp(&a), Less);
-        assert_eq!(c.cmp(&b), Equal);
-    }
-
-    #[test]
-    fn test_bit_vec_remove() {
-        let mut a = BitSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.remove(&1));
-
-        assert!(a.insert(100));
-        assert!(a.remove(&100));
-
-        assert!(a.insert(1000));
-        assert!(a.remove(&1000));
-        a.shrink_to_fit();
-    }
-
-    #[test]
-    fn test_bit_vec_clone() {
-        let mut a = BitSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.insert(100));
-        assert!(a.insert(1000));
-
-        let mut b = a.clone();
-
-        assert!(a == b);
-
-        assert!(b.remove(&1));
-        assert!(a.contains(&1));
-
-        assert!(a.remove(&1000));
-        assert!(b.contains(&1000));
-    }
-}
-
-
-
-
-
-#[cfg(test)]
-mod bit_set_bench {
-    use std::prelude::v1::*;
-    use std::rand;
-    use std::rand::Rng;
-    use std::u32;
-    use test::{Bencher, black_box};
-
-    use super::{BitVec, BitSet};
-
-    const BENCH_BITS : usize = 1 << 14;
-
-    fn rng() -> rand::IsaacRng {
-        let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
-        rand::SeedableRng::from_seed(seed)
-    }
-
-    #[bench]
-    fn bench_bit_vecset_small(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bit_vec = BitSet::new();
-        b.iter(|| {
-            for _ in 0..100 {
-                bit_vec.insert((r.next_u32() as usize) % u32::BITS as usize);
-            }
-            black_box(&bit_vec);
-        });
-    }
-
-    #[bench]
-    fn bench_bit_vecset_big(b: &mut Bencher) {
-        let mut r = rng();
-        let mut bit_vec = BitSet::new();
-        b.iter(|| {
-            for _ in 0..100 {
-                bit_vec.insert((r.next_u32() as usize) % BENCH_BITS);
-            }
-            black_box(&bit_vec);
-        });
-    }
-
-    #[bench]
-    fn bench_bit_vecset_iter(b: &mut Bencher) {
-        let bit_vec = BitSet::from_bit_vec(BitVec::from_fn(BENCH_BITS,
-                                              |idx| {idx % 3 == 0}));
-        b.iter(|| {
-            let mut sum = 0;
-            for idx in &bit_vec {
-                sum += idx as usize;
-            }
-            sum
-        })
-    }
-}
diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs
index 5de6cbe61e9..c7e1e3c9176 100644
--- a/src/libcollections/btree/map.rs
+++ b/src/libcollections/btree/map.rs
@@ -64,6 +64,10 @@ use super::node::{self, Node, Found, GoDown};
 /// and possibly other factors. Using linear search, searching for a random element is expected
 /// to take O(B log<sub>B</sub>n) comparisons, which is generally worse than a BST. In practice,
 /// however, performance is excellent.
+///
+/// It is a logic error for a key to be modified in such a way that the key's ordering relative to
+/// any other key, as determined by the `Ord` trait, changes while it is in the map. This is
+/// normally only possible through `Cell`, `RefCell`, global state, I/O, or unsafe code.
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct BTreeMap<K, V> {
@@ -1595,309 +1599,3 @@ impl<K: Ord, V> BTreeMap<K, V> {
         }
     }
 }
-
-
-
-
-
-#[cfg(test)]
-mod test {
-    use prelude::*;
-    use std::iter::range_inclusive;
-
-    use super::BTreeMap;
-    use super::Entry::{Occupied, Vacant};
-    use Bound::{self, Included, Excluded, Unbounded};
-
-    #[test]
-    fn test_basic_large() {
-        let mut map = BTreeMap::new();
-        let size = 10000;
-        assert_eq!(map.len(), 0);
-
-        for i in 0..size {
-            assert_eq!(map.insert(i, 10*i), None);
-            assert_eq!(map.len(), i + 1);
-        }
-
-        for i in 0..size {
-            assert_eq!(map.get(&i).unwrap(), &(i*10));
-        }
-
-        for i in size..size*2 {
-            assert_eq!(map.get(&i), None);
-        }
-
-        for i in 0..size {
-            assert_eq!(map.insert(i, 100*i), Some(10*i));
-            assert_eq!(map.len(), size);
-        }
-
-        for i in 0..size {
-            assert_eq!(map.get(&i).unwrap(), &(i*100));
-        }
-
-        for i in 0..size/2 {
-            assert_eq!(map.remove(&(i*2)), Some(i*200));
-            assert_eq!(map.len(), size - i - 1);
-        }
-
-        for i in 0..size/2 {
-            assert_eq!(map.get(&(2*i)), None);
-            assert_eq!(map.get(&(2*i+1)).unwrap(), &(i*200 + 100));
-        }
-
-        for i in 0..size/2 {
-            assert_eq!(map.remove(&(2*i)), None);
-            assert_eq!(map.remove(&(2*i+1)), Some(i*200 + 100));
-            assert_eq!(map.len(), size/2 - i - 1);
-        }
-    }
-
-    #[test]
-    fn test_basic_small() {
-        let mut map = BTreeMap::new();
-        assert_eq!(map.remove(&1), None);
-        assert_eq!(map.get(&1), None);
-        assert_eq!(map.insert(1, 1), None);
-        assert_eq!(map.get(&1), Some(&1));
-        assert_eq!(map.insert(1, 2), Some(1));
-        assert_eq!(map.get(&1), Some(&2));
-        assert_eq!(map.insert(2, 4), None);
-        assert_eq!(map.get(&2), Some(&4));
-        assert_eq!(map.remove(&1), Some(2));
-        assert_eq!(map.remove(&2), Some(4));
-        assert_eq!(map.remove(&1), None);
-    }
-
-    #[test]
-    fn test_iter() {
-        let size = 10000;
-
-        // Forwards
-        let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
-
-        fn test<T>(size: usize, mut iter: T) where T: Iterator<Item=(usize, usize)> {
-            for i in 0..size {
-                assert_eq!(iter.size_hint(), (size - i, Some(size - i)));
-                assert_eq!(iter.next().unwrap(), (i, i));
-            }
-            assert_eq!(iter.size_hint(), (0, Some(0)));
-            assert_eq!(iter.next(), None);
-        }
-        test(size, map.iter().map(|(&k, &v)| (k, v)));
-        test(size, map.iter_mut().map(|(&k, &mut v)| (k, v)));
-        test(size, map.into_iter());
-    }
-
-    #[test]
-    fn test_iter_rev() {
-        let size = 10000;
-
-        // Forwards
-        let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
-
-        fn test<T>(size: usize, mut iter: T) where T: Iterator<Item=(usize, usize)> {
-            for i in 0..size {
-                assert_eq!(iter.size_hint(), (size - i, Some(size - i)));
-                assert_eq!(iter.next().unwrap(), (size - i - 1, size - i - 1));
-            }
-            assert_eq!(iter.size_hint(), (0, Some(0)));
-            assert_eq!(iter.next(), None);
-        }
-        test(size, map.iter().rev().map(|(&k, &v)| (k, v)));
-        test(size, map.iter_mut().rev().map(|(&k, &mut v)| (k, v)));
-        test(size, map.into_iter().rev());
-    }
-
-    #[test]
-    fn test_iter_mixed() {
-        let size = 10000;
-
-        // Forwards
-        let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
-
-        fn test<T>(size: usize, mut iter: T)
-                where T: Iterator<Item=(usize, usize)> + DoubleEndedIterator {
-            for i in 0..size / 4 {
-                assert_eq!(iter.size_hint(), (size - i * 2, Some(size - i * 2)));
-                assert_eq!(iter.next().unwrap(), (i, i));
-                assert_eq!(iter.next_back().unwrap(), (size - i - 1, size - i - 1));
-            }
-            for i in size / 4..size * 3 / 4 {
-                assert_eq!(iter.size_hint(), (size * 3 / 4 - i, Some(size * 3 / 4 - i)));
-                assert_eq!(iter.next().unwrap(), (i, i));
-            }
-            assert_eq!(iter.size_hint(), (0, Some(0)));
-            assert_eq!(iter.next(), None);
-        }
-        test(size, map.iter().map(|(&k, &v)| (k, v)));
-        test(size, map.iter_mut().map(|(&k, &mut v)| (k, v)));
-        test(size, map.into_iter());
-    }
-
-    #[test]
-    fn test_range_small() {
-        let size = 5;
-
-        // Forwards
-        let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
-
-        let mut j = 0;
-        for ((&k, &v), i) in map.range(Included(&2), Unbounded).zip(2..size) {
-            assert_eq!(k, i);
-            assert_eq!(v, i);
-            j += 1;
-        }
-        assert_eq!(j, size - 2);
-    }
-
-    #[test]
-    fn test_range_1000() {
-        let size = 1000;
-        let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
-
-        fn test(map: &BTreeMap<u32, u32>, size: u32, min: Bound<&u32>, max: Bound<&u32>) {
-            let mut kvs = map.range(min, max).map(|(&k, &v)| (k, v));
-            let mut pairs = (0..size).map(|i| (i, i));
-
-            for (kv, pair) in kvs.by_ref().zip(pairs.by_ref()) {
-                assert_eq!(kv, pair);
-            }
-            assert_eq!(kvs.next(), None);
-            assert_eq!(pairs.next(), None);
-        }
-        test(&map, size, Included(&0), Excluded(&size));
-        test(&map, size, Unbounded, Excluded(&size));
-        test(&map, size, Included(&0), Included(&(size - 1)));
-        test(&map, size, Unbounded, Included(&(size - 1)));
-        test(&map, size, Included(&0), Unbounded);
-        test(&map, size, Unbounded, Unbounded);
-    }
-
-    #[test]
-    fn test_range() {
-        let size = 200;
-        let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
-
-        for i in 0..size {
-            for j in i..size {
-                let mut kvs = map.range(Included(&i), Included(&j)).map(|(&k, &v)| (k, v));
-                let mut pairs = range_inclusive(i, j).map(|i| (i, i));
-
-                for (kv, pair) in kvs.by_ref().zip(pairs.by_ref()) {
-                    assert_eq!(kv, pair);
-                }
-                assert_eq!(kvs.next(), None);
-                assert_eq!(pairs.next(), None);
-            }
-        }
-    }
-
-    #[test]
-    fn test_entry(){
-        let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
-
-        let mut map: BTreeMap<_, _> = xs.iter().cloned().collect();
-
-        // Existing key (insert)
-        match map.entry(1) {
-            Vacant(_) => unreachable!(),
-            Occupied(mut view) => {
-                assert_eq!(view.get(), &10);
-                assert_eq!(view.insert(100), 10);
-            }
-        }
-        assert_eq!(map.get(&1).unwrap(), &100);
-        assert_eq!(map.len(), 6);
-
-
-        // Existing key (update)
-        match map.entry(2) {
-            Vacant(_) => unreachable!(),
-            Occupied(mut view) => {
-                let v = view.get_mut();
-                *v *= 10;
-            }
-        }
-        assert_eq!(map.get(&2).unwrap(), &200);
-        assert_eq!(map.len(), 6);
-
-        // Existing key (take)
-        match map.entry(3) {
-            Vacant(_) => unreachable!(),
-            Occupied(view) => {
-                assert_eq!(view.remove(), 30);
-            }
-        }
-        assert_eq!(map.get(&3), None);
-        assert_eq!(map.len(), 5);
-
-
-        // Inexistent key (insert)
-        match map.entry(10) {
-            Occupied(_) => unreachable!(),
-            Vacant(view) => {
-                assert_eq!(*view.insert(1000), 1000);
-            }
-        }
-        assert_eq!(map.get(&10).unwrap(), &1000);
-        assert_eq!(map.len(), 6);
-    }
-}
-
-
-
-
-
-
-#[cfg(test)]
-mod bench {
-    use prelude::*;
-    use std::rand::{weak_rng, Rng};
-    use test::{Bencher, black_box};
-
-    use super::BTreeMap;
-
-    map_insert_rand_bench!{insert_rand_100,    100,    BTreeMap}
-    map_insert_rand_bench!{insert_rand_10_000, 10_000, BTreeMap}
-
-    map_insert_seq_bench!{insert_seq_100,    100,    BTreeMap}
-    map_insert_seq_bench!{insert_seq_10_000, 10_000, BTreeMap}
-
-    map_find_rand_bench!{find_rand_100,    100,    BTreeMap}
-    map_find_rand_bench!{find_rand_10_000, 10_000, BTreeMap}
-
-    map_find_seq_bench!{find_seq_100,    100,    BTreeMap}
-    map_find_seq_bench!{find_seq_10_000, 10_000, BTreeMap}
-
-    fn bench_iter(b: &mut Bencher, size: i32) {
-        let mut map = BTreeMap::<i32, i32>::new();
-        let mut rng = weak_rng();
-
-        for _ in 0..size {
-            map.insert(rng.gen(), rng.gen());
-        }
-
-        b.iter(|| {
-            for entry in &map {
-                black_box(entry);
-            }
-        });
-    }
-
-    #[bench]
-    pub fn iter_20(b: &mut Bencher) {
-        bench_iter(b, 20);
-    }
-
-    #[bench]
-    pub fn iter_1000(b: &mut Bencher) {
-        bench_iter(b, 1000);
-    }
-
-    #[bench]
-    pub fn iter_100000(b: &mut Bencher) {
-        bench_iter(b, 100000);
-    }
-}
diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs
index f2a6910a302..006d6bb040e 100644
--- a/src/libcollections/btree/node.rs
+++ b/src/libcollections/btree/node.rs
@@ -23,7 +23,7 @@ use core::iter::Zip;
 use core::marker::PhantomData;
 use core::ops::{Deref, DerefMut, Index, IndexMut};
 use core::ptr::Unique;
-use core::{slice, mem, ptr, cmp, num, raw};
+use core::{slice, mem, ptr, cmp, raw};
 use alloc::heap::{self, EMPTY};
 
 use borrow::Borrow;
@@ -105,7 +105,10 @@ struct MutNodeSlice<'a, K: 'a, V: 'a> {
 /// Fails if `target_alignment` is not a power of two.
 #[inline]
 fn round_up_to_next(unrounded: usize, target_alignment: usize) -> usize {
-    assert!(num::UnsignedInt::is_power_of_two(target_alignment));
+    #[cfg(stage0)]
+    use core::num::UnsignedInt;
+
+    assert!(target_alignment.is_power_of_two());
     (unrounded + target_alignment - 1) & !(target_alignment - 1)
 }
 
@@ -348,14 +351,8 @@ impl<K, V> Node<K, V> {
     #[inline]
     pub fn as_slices<'a>(&'a self) -> (&'a [K], &'a [V]) {
         unsafe {(
-            mem::transmute(raw::Slice {
-                data: *self.keys as *const K,
-                len: self.len()
-            }),
-            mem::transmute(raw::Slice {
-                data: *self.vals as *const V,
-                len: self.len()
-            })
+            slice::from_raw_parts(*self.keys, self.len()),
+            slice::from_raw_parts(*self.vals, self.len()),
         )}
     }
 
diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs
index bc2e68b999a..5616d36ce0b 100644
--- a/src/libcollections/btree/set.rs
+++ b/src/libcollections/btree/set.rs
@@ -30,6 +30,10 @@ use Bound;
 ///
 /// See BTreeMap's documentation for a detailed discussion of this collection's performance
 /// benefits and drawbacks.
+///
+/// It is a logic error for an item to be modified in such a way that the item's ordering relative
+/// to any other item, as determined by the `Ord` trait, changes while it is in the set. This is
+/// normally only possible through `Cell`, `RefCell`, global state, I/O, or unsafe code.
 #[derive(Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct BTreeSet<T>{
@@ -738,180 +742,3 @@ impl<'a, T: Ord> Iterator for Union<'a, T> {
         }
     }
 }
-
-
-#[cfg(test)]
-mod test {
-    use prelude::*;
-
-    use super::BTreeSet;
-    use std::hash::{self, SipHasher};
-
-    #[test]
-    fn test_clone_eq() {
-      let mut m = BTreeSet::new();
-
-      m.insert(1);
-      m.insert(2);
-
-      assert!(m.clone() == m);
-    }
-
-    #[test]
-    fn test_hash() {
-      let mut x = BTreeSet::new();
-      let mut y = BTreeSet::new();
-
-      x.insert(1);
-      x.insert(2);
-      x.insert(3);
-
-      y.insert(3);
-      y.insert(2);
-      y.insert(1);
-
-      assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
-    }
-
-    struct Counter<'a, 'b> {
-        i: &'a mut usize,
-        expected: &'b [i32],
-    }
-
-    impl<'a, 'b, 'c> FnMut<(&'c i32,)> for Counter<'a, 'b> {
-        type Output = bool;
-
-        extern "rust-call" fn call_mut(&mut self, (&x,): (&'c i32,)) -> bool {
-            assert_eq!(x, self.expected[*self.i]);
-            *self.i += 1;
-            true
-        }
-    }
-
-    fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F) where
-        // FIXME Replace Counter with `Box<FnMut(_) -> _>`
-        F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, Counter) -> bool,
-    {
-        let mut set_a = BTreeSet::new();
-        let mut set_b = BTreeSet::new();
-
-        for x in a { assert!(set_a.insert(*x)) }
-        for y in b { assert!(set_b.insert(*y)) }
-
-        let mut i = 0;
-        f(&set_a, &set_b, Counter { i: &mut i, expected: expected });
-        assert_eq!(i, expected.len());
-    }
-
-    #[test]
-    fn test_intersection() {
-        fn check_intersection(a: &[i32], b: &[i32], expected: &[i32]) {
-            check(a, b, expected, |x, y, f| x.intersection(y).all(f))
-        }
-
-        check_intersection(&[], &[], &[]);
-        check_intersection(&[1, 2, 3], &[], &[]);
-        check_intersection(&[], &[1, 2, 3], &[]);
-        check_intersection(&[2], &[1, 2, 3], &[2]);
-        check_intersection(&[1, 2, 3], &[2], &[2]);
-        check_intersection(&[11, 1, 3, 77, 103, 5, -5],
-                           &[2, 11, 77, -9, -42, 5, 3],
-                           &[3, 5, 11, 77]);
-    }
-
-    #[test]
-    fn test_difference() {
-        fn check_difference(a: &[i32], b: &[i32], expected: &[i32]) {
-            check(a, b, expected, |x, y, f| x.difference(y).all(f))
-        }
-
-        check_difference(&[], &[], &[]);
-        check_difference(&[1, 12], &[], &[1, 12]);
-        check_difference(&[], &[1, 2, 3, 9], &[]);
-        check_difference(&[1, 3, 5, 9, 11],
-                         &[3, 9],
-                         &[1, 5, 11]);
-        check_difference(&[-5, 11, 22, 33, 40, 42],
-                         &[-12, -5, 14, 23, 34, 38, 39, 50],
-                         &[11, 22, 33, 40, 42]);
-    }
-
-    #[test]
-    fn test_symmetric_difference() {
-        fn check_symmetric_difference(a: &[i32], b: &[i32], expected: &[i32]) {
-            check(a, b, expected, |x, y, f| x.symmetric_difference(y).all(f))
-        }
-
-        check_symmetric_difference(&[], &[], &[]);
-        check_symmetric_difference(&[1, 2, 3], &[2], &[1, 3]);
-        check_symmetric_difference(&[2], &[1, 2, 3], &[1, 3]);
-        check_symmetric_difference(&[1, 3, 5, 9, 11],
-                                   &[-2, 3, 9, 14, 22],
-                                   &[-2, 1, 5, 11, 14, 22]);
-    }
-
-    #[test]
-    fn test_union() {
-        fn check_union(a: &[i32], b: &[i32], expected: &[i32]) {
-            check(a, b, expected, |x, y, f| x.union(y).all(f))
-        }
-
-        check_union(&[], &[], &[]);
-        check_union(&[1, 2, 3], &[2], &[1, 2, 3]);
-        check_union(&[2], &[1, 2, 3], &[1, 2, 3]);
-        check_union(&[1, 3, 5, 9, 11, 16, 19, 24],
-                    &[-2, 1, 5, 9, 13, 19],
-                    &[-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]);
-    }
-
-    #[test]
-    fn test_zip() {
-        let mut x = BTreeSet::new();
-        x.insert(5);
-        x.insert(12);
-        x.insert(11);
-
-        let mut y = BTreeSet::new();
-        y.insert("foo");
-        y.insert("bar");
-
-        let x = x;
-        let y = y;
-        let mut z = x.iter().zip(y.iter());
-
-        // FIXME: #5801: this needs a type hint to compile...
-        let result: Option<(&usize, & &'static str)> = z.next();
-        assert_eq!(result.unwrap(), (&5, &("bar")));
-
-        let result: Option<(&usize, & &'static str)> = z.next();
-        assert_eq!(result.unwrap(), (&11, &("foo")));
-
-        let result: Option<(&usize, & &'static str)> = z.next();
-        assert!(result.is_none());
-    }
-
-    #[test]
-    fn test_from_iter() {
-        let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9];
-
-        let set: BTreeSet<_> = xs.iter().cloned().collect();
-
-        for x in &xs {
-            assert!(set.contains(x));
-        }
-    }
-
-    #[test]
-    fn test_show() {
-        let mut set = BTreeSet::new();
-        let empty = BTreeSet::<i32>::new();
-
-        set.insert(1);
-        set.insert(2);
-
-        let set_str = format!("{:?}", set);
-
-        assert_eq!(set_str, "{1, 2}");
-        assert_eq!(format!("{:?}", empty), "{}");
-    }
-}
diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs
index 68ff94cfbfb..fe2efc7164d 100644
--- a/src/libcollections/enum_set.rs
+++ b/src/libcollections/enum_set.rs
@@ -24,6 +24,11 @@ use core::ops::{Sub, BitOr, BitAnd, BitXor};
 
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 /// A specialized set implementation to use enum types.
+///
+/// It is a logic error for an item to be modified in such a way that the transformation of the
+/// item to or from a `usize`, as determined by the `CLike` trait, changes while the item is in the
+/// set. This is normally only possible through `Cell`, `RefCell`, global state, I/O, or unsafe
+/// code.
 pub struct EnumSet<E> {
     // We must maintain the invariant that no bits are set
     // for which no variant exists
@@ -280,241 +285,3 @@ impl<E:CLike> Extend<E> for EnumSet<E> {
         }
     }
 }
-
-#[cfg(test)]
-mod test {
-    use self::Foo::*;
-    use prelude::*;
-    use core::mem;
-
-    use super::{EnumSet, CLike};
-
-    #[derive(Copy, PartialEq, Debug)]
-    #[repr(usize)]
-    enum Foo {
-        A, B, C
-    }
-
-    impl CLike for Foo {
-        fn to_usize(&self) -> usize {
-            *self as usize
-        }
-
-        fn from_usize(v: usize) -> Foo {
-            unsafe { mem::transmute(v) }
-        }
-    }
-
-    #[test]
-    fn test_new() {
-        let e: EnumSet<Foo> = EnumSet::new();
-        assert!(e.is_empty());
-    }
-
-    #[test]
-    fn test_show() {
-        let mut e = EnumSet::new();
-        assert!(format!("{:?}", e) == "{}");
-        e.insert(A);
-        assert!(format!("{:?}", e) == "{A}");
-        e.insert(C);
-        assert!(format!("{:?}", e) == "{A, C}");
-    }
-
-    #[test]
-    fn test_len() {
-        let mut e = EnumSet::new();
-        assert_eq!(e.len(), 0);
-        e.insert(A);
-        e.insert(B);
-        e.insert(C);
-        assert_eq!(e.len(), 3);
-        e.remove(&A);
-        assert_eq!(e.len(), 2);
-        e.clear();
-        assert_eq!(e.len(), 0);
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // intersect
-
-    #[test]
-    fn test_two_empties_do_not_intersect() {
-        let e1: EnumSet<Foo> = EnumSet::new();
-        let e2: EnumSet<Foo> = EnumSet::new();
-        assert!(e1.is_disjoint(&e2));
-    }
-
-    #[test]
-    fn test_empty_does_not_intersect_with_full() {
-        let e1: EnumSet<Foo> = EnumSet::new();
-
-        let mut e2: EnumSet<Foo> = EnumSet::new();
-        e2.insert(A);
-        e2.insert(B);
-        e2.insert(C);
-
-        assert!(e1.is_disjoint(&e2));
-    }
-
-    #[test]
-    fn test_disjoint_intersects() {
-        let mut e1: EnumSet<Foo> = EnumSet::new();
-        e1.insert(A);
-
-        let mut e2: EnumSet<Foo> = EnumSet::new();
-        e2.insert(B);
-
-        assert!(e1.is_disjoint(&e2));
-    }
-
-    #[test]
-    fn test_overlapping_intersects() {
-        let mut e1: EnumSet<Foo> = EnumSet::new();
-        e1.insert(A);
-
-        let mut e2: EnumSet<Foo> = EnumSet::new();
-        e2.insert(A);
-        e2.insert(B);
-
-        assert!(!e1.is_disjoint(&e2));
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // contains and contains_elem
-
-    #[test]
-    fn test_superset() {
-        let mut e1: EnumSet<Foo> = EnumSet::new();
-        e1.insert(A);
-
-        let mut e2: EnumSet<Foo> = EnumSet::new();
-        e2.insert(A);
-        e2.insert(B);
-
-        let mut e3: EnumSet<Foo> = EnumSet::new();
-        e3.insert(C);
-
-        assert!(e1.is_subset(&e2));
-        assert!(e2.is_superset(&e1));
-        assert!(!e3.is_superset(&e2));
-        assert!(!e2.is_superset(&e3))
-    }
-
-    #[test]
-    fn test_contains() {
-        let mut e1: EnumSet<Foo> = EnumSet::new();
-        e1.insert(A);
-        assert!(e1.contains(&A));
-        assert!(!e1.contains(&B));
-        assert!(!e1.contains(&C));
-
-        e1.insert(A);
-        e1.insert(B);
-        assert!(e1.contains(&A));
-        assert!(e1.contains(&B));
-        assert!(!e1.contains(&C));
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // iter
-
-    #[test]
-    fn test_iterator() {
-        let mut e1: EnumSet<Foo> = EnumSet::new();
-
-        let elems: ::vec::Vec<Foo> = e1.iter().collect();
-        assert!(elems.is_empty());
-
-        e1.insert(A);
-        let elems: ::vec::Vec<_> = e1.iter().collect();
-        assert_eq!([A], elems);
-
-        e1.insert(C);
-        let elems: ::vec::Vec<_> = e1.iter().collect();
-        assert_eq!([A,C], elems);
-
-        e1.insert(C);
-        let elems: ::vec::Vec<_> = e1.iter().collect();
-        assert_eq!([A,C], elems);
-
-        e1.insert(B);
-        let elems: ::vec::Vec<_> = e1.iter().collect();
-        assert_eq!([A,B,C], elems);
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // operators
-
-    #[test]
-    fn test_operators() {
-        let mut e1: EnumSet<Foo> = EnumSet::new();
-        e1.insert(A);
-        e1.insert(C);
-
-        let mut e2: EnumSet<Foo> = EnumSet::new();
-        e2.insert(B);
-        e2.insert(C);
-
-        let e_union = e1 | e2;
-        let elems: ::vec::Vec<_> = e_union.iter().collect();
-        assert_eq!([A,B,C], elems);
-
-        let e_intersection = e1 & e2;
-        let elems: ::vec::Vec<_> = e_intersection.iter().collect();
-        assert_eq!([C], elems);
-
-        // Another way to express intersection
-        let e_intersection = e1 - (e1 - e2);
-        let elems: ::vec::Vec<_> = e_intersection.iter().collect();
-        assert_eq!([C], elems);
-
-        let e_subtract = e1 - e2;
-        let elems: ::vec::Vec<_> = e_subtract.iter().collect();
-        assert_eq!([A], elems);
-
-        // Bitwise XOR of two sets, aka symmetric difference
-        let e_symmetric_diff = e1 ^ e2;
-        let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect();
-        assert_eq!([A,B], elems);
-
-        // Another way to express symmetric difference
-        let e_symmetric_diff = (e1 - e2) | (e2 - e1);
-        let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect();
-        assert_eq!([A,B], elems);
-
-        // Yet another way to express symmetric difference
-        let e_symmetric_diff = (e1 | e2) - (e1 & e2);
-        let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect();
-        assert_eq!([A,B], elems);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_overflow() {
-        #[allow(dead_code)]
-        #[derive(Copy)]
-        #[repr(usize)]
-        enum Bar {
-            V00, V01, V02, V03, V04, V05, V06, V07, V08, V09,
-            V10, V11, V12, V13, V14, V15, V16, V17, V18, V19,
-            V20, V21, V22, V23, V24, V25, V26, V27, V28, V29,
-            V30, V31, V32, V33, V34, V35, V36, V37, V38, V39,
-            V40, V41, V42, V43, V44, V45, V46, V47, V48, V49,
-            V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
-            V60, V61, V62, V63, V64, V65, V66, V67, V68, V69,
-        }
-
-        impl CLike for Bar {
-            fn to_usize(&self) -> usize {
-                *self as usize
-            }
-
-            fn from_usize(v: usize) -> Bar {
-                unsafe { mem::transmute(v) }
-            }
-        }
-        let mut set = EnumSet::new();
-        set.insert(Bar::V64);
-    }
-}
diff --git a/src/libcollections/fmt.rs b/src/libcollections/fmt.rs
index ae439b06a5b..1deb08ad0d1 100644
--- a/src/libcollections/fmt.rs
+++ b/src/libcollections/fmt.rs
@@ -434,15 +434,3 @@ pub fn format(args: Arguments) -> string::String {
     let _ = write!(&mut output, "{}", args);
     output
 }
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use fmt;
-
-    #[test]
-    fn test_format() {
-        let s = fmt::format(format_args!("Hello, {}!", "world"));
-        assert_eq!(s.as_slice(), "Hello, world!");
-    }
-}
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index f7943c0bb91..b75f346c188 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -27,12 +27,14 @@
 #![feature(box_syntax)]
 #![feature(box_patterns)]
 #![feature(core)]
+#![feature(lang_items)]
 #![feature(staged_api)]
 #![feature(unboxed_closures)]
 #![feature(unicode)]
 #![feature(unsafe_destructor)]
 #![feature(unique)]
 #![feature(unsafe_no_drop_flag)]
+#![feature(step_by)]
 #![cfg_attr(test, feature(rand, rustc_private, test))]
 #![cfg_attr(test, allow(deprecated))] // rand
 
@@ -45,9 +47,8 @@ extern crate core;
 extern crate unicode;
 extern crate alloc;
 
-#[cfg(test)] extern crate test;
 #[cfg(test)] #[macro_use] extern crate std;
-#[cfg(test)] #[macro_use] extern crate log;
+#[cfg(test)] extern crate test;
 
 pub use binary_heap::BinaryHeap;
 pub use bit_vec::BitVec;
@@ -83,8 +84,6 @@ pub use alloc::boxed;
 #[macro_use]
 mod macros;
 
-#[cfg(test)] #[macro_use] mod bench;
-
 pub mod binary_heap;
 mod bit;
 mod btree;
@@ -140,40 +139,6 @@ mod std {
     pub use core::ops;      // RangeFull
 }
 
-#[cfg(test)]
-mod prelude {
-    // from core.
-    pub use core::clone::Clone;
-    pub use core::cmp::{PartialEq, Eq, PartialOrd, Ord};
-    pub use core::cmp::Ordering::{Less, Equal, Greater};
-    pub use core::iter::range;
-    pub use core::iter::{FromIterator, Extend, IteratorExt};
-    pub use core::iter::{Iterator, DoubleEndedIterator, RandomAccessIterator};
-    pub use core::iter::{ExactSizeIterator};
-    pub use core::marker::{Copy, Send, Sized, Sync};
-    pub use core::mem::drop;
-    pub use core::ops::{Drop, Fn, FnMut, FnOnce};
-    pub use core::option::Option;
-    pub use core::option::Option::{Some, None};
-    pub use core::ptr::PtrExt;
-    pub use core::result::Result;
-    pub use core::result::Result::{Ok, Err};
-
-    // in core and collections (may differ).
-    pub use slice::{AsSlice, SliceExt};
-    pub use str::{Str, StrExt};
-
-    // from other crates.
-    pub use alloc::boxed::Box;
-    pub use unicode::char::CharExt;
-
-    // from collections.
-    pub use borrow::IntoCow;
-    pub use slice::SliceConcatExt;
-    pub use string::{String, ToString};
-    pub use vec::Vec;
-}
-
 /// An endpoint of a range of keys.
 #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
 pub enum Bound<T> {
diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs
index 5ca3cb38058..9e0a6d04381 100644
--- a/src/libcollections/linked_list.rs
+++ b/src/libcollections/linked_list.rs
@@ -940,16 +940,21 @@ impl<A: Hash> Hash for LinkedList<A> {
 }
 
 #[cfg(test)]
-mod tests {
-    use prelude::*;
+mod test {
+    use std::clone::Clone;
+    use std::iter::{Iterator, IteratorExt};
+    use std::option::Option::{Some, None, self};
     use std::rand;
-    use std::hash::{self, SipHasher};
     use std::thread;
-    use test::Bencher;
-    use test;
+    use std::vec::Vec;
 
     use super::{LinkedList, Node};
 
+    #[cfg(test)]
+    fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
+        v.iter().cloned().collect()
+    }
+
     pub fn check_links<T>(list: &LinkedList<T>) {
         let mut len = 0;
         let mut last_ptr: Option<&Node<T>> = None;
@@ -983,56 +988,6 @@ mod tests {
     }
 
     #[test]
-    fn test_basic() {
-        let mut m = LinkedList::<Box<_>>::new();
-        assert_eq!(m.pop_front(), None);
-        assert_eq!(m.pop_back(), None);
-        assert_eq!(m.pop_front(), None);
-        m.push_front(box 1);
-        assert_eq!(m.pop_front(), Some(box 1));
-        m.push_back(box 2);
-        m.push_back(box 3);
-        assert_eq!(m.len(), 2);
-        assert_eq!(m.pop_front(), Some(box 2));
-        assert_eq!(m.pop_front(), Some(box 3));
-        assert_eq!(m.len(), 0);
-        assert_eq!(m.pop_front(), None);
-        m.push_back(box 1);
-        m.push_back(box 3);
-        m.push_back(box 5);
-        m.push_back(box 7);
-        assert_eq!(m.pop_front(), Some(box 1));
-
-        let mut n = LinkedList::new();
-        n.push_front(2);
-        n.push_front(3);
-        {
-            assert_eq!(n.front().unwrap(), &3);
-            let x = n.front_mut().unwrap();
-            assert_eq!(*x, 3);
-            *x = 0;
-        }
-        {
-            assert_eq!(n.back().unwrap(), &2);
-            let y = n.back_mut().unwrap();
-            assert_eq!(*y, 2);
-            *y = 1;
-        }
-        assert_eq!(n.pop_front(), Some(0));
-        assert_eq!(n.pop_front(), Some(1));
-    }
-
-    #[cfg(test)]
-    fn generate_test() -> LinkedList<i32> {
-        list_from(&[0,1,2,3,4,5,6])
-    }
-
-    #[cfg(test)]
-    fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
-        v.iter().cloned().collect()
-    }
-
-    #[test]
     fn test_append() {
         // Empty to empty
         {
@@ -1090,166 +1045,6 @@ mod tests {
     }
 
     #[test]
-    fn test_split_off() {
-        // singleton
-        {
-            let mut m = LinkedList::new();
-            m.push_back(1);
-
-            let p = m.split_off(0);
-            assert_eq!(m.len(), 0);
-            assert_eq!(p.len(), 1);
-            assert_eq!(p.back(), Some(&1));
-            assert_eq!(p.front(), Some(&1));
-        }
-
-        // not singleton, forwards
-        {
-            let u = vec![1,2,3,4,5];
-            let mut m = list_from(&u);
-            let mut n = m.split_off(2);
-            assert_eq!(m.len(), 2);
-            assert_eq!(n.len(), 3);
-            for elt in 1..3 {
-                assert_eq!(m.pop_front(), Some(elt));
-            }
-            for elt in 3..6 {
-                assert_eq!(n.pop_front(), Some(elt));
-            }
-        }
-        // not singleton, backwards
-        {
-            let u = vec![1,2,3,4,5];
-            let mut m = list_from(&u);
-            let mut n = m.split_off(4);
-            assert_eq!(m.len(), 4);
-            assert_eq!(n.len(), 1);
-            for elt in 1..5 {
-                assert_eq!(m.pop_front(), Some(elt));
-            }
-            for elt in 5..6 {
-                assert_eq!(n.pop_front(), Some(elt));
-            }
-        }
-
-        // no-op on the last index
-        {
-            let mut m = LinkedList::new();
-            m.push_back(1);
-
-            let p = m.split_off(1);
-            assert_eq!(m.len(), 1);
-            assert_eq!(p.len(), 0);
-            assert_eq!(m.back(), Some(&1));
-            assert_eq!(m.front(), Some(&1));
-        }
-
-    }
-
-    #[test]
-    fn test_iterator() {
-        let m = generate_test();
-        for (i, elt) in m.iter().enumerate() {
-            assert_eq!(i as i32, *elt);
-        }
-        let mut n = LinkedList::new();
-        assert_eq!(n.iter().next(), None);
-        n.push_front(4);
-        let mut it = n.iter();
-        assert_eq!(it.size_hint(), (1, Some(1)));
-        assert_eq!(it.next().unwrap(), &4);
-        assert_eq!(it.size_hint(), (0, Some(0)));
-        assert_eq!(it.next(), None);
-    }
-
-    #[test]
-    fn test_iterator_clone() {
-        let mut n = LinkedList::new();
-        n.push_back(2);
-        n.push_back(3);
-        n.push_back(4);
-        let mut it = n.iter();
-        it.next();
-        let mut jt = it.clone();
-        assert_eq!(it.next(), jt.next());
-        assert_eq!(it.next_back(), jt.next_back());
-        assert_eq!(it.next(), jt.next());
-    }
-
-    #[test]
-    fn test_iterator_double_end() {
-        let mut n = LinkedList::new();
-        assert_eq!(n.iter().next(), None);
-        n.push_front(4);
-        n.push_front(5);
-        n.push_front(6);
-        let mut it = n.iter();
-        assert_eq!(it.size_hint(), (3, Some(3)));
-        assert_eq!(it.next().unwrap(), &6);
-        assert_eq!(it.size_hint(), (2, Some(2)));
-        assert_eq!(it.next_back().unwrap(), &4);
-        assert_eq!(it.size_hint(), (1, Some(1)));
-        assert_eq!(it.next_back().unwrap(), &5);
-        assert_eq!(it.next_back(), None);
-        assert_eq!(it.next(), None);
-    }
-
-    #[test]
-    fn test_rev_iter() {
-        let m = generate_test();
-        for (i, elt) in m.iter().rev().enumerate() {
-            assert_eq!((6 - i) as i32, *elt);
-        }
-        let mut n = LinkedList::new();
-        assert_eq!(n.iter().rev().next(), None);
-        n.push_front(4);
-        let mut it = n.iter().rev();
-        assert_eq!(it.size_hint(), (1, Some(1)));
-        assert_eq!(it.next().unwrap(), &4);
-        assert_eq!(it.size_hint(), (0, Some(0)));
-        assert_eq!(it.next(), None);
-    }
-
-    #[test]
-    fn test_mut_iter() {
-        let mut m = generate_test();
-        let mut len = m.len();
-        for (i, elt) in m.iter_mut().enumerate() {
-            assert_eq!(i as i32, *elt);
-            len -= 1;
-        }
-        assert_eq!(len, 0);
-        let mut n = LinkedList::new();
-        assert!(n.iter_mut().next().is_none());
-        n.push_front(4);
-        n.push_back(5);
-        let mut it = n.iter_mut();
-        assert_eq!(it.size_hint(), (2, Some(2)));
-        assert!(it.next().is_some());
-        assert!(it.next().is_some());
-        assert_eq!(it.size_hint(), (0, Some(0)));
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_iterator_mut_double_end() {
-        let mut n = LinkedList::new();
-        assert!(n.iter_mut().next_back().is_none());
-        n.push_front(4);
-        n.push_front(5);
-        n.push_front(6);
-        let mut it = n.iter_mut();
-        assert_eq!(it.size_hint(), (3, Some(3)));
-        assert_eq!(*it.next().unwrap(), 6);
-        assert_eq!(it.size_hint(), (2, Some(2)));
-        assert_eq!(*it.next_back().unwrap(), 4);
-        assert_eq!(it.size_hint(), (1, Some(1)));
-        assert_eq!(*it.next_back().unwrap(), 5);
-        assert!(it.next_back().is_none());
-        assert!(it.next().is_none());
-    }
-
-    #[test]
     fn test_insert_prev() {
         let mut m = list_from(&[0,2,4,6,8]);
         let len = m.len();
@@ -1277,20 +1072,6 @@ mod tests {
     }
 
     #[test]
-    fn test_mut_rev_iter() {
-        let mut m = generate_test();
-        for (i, elt) in m.iter_mut().rev().enumerate() {
-            assert_eq!((6 - i) as i32, *elt);
-        }
-        let mut n = LinkedList::new();
-        assert!(n.iter_mut().rev().next().is_none());
-        n.push_front(4);
-        let mut it = n.iter_mut().rev();
-        assert!(it.next().is_some());
-        assert!(it.next().is_none());
-    }
-
-    #[test]
     fn test_send() {
         let n = list_from(&[1,2,3]);
         thread::spawn(move || {
@@ -1301,81 +1082,6 @@ mod tests {
     }
 
     #[test]
-    fn test_eq() {
-        let mut n = list_from(&[]);
-        let mut m = list_from(&[]);
-        assert!(n == m);
-        n.push_front(1);
-        assert!(n != m);
-        m.push_back(1);
-        assert!(n == m);
-
-        let n = list_from(&[2,3,4]);
-        let m = list_from(&[1,2,3]);
-        assert!(n != m);
-    }
-
-    #[test]
-    fn test_hash() {
-      let mut x = LinkedList::new();
-      let mut y = LinkedList::new();
-
-      assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
-
-      x.push_back(1);
-      x.push_back(2);
-      x.push_back(3);
-
-      y.push_front(3);
-      y.push_front(2);
-      y.push_front(1);
-
-      assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
-    }
-
-    #[test]
-    fn test_ord() {
-        let n = list_from(&[]);
-        let m = list_from(&[1,2,3]);
-        assert!(n < m);
-        assert!(m > n);
-        assert!(n <= n);
-        assert!(n >= n);
-    }
-
-    #[test]
-    fn test_ord_nan() {
-        let nan = 0.0f64/0.0;
-        let n = list_from(&[nan]);
-        let m = list_from(&[nan]);
-        assert!(!(n < m));
-        assert!(!(n > m));
-        assert!(!(n <= m));
-        assert!(!(n >= m));
-
-        let n = list_from(&[nan]);
-        let one = list_from(&[1.0f64]);
-        assert!(!(n < one));
-        assert!(!(n > one));
-        assert!(!(n <= one));
-        assert!(!(n >= one));
-
-        let u = list_from(&[1.0f64,2.0,nan]);
-        let v = list_from(&[1.0f64,2.0,3.0]);
-        assert!(!(u < v));
-        assert!(!(u > v));
-        assert!(!(u <= v));
-        assert!(!(u >= v));
-
-        let s = list_from(&[1.0f64,2.0,4.0,2.0]);
-        let t = list_from(&[1.0f64,2.0,3.0,2.0]);
-        assert!(!(s < t));
-        assert!(s > one);
-        assert!(!(s <= one));
-        assert!(s >= one);
-    }
-
-    #[test]
     fn test_fuzz() {
         for _ in 0..25 {
             fuzz_test(3);
@@ -1384,15 +1090,6 @@ mod tests {
         }
     }
 
-    #[test]
-    fn test_show() {
-        let list: LinkedList<_> = (0..10).collect();
-        assert_eq!(format!("{:?}", list), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
-
-        let list: LinkedList<_> = vec!["just", "one", "test", "more"].iter().cloned().collect();
-        assert_eq!(format!("{:?}", list), "[\"just\", \"one\", \"test\", \"more\"]");
-    }
-
     #[cfg(test)]
     fn fuzz_test(sz: i32) {
         let mut m: LinkedList<_> = LinkedList::new();
@@ -1431,79 +1128,4 @@ mod tests {
         }
         assert_eq!(i, v.len());
     }
-
-    #[bench]
-    fn bench_collect_into(b: &mut test::Bencher) {
-        let v = &[0; 64];
-        b.iter(|| {
-            let _: LinkedList<_> = v.iter().cloned().collect();
-        })
-    }
-
-    #[bench]
-    fn bench_push_front(b: &mut test::Bencher) {
-        let mut m: LinkedList<_> = LinkedList::new();
-        b.iter(|| {
-            m.push_front(0);
-        })
-    }
-
-    #[bench]
-    fn bench_push_back(b: &mut test::Bencher) {
-        let mut m: LinkedList<_> = LinkedList::new();
-        b.iter(|| {
-            m.push_back(0);
-        })
-    }
-
-    #[bench]
-    fn bench_push_back_pop_back(b: &mut test::Bencher) {
-        let mut m: LinkedList<_> = LinkedList::new();
-        b.iter(|| {
-            m.push_back(0);
-            m.pop_back();
-        })
-    }
-
-    #[bench]
-    fn bench_push_front_pop_front(b: &mut test::Bencher) {
-        let mut m: LinkedList<_> = LinkedList::new();
-        b.iter(|| {
-            m.push_front(0);
-            m.pop_front();
-        })
-    }
-
-    #[bench]
-    fn bench_iter(b: &mut test::Bencher) {
-        let v = &[0; 128];
-        let m: LinkedList<_> = v.iter().cloned().collect();
-        b.iter(|| {
-            assert!(m.iter().count() == 128);
-        })
-    }
-    #[bench]
-    fn bench_iter_mut(b: &mut test::Bencher) {
-        let v = &[0; 128];
-        let mut m: LinkedList<_> = v.iter().cloned().collect();
-        b.iter(|| {
-            assert!(m.iter_mut().count() == 128);
-        })
-    }
-    #[bench]
-    fn bench_iter_rev(b: &mut test::Bencher) {
-        let v = &[0; 128];
-        let m: LinkedList<_> = v.iter().cloned().collect();
-        b.iter(|| {
-            assert!(m.iter().rev().count() == 128);
-        })
-    }
-    #[bench]
-    fn bench_iter_mut_rev(b: &mut test::Bencher) {
-        let v = &[0; 128];
-        let mut m: LinkedList<_> = v.iter().cloned().collect();
-        b.iter(|| {
-            assert!(m.iter_mut().rev().count() == 128);
-        })
-    }
 }
diff --git a/src/libcollections/macros.rs b/src/libcollections/macros.rs
index 0f6a85d75da..3c7326dbd8f 100644
--- a/src/libcollections/macros.rs
+++ b/src/libcollections/macros.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(stage0)]
 /// Creates a `Vec` containing the arguments.
 ///
 /// `vec!` allows `Vec`s to be defined with the same syntax as array expressions.
@@ -45,6 +46,60 @@ macro_rules! vec {
     ($($x:expr,)*) => (vec![$($x),*])
 }
 
+#[cfg(not(stage0))]
+/// Creates a `Vec` containing the arguments.
+///
+/// `vec!` allows `Vec`s to be defined with the same syntax as array expressions.
+/// There are two forms of this macro:
+///
+/// - Create a `Vec` containing a given list of elements:
+///
+/// ```
+/// let v = vec![1, 2, 3];
+/// assert_eq!(v[0], 1);
+/// assert_eq!(v[1], 2);
+/// assert_eq!(v[2], 3);
+/// ```
+///
+/// - Create a `Vec` from a given element and size:
+///
+/// ```
+/// let v = vec![1; 3];
+/// assert_eq!(v, [1, 1, 1]);
+/// ```
+///
+/// Note that unlike array expressions this syntax supports all elements
+/// which implement `Clone` and the number of elements doesn't have to be
+/// a constant.
+#[cfg(not(test))]
+#[macro_export]
+#[stable(feature = "rust1", since = "1.0.0")]
+macro_rules! vec {
+    ($elem:expr; $n:expr) => (
+        $crate::vec::from_elem($elem, $n)
+    );
+    ($($x:expr),*) => (
+        <[_]>::into_vec($crate::boxed::Box::new([$($x),*]))
+    );
+    ($($x:expr,)*) => (vec![$($x),*])
+}
+
+// HACK(japaric): with cfg(test) the inherent `[T]::into_vec` method, which is required for this
+// macro definition, is not available. Instead use the `slice::into_vec`  function which is only
+// available with cfg(test)
+// NB see the slice::hack module in slice.rs for more information
+#[cfg(not(stage0))]
+#[cfg(test)]
+macro_rules! vec {
+    ($elem:expr; $n:expr) => (
+        $crate::vec::from_elem($elem, $n)
+    );
+    ($($x:expr),*) => (
+        $crate::slice::into_vec($crate::boxed::Box::new([$($x),*]))
+    );
+    ($($x:expr,)*) => (vec![$($x),*])
+}
+
 /// Use the syntax described in `std::fmt` to create a value of type `String`.
 /// See `std::fmt` for more information.
 ///
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 76fda8485ab..4993994d46b 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -92,13 +92,14 @@ use core::clone::Clone;
 use core::cmp::Ordering::{self, Greater, Less};
 use core::cmp::{self, Ord, PartialEq};
 use core::iter::{Iterator, IteratorExt};
-use core::iter::{range_step, MultiplicativeIterator};
+use core::iter::MultiplicativeIterator;
 use core::marker::Sized;
 use core::mem::size_of;
 use core::mem;
 use core::num::wrapping::WrappingOps;
 use core::ops::FnMut;
 use core::option::Option::{self, Some, None};
+#[cfg(stage0)]
 use core::ptr::PtrExt;
 use core::ptr;
 use core::result::Result;
@@ -120,6 +121,7 @@ pub use core::slice::{from_raw_buf, from_raw_mut_buf};
 // Basic slice extension methods
 ////////////////////////////////////////////////////////////////////////////////
 
+#[cfg(stage0)]
 /// Allocating extension methods for slices.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait SliceExt {
@@ -795,6 +797,7 @@ pub trait SliceExt {
     fn into_vec(self: Box<Self>) -> Vec<Self::Item>;
 }
 
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> SliceExt for [T] {
     type Item = T;
@@ -1080,6 +1083,942 @@ impl<T> SliceExt for [T] {
     }
 }
 
+// HACK(japaric) needed for the implementation of `vec!` macro during testing
+// NB see the hack module in this file for more details
+#[cfg(not(stage0))]
+#[cfg(test)]
+pub use self::hack::into_vec;
+
+// HACK(japaric) needed for the implementation of `Vec::clone` during testing
+// NB see the hack module in this file for more details
+#[cfg(not(stage0))]
+#[cfg(test)]
+pub use self::hack::to_vec;
+
+// HACK(japaric): With cfg(test) `impl [T]` is not available, these three functions are actually
+// methods that are in `impl [T]` but not in `core::slice::SliceExt` - we need to supply these
+// functions for the `test_permutations` test
+#[cfg(not(stage0))]
+mod hack {
+    use alloc::boxed::Box;
+    use core::clone::Clone;
+    #[cfg(test)]
+    use core::iter::{Iterator, IteratorExt};
+    use core::mem;
+    #[cfg(test)]
+    use core::option::Option::{Some, None};
+
+    #[cfg(test)]
+    use string::ToString;
+    use vec::Vec;
+
+    use super::{ElementSwaps, Permutations};
+
+    pub fn into_vec<T>(mut b: Box<[T]>) -> Vec<T> {
+        unsafe {
+            let xs = Vec::from_raw_parts(b.as_mut_ptr(), b.len(), b.len());
+            mem::forget(b);
+            xs
+        }
+    }
+
+    pub fn permutations<T>(s: &[T]) -> Permutations<T> where T: Clone {
+        Permutations{
+            swaps: ElementSwaps::new(s.len()),
+            v: to_vec(s),
+        }
+    }
+
+    #[inline]
+    pub fn to_vec<T>(s: &[T]) -> Vec<T> where T: Clone {
+        let mut vector = Vec::with_capacity(s.len());
+        vector.push_all(s);
+        vector
+    }
+
+    // NB we can remove this hack if we move this test to libcollectionstest - but that can't be
+    // done right now because the test needs access to the private fields of Permutations
+    #[test]
+    fn test_permutations() {
+        {
+            let v: [i32; 0] = [];
+            let mut it = permutations(&v);
+            let (min_size, max_opt) = it.size_hint();
+            assert_eq!(min_size, 1);
+            assert_eq!(max_opt.unwrap(), 1);
+            assert_eq!(it.next(), Some(to_vec(&v)));
+            assert_eq!(it.next(), None);
+        }
+        {
+            let v = ["Hello".to_string()];
+            let mut it = permutations(&v);
+            let (min_size, max_opt) = it.size_hint();
+            assert_eq!(min_size, 1);
+            assert_eq!(max_opt.unwrap(), 1);
+            assert_eq!(it.next(), Some(to_vec(&v)));
+            assert_eq!(it.next(), None);
+        }
+        {
+            let v = [1, 2, 3];
+            let mut it = permutations(&v);
+            let (min_size, max_opt) = it.size_hint();
+            assert_eq!(min_size, 3*2);
+            assert_eq!(max_opt.unwrap(), 3*2);
+            assert_eq!(it.next().unwrap(), [1,2,3]);
+            assert_eq!(it.next().unwrap(), [1,3,2]);
+            assert_eq!(it.next().unwrap(), [3,1,2]);
+            let (min_size, max_opt) = it.size_hint();
+            assert_eq!(min_size, 3);
+            assert_eq!(max_opt.unwrap(), 3);
+            assert_eq!(it.next().unwrap(), [3,2,1]);
+            assert_eq!(it.next().unwrap(), [2,3,1]);
+            assert_eq!(it.next().unwrap(), [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;
+            let mut it = permutations(&v);
+            let (min_size, max_opt) = it.size_hint();
+            for _perm in it.by_ref() {
+                amt += 1;
+            }
+            assert_eq!(amt, it.swaps.swaps_made);
+            assert_eq!(amt, min_size);
+            assert_eq!(amt, 2 * 3 * 4 * 5 * 6);
+            assert_eq!(amt, max_opt.unwrap());
+        }
+    }
+}
+
+#[cfg(not(stage0))]
+/// Allocating extension methods for slices.
+#[lang = "slice"]
+#[cfg(not(test))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> [T] {
+    /// Sorts the slice, 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`.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// let mut v = [5, 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]);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sort_by<F>(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering {
+        merge_sort(self, compare)
+    }
+
+    /// 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 `src` to stop copying from
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// let mut a = [1, 2, 3, 4, 5];
+    /// let b = vec![6, 7, 8];
+    /// let num_moved = a.move_from(b, 0, 3);
+    /// assert_eq!(num_moved, 3);
+    /// assert!(a == [6, 7, 8, 4, 5]);
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "uncertain about this API approach")]
+    #[inline]
+    pub fn move_from(&mut self, mut src: Vec<T>, start: usize, end: usize) -> usize {
+        for (a, b) in self.iter_mut().zip(src[start .. end].iter_mut()) {
+            mem::swap(a, b);
+        }
+        cmp::min(self.len(), end-start)
+    }
+
+    /// Deprecated: use `&s[start .. end]` notation instead.
+    #[unstable(feature = "collections",
+               reason = "will be replaced by slice syntax")]
+    #[deprecated(since = "1.0.0", reason = "use &s[start .. end] instead")]
+    #[inline]
+    pub fn slice(&self, start: usize, end: usize) -> &[T] {
+        &self[start .. end]
+    }
+
+    /// Deprecated: use `&s[start..]` notation instead.
+    #[unstable(feature = "collections",
+               reason = "will be replaced by slice syntax")]
+    #[deprecated(since = "1.0.0", reason = "use &s[start..] instead")]
+    #[inline]
+    pub fn slice_from(&self, start: usize) -> &[T] {
+        &self[start ..]
+    }
+
+    /// Deprecated: use `&s[..end]` notation instead.
+    #[unstable(feature = "collections",
+               reason = "will be replaced by slice syntax")]
+    #[deprecated(since = "1.0.0", reason = "use &s[..end] instead")]
+    #[inline]
+    pub fn slice_to(&self, end: usize) -> &[T] {
+        &self[.. end]
+    }
+
+    /// Divides one slice 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).
+    ///
+    /// Panics if `mid > len`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v = [10, 40, 30, 20, 50];
+    /// let (v1, v2) = v.split_at(2);
+    /// assert_eq!([10, 40], v1);
+    /// assert_eq!([30, 20, 50], v2);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn split_at(&self, mid: usize) -> (&[T], &[T]) {
+        core_slice::SliceExt::split_at(self, mid)
+    }
+
+    /// Returns an iterator over the slice.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn iter(&self) -> Iter<T> {
+        core_slice::SliceExt::iter(self)
+    }
+
+    /// Returns an iterator over subslices separated by elements that match
+    /// `pred`.  The matched element is not contained in the subslices.
+    ///
+    /// # Examples
+    ///
+    /// Print the slice split by numbers divisible by 3 (i.e. `[10, 40]`,
+    /// `[20]`, `[50]`):
+    ///
+    /// ```
+    /// let v = [10, 40, 30, 20, 60, 50];
+    /// for group in v.split(|num| *num % 3 == 0) {
+    ///     println!("{:?}", group);
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn split<F>(&self, pred: F) -> Split<T, F> where F: FnMut(&T) -> bool {
+        core_slice::SliceExt::split(self, pred)
+    }
+
+    /// Returns an iterator over subslices separated by elements that match
+    /// `pred`, limited to splitting at most `n` times.  The matched element is
+    /// not contained in the subslices.
+    ///
+    /// # Examples
+    ///
+    /// Print the slice split once by numbers divisible by 3 (i.e. `[10, 40]`,
+    /// `[20, 60, 50]`):
+    ///
+    /// ```
+    /// let v = [10, 40, 30, 20, 60, 50];
+    /// for group in v.splitn(1, |num| *num % 3 == 0) {
+    ///     println!("{:?}", group);
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<T, F> where F: FnMut(&T) -> bool {
+        core_slice::SliceExt::splitn(self, n, pred)
+    }
+
+    /// Returns an iterator over subslices separated by elements that match
+    /// `pred` limited to splitting at most `n` times. This starts at the end of
+    /// the slice and works backwards.  The matched element is not contained in
+    /// the subslices.
+    ///
+    /// # Examples
+    ///
+    /// Print the slice split once, starting from the end, by numbers divisible
+    /// by 3 (i.e. `[50]`, `[10, 40, 30, 20]`):
+    ///
+    /// ```
+    /// let v = [10, 40, 30, 20, 60, 50];
+    /// for group in v.rsplitn(1, |num| *num % 3 == 0) {
+    ///     println!("{:?}", group);
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<T, F> where F: FnMut(&T) -> bool {
+        core_slice::SliceExt::rsplitn(self, n, pred)
+    }
+
+    /// Returns an iterator over all contiguous windows of length
+    /// `size`. The windows overlap. If the slice is shorter than
+    /// `size`, the iterator returns no values.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `size` is 0.
+    ///
+    /// # Example
+    ///
+    /// Print the adjacent pairs of a slice (i.e. `[1,2]`, `[2,3]`,
+    /// `[3,4]`):
+    ///
+    /// ```rust
+    /// let v = &[1, 2, 3, 4];
+    /// for win in v.windows(2) {
+    ///     println!("{:?}", win);
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn windows(&self, size: usize) -> Windows<T> {
+        core_slice::SliceExt::windows(self, size)
+    }
+
+    /// Returns an iterator over `size` elements of the slice at a
+    /// time. The chunks do not overlap. If `size` does not divide the
+    /// length of the slice, then the last chunk will not have length
+    /// `size`.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `size` is 0.
+    ///
+    /// # Example
+    ///
+    /// Print the slice 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);
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn chunks(&self, size: usize) -> Chunks<T> {
+        core_slice::SliceExt::chunks(self, size)
+    }
+
+    /// Returns the element of a slice at the given index, or `None` if the
+    /// index is out of bounds.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v = [10, 40, 30];
+    /// assert_eq!(Some(&40), v.get(1));
+    /// assert_eq!(None, v.get(3));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn get(&self, index: usize) -> Option<&T> {
+        core_slice::SliceExt::get(self, index)
+    }
+
+    /// Returns the first element of a slice, or `None` if it is empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v = [10, 40, 30];
+    /// assert_eq!(Some(&10), v.first());
+    ///
+    /// let w: &[i32] = &[];
+    /// assert_eq!(None, w.first());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn first(&self) -> Option<&T> {
+        core_slice::SliceExt::first(self)
+    }
+
+    /// Returns all but the first element of a slice.
+    #[unstable(feature = "collections", reason = "likely to be renamed")]
+    #[inline]
+    pub fn tail(&self) -> &[T] {
+        core_slice::SliceExt::tail(self)
+    }
+
+    /// Returns all but the last element of a slice.
+    #[unstable(feature = "collections", reason = "likely to be renamed")]
+    #[inline]
+    pub fn init(&self) -> &[T] {
+        core_slice::SliceExt::init(self)
+    }
+
+    /// Returns the last element of a slice, or `None` if it is empty.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v = [10, 40, 30];
+    /// assert_eq!(Some(&30), v.last());
+    ///
+    /// let w: &[i32] = &[];
+    /// assert_eq!(None, w.last());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn last(&self) -> Option<&T> {
+        core_slice::SliceExt::last(self)
+    }
+
+    /// Returns a pointer to the element at the given index, without doing
+    /// bounds checking.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub unsafe fn get_unchecked(&self, index: usize) -> &T {
+        core_slice::SliceExt::get_unchecked(self, index)
+    }
+
+    /// Returns an unsafe pointer to the slice's buffer
+    ///
+    /// The caller must ensure that the slice outlives the pointer this
+    /// function returns, or else it will end up pointing to garbage.
+    ///
+    /// Modifying the slice may cause its buffer to be reallocated, which
+    /// would also make any pointers to it invalid.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn as_ptr(&self) -> *const T {
+        core_slice::SliceExt::as_ptr(self)
+    }
+
+    /// Binary search a sorted slice with a comparator function.
+    ///
+    /// The comparator function should implement an order consistent
+    /// with the sort order of the underlying slice, returning an
+    /// order code that indicates whether its argument is `Less`,
+    /// `Equal` or `Greater` the desired target.
+    ///
+    /// If a matching value is found then returns `Ok`, containing
+    /// the index for the matched element; if no match is found then
+    /// `Err` is returned, containing the index where a matching
+    /// element could be inserted while maintaining sorted order.
+    ///
+    /// # Example
+    ///
+    /// Looks up a series of four elements. The first is found, with a
+    /// uniquely determined position; the second and third are not
+    /// found; the fourth could match any position in `[1,4]`.
+    ///
+    /// ```rust
+    /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+    /// let s = s.as_slice();
+    ///
+    /// let seek = 13;
+    /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+    /// let seek = 4;
+    /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+    /// let seek = 100;
+    /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+    /// let seek = 1;
+    /// let r = s.binary_search_by(|probe| probe.cmp(&seek));
+    /// assert!(match r { Ok(1...4) => true, _ => false, });
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn binary_search_by<F>(&self, f: F) -> Result<usize, usize> where F: FnMut(&T) -> Ordering {
+        core_slice::SliceExt::binary_search_by(self, f)
+    }
+
+    /// Return the number of elements in the slice
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let a = [1, 2, 3];
+    /// assert_eq!(a.len(), 3);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn len(&self) -> usize {
+        core_slice::SliceExt::len(self)
+    }
+
+    /// Returns true if the slice has a length of 0
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let a = [1, 2, 3];
+    /// assert!(!a.is_empty());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_empty(&self) -> bool {
+        core_slice::SliceExt::is_empty(self)
+    }
+
+    /// Returns a mutable reference to the element at the given index,
+    /// or `None` if the index is out of bounds
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
+        core_slice::SliceExt::get_mut(self, index)
+    }
+
+    /// Work with `self` as a mut slice.
+    /// Primarily intended for getting a &mut [T] from a [T; N].
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn as_mut_slice(&mut self) -> &mut [T] {
+        core_slice::SliceExt::as_mut_slice(self)
+    }
+
+    /// Deprecated: use `&mut s[start .. end]` instead.
+    #[unstable(feature = "collections",
+               reason = "will be replaced by slice syntax")]
+    #[deprecated(since = "1.0.0", reason = "use &mut s[start .. end] instead")]
+    #[inline]
+    pub fn slice_mut(&mut self, start: usize, end: usize) -> &mut [T] {
+        &mut self[start .. end]
+    }
+
+    /// Deprecated: use `&mut s[start ..]` instead.
+    #[unstable(feature = "collections",
+               reason = "will be replaced by slice syntax")]
+    #[deprecated(since = "1.0.0", reason = "use &mut s[start ..] instead")]
+    #[inline]
+    pub fn slice_from_mut(&mut self, start: usize) -> &mut [T] {
+        &mut self[start ..]
+    }
+
+    /// Deprecated: use `&mut s[.. end]` instead.
+    #[unstable(feature = "collections",
+               reason = "will be replaced by slice syntax")]
+    #[deprecated(since = "1.0.0", reason = "use &mut s[.. end] instead")]
+    #[inline]
+    pub fn slice_to_mut(&mut self, end: usize) -> &mut [T] {
+        &mut self[.. end]
+    }
+
+    /// Returns an iterator that allows modifying each value
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn iter_mut(&mut self) -> IterMut<T> {
+        core_slice::SliceExt::iter_mut(self)
+    }
+
+    /// Returns a mutable pointer to the first element of a slice, or `None` if it is empty
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn first_mut(&mut self) -> Option<&mut T> {
+        core_slice::SliceExt::first_mut(self)
+    }
+
+    /// Returns all but the first element of a mutable slice
+    #[unstable(feature = "collections",
+               reason = "likely to be renamed or removed")]
+    #[inline]
+    pub fn tail_mut(&mut self) -> &mut [T] {
+        core_slice::SliceExt::tail_mut(self)
+    }
+
+    /// Returns all but the last element of a mutable slice
+    #[unstable(feature = "collections",
+               reason = "likely to be renamed or removed")]
+    #[inline]
+    pub fn init_mut(&mut self) -> &mut [T] {
+        core_slice::SliceExt::init_mut(self)
+    }
+
+    /// Returns a mutable pointer to the last item in the slice.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn last_mut(&mut self) -> Option<&mut T> {
+        core_slice::SliceExt::last_mut(self)
+    }
+
+    /// Returns an iterator over mutable subslices separated by elements that
+    /// match `pred`.  The matched element is not contained in the subslices.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<T, F> where F: FnMut(&T) -> bool {
+        core_slice::SliceExt::split_mut(self, pred)
+    }
+
+    /// Returns an iterator over subslices separated by elements that match
+    /// `pred`, limited to splitting at most `n` times.  The matched element is
+    /// not contained in the subslices.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<T, F>
+                         where F: FnMut(&T) -> bool {
+        core_slice::SliceExt::splitn_mut(self, n, pred)
+    }
+
+    /// Returns an iterator over subslices separated by elements that match
+    /// `pred` limited to splitting at most `n` times. This starts at the end of
+    /// the slice and works backwards.  The matched element is not contained in
+    /// the subslices.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn rsplitn_mut<F>(&mut self,  n: usize, pred: F) -> RSplitNMut<T, F>
+                      where F: FnMut(&T) -> bool {
+        core_slice::SliceExt::rsplitn_mut(self, n, pred)
+    }
+
+    /// Returns an iterator over `chunk_size` elements of the slice at a time.
+    /// The chunks are mutable and do not overlap. If `chunk_size` does
+    /// not divide the length of the slice, then the last chunk will not
+    /// have length `chunk_size`.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `chunk_size` is 0.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> {
+        core_slice::SliceExt::chunks_mut(self, chunk_size)
+    }
+
+    /// Swaps two elements in a slice.
+    ///
+    /// # Arguments
+    ///
+    /// * a - The index of the first element
+    /// * b - The index of the second element
+    ///
+    /// # Panics
+    ///
+    /// Panics if `a` or `b` are out of bounds.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = ["a", "b", "c", "d"];
+    /// v.swap(1, 3);
+    /// assert!(v == ["a", "d", "c", "b"]);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn swap(&mut self, a: usize, b: usize) {
+        core_slice::SliceExt::swap(self, a, b)
+    }
+
+    /// 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).
+    ///
+    /// # Panics
+    ///
+    /// Panics 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.split_at_mut(0);
+    ///    assert!(left == []);
+    ///    assert!(right == [1, 2, 3, 4, 5, 6]);
+    /// }
+    ///
+    /// {
+    ///     let (left, right) = v.split_at_mut(2);
+    ///     assert!(left == [1, 2]);
+    ///     assert!(right == [3, 4, 5, 6]);
+    /// }
+    ///
+    /// {
+    ///     let (left, right) = v.split_at_mut(6);
+    ///     assert!(left == [1, 2, 3, 4, 5, 6]);
+    ///     assert!(right == []);
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
+        core_slice::SliceExt::split_at_mut(self, mid)
+    }
+
+    /// Reverse the order of elements in a slice, in place.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = [1, 2, 3];
+    /// v.reverse();
+    /// assert!(v == [3, 2, 1]);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn reverse(&mut self) {
+        core_slice::SliceExt::reverse(self)
+    }
+
+    /// Returns an unsafe mutable pointer to the element in index
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
+        core_slice::SliceExt::get_unchecked_mut(self, index)
+    }
+
+    /// Return an unsafe mutable pointer to the slice's buffer.
+    ///
+    /// The caller must ensure that the slice outlives the pointer this
+    /// function returns, or else it will end up pointing to garbage.
+    ///
+    /// Modifying the slice may cause its buffer to be reallocated, which
+    /// would also make any pointers to it invalid.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn as_mut_ptr(&mut self) -> *mut T {
+        core_slice::SliceExt::as_mut_ptr(self)
+    }
+
+    /// Copies `self` into a new `Vec`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn to_vec(&self) -> Vec<T> where T: Clone {
+        // NB see hack module in this file
+        hack::to_vec(self)
+    }
+
+    /// Creates an iterator that yields every possible permutation of the
+    /// vector in succession.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// let v = [1, 2, 3];
+    /// let mut perms = v.permutations();
+    ///
+    /// for p in perms {
+    ///   println!("{:?}", p);
+    /// }
+    /// ```
+    ///
+    /// Iterating through permutations one by one.
+    ///
+    /// ```rust
+    /// let v = [1, 2, 3];
+    /// let mut perms = v.permutations();
+    ///
+    /// assert_eq!(Some(vec![1, 2, 3]), perms.next());
+    /// assert_eq!(Some(vec![1, 3, 2]), perms.next());
+    /// assert_eq!(Some(vec![3, 1, 2]), perms.next());
+    /// ```
+    #[unstable(feature = "collections")]
+    #[inline]
+    pub fn permutations(&self) -> Permutations<T> where T: Clone {
+        // NB see hack module in this file
+        hack::permutations(self)
+    }
+
+    /// 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
+    /// let mut dst = [0, 0, 0];
+    /// let src = [1, 2];
+    ///
+    /// assert!(dst.clone_from_slice(&src) == 2);
+    /// assert!(dst == [1, 2, 0]);
+    ///
+    /// let src2 = [3, 4, 5, 6];
+    /// assert!(dst.clone_from_slice(&src2) == 3);
+    /// assert!(dst == [3, 4, 5]);
+    /// ```
+    #[unstable(feature = "collections")]
+    pub fn clone_from_slice(&mut self, src: &[T]) -> usize where T: Clone {
+        core_slice::SliceExt::clone_from_slice(self, src)
+    }
+
+    /// Sorts the slice, in place.
+    ///
+    /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// let mut v = [-5, 4, 1, -3, 2];
+    ///
+    /// v.sort();
+    /// assert!(v == [-5, -3, 1, 2, 4]);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sort(&mut self) where T: Ord {
+        self.sort_by(|a, b| a.cmp(b))
+    }
+
+    /// Binary search a sorted slice for a given element.
+    ///
+    /// If the value is found then `Ok` is returned, containing the
+    /// index of the matching element; if the value is not found then
+    /// `Err` is returned, containing the index where a matching
+    /// element could be inserted while maintaining sorted order.
+    ///
+    /// # Example
+    ///
+    /// Looks up a series of four elements. The first is found, with a
+    /// uniquely determined position; the second and third are not
+    /// found; the fourth could match any position in `[1,4]`.
+    ///
+    /// ```rust
+    /// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+    /// let s = s.as_slice();
+    ///
+    /// assert_eq!(s.binary_search(&13),  Ok(9));
+    /// assert_eq!(s.binary_search(&4),   Err(7));
+    /// assert_eq!(s.binary_search(&100), Err(13));
+    /// let r = s.binary_search(&1);
+    /// assert!(match r { Ok(1...4) => true, _ => false, });
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn binary_search(&self, x: &T) -> Result<usize, usize> where T: Ord {
+        core_slice::SliceExt::binary_search(self, x)
+    }
+
+    /// Deprecated: use `binary_search` instead.
+    #[unstable(feature = "collections")]
+    #[deprecated(since = "1.0.0", reason = "use binary_search instead")]
+    pub fn binary_search_elem(&self, x: &T) -> Result<usize, usize> where T: Ord {
+        self.binary_search(x)
+    }
+
+    /// Mutates the slice to the next lexicographic permutation.
+    ///
+    /// Returns `true` if successful and `false` if the slice is at the
+    /// last-ordered permutation.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let v: &mut [_] = &mut [0, 1, 2];
+    /// v.next_permutation();
+    /// let b: &mut [_] = &mut [0, 2, 1];
+    /// assert!(v == b);
+    /// v.next_permutation();
+    /// let b: &mut [_] = &mut [1, 0, 2];
+    /// assert!(v == b);
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "uncertain if this merits inclusion in std")]
+    pub fn next_permutation(&mut self) -> bool where T: Ord {
+        core_slice::SliceExt::next_permutation(self)
+    }
+
+    /// Mutates the slice to the previous lexicographic permutation.
+    ///
+    /// Returns `true` if successful and `false` if the slice is at the
+    /// first-ordered permutation.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let v: &mut [_] = &mut [1, 0, 2];
+    /// v.prev_permutation();
+    /// let b: &mut [_] = &mut [0, 2, 1];
+    /// assert!(v == b);
+    /// v.prev_permutation();
+    /// let b: &mut [_] = &mut [0, 1, 2];
+    /// assert!(v == b);
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "uncertain if this merits inclusion in std")]
+    pub fn prev_permutation(&mut self) -> bool where T: Ord {
+        core_slice::SliceExt::prev_permutation(self)
+    }
+
+    /// Find the first index containing a matching value.
+    #[unstable(feature = "collections")]
+    pub fn position_elem(&self, t: &T) -> Option<usize> where T: PartialEq {
+        core_slice::SliceExt::position_elem(self, t)
+    }
+
+    /// Find the last index containing a matching value.
+    #[unstable(feature = "collections")]
+    pub fn rposition_elem(&self, t: &T) -> Option<usize> where T: PartialEq {
+        core_slice::SliceExt::rposition_elem(self, t)
+    }
+
+    /// Returns true if the slice contains an element with the given value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v = [10, 40, 30];
+    /// assert!(v.contains(&30));
+    /// assert!(!v.contains(&50));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn contains(&self, x: &T) -> bool where T: PartialEq {
+        core_slice::SliceExt::contains(self, x)
+    }
+
+    /// Returns true if `needle` is a prefix of the slice.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v = [10, 40, 30];
+    /// assert!(v.starts_with(&[10]));
+    /// assert!(v.starts_with(&[10, 40]));
+    /// assert!(!v.starts_with(&[50]));
+    /// assert!(!v.starts_with(&[10, 50]));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq {
+        core_slice::SliceExt::starts_with(self, needle)
+    }
+
+    /// Returns true if `needle` is a suffix of the slice.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v = [10, 40, 30];
+    /// assert!(v.ends_with(&[30]));
+    /// assert!(v.ends_with(&[40, 30]));
+    /// assert!(!v.ends_with(&[50]));
+    /// assert!(!v.ends_with(&[50, 30]));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq {
+        core_slice::SliceExt::ends_with(self, needle)
+    }
+
+    /// Convert `self` into a vector without clones or allocation.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn into_vec(self: Box<Self>) -> Vec<T> {
+        // NB see hack module in this file
+        hack::into_vec(self)
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Extension traits for slices over specific kinds of data
 ////////////////////////////////////////////////////////////////////////////////
@@ -1189,7 +2128,15 @@ impl<T> BorrowMut<[T]> for Vec<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Clone> ToOwned for [T] {
     type Owned = Vec<T>;
+    #[cfg(not(test))]
     fn to_owned(&self) -> Vec<T> { self.to_vec() }
+
+    // HACK(japaric): with cfg(test) the inherent `[T]::to_vec`, which is required for this method
+    // definition, is not available. Since we don't require this method for testing purposes, I'll
+    // just stub it
+    // NB see the slice::hack module in slice.rs for more information
+    #[cfg(test)]
+    fn to_owned(&self) -> Vec<T> { panic!("not available with cfg(test)") }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1387,7 +2334,7 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
     // 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) {
+    for start in (0.. len).step_by(insertion) {
         // start <= i < len;
         for i in start..cmp::min(start + insertion, len) {
             // j satisfies: start <= j <= i;
@@ -1427,7 +2374,7 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
         // a time, placing the result in `buf_tmp`.
 
         // 0 <= start <= len.
-        for start in range_step(0, len, 2 * width) {
+        for start in (0..len).step_by(2 * width) {
             // manipulate pointers directly for speed (rather than
             // using a `for` loop with `range` and `.offset` inside
             // that loop).
@@ -1506,1633 +2453,3 @@ fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order
         old
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use alloc::boxed::Box;
-    use core::cmp::Ordering::{Greater, Less, Equal};
-    use core::prelude::{Some, None, Clone};
-    use core::prelude::{Iterator, IteratorExt};
-    use core::prelude::{AsSlice};
-    use core::prelude::Ord;
-    use core::default::Default;
-    use core::mem;
-    use std::iter::RandomAccessIterator;
-    use std::rand::{Rng, thread_rng};
-    use std::rc::Rc;
-    use string::ToString;
-    use vec::Vec;
-    use super::{ElementSwaps, SliceConcatExt, SliceExt};
-
-    fn square(n: usize) -> usize { n * n }
-
-    fn is_odd(n: &usize) -> bool { *n % 2 == 1 }
-
-    #[test]
-    fn test_from_fn() {
-        // Test on-stack from_fn.
-        let mut v: Vec<_> = (0..3).map(square).collect();
-        {
-            let v = v;
-            assert_eq!(v.len(), 3);
-            assert_eq!(v[0], 0);
-            assert_eq!(v[1], 1);
-            assert_eq!(v[2], 4);
-        }
-
-        // Test on-heap from_fn.
-        v = (0..5).map(square).collect();
-        {
-            let v = v;
-            assert_eq!(v.len(), 5);
-            assert_eq!(v[0], 0);
-            assert_eq!(v[1], 1);
-            assert_eq!(v[2], 4);
-            assert_eq!(v[3], 9);
-            assert_eq!(v[4], 16);
-        }
-    }
-
-    #[test]
-    fn test_from_elem() {
-        // Test on-stack from_elem.
-        let mut v = vec![10, 10];
-        {
-            let v = v;
-            assert_eq!(v.len(), 2);
-            assert_eq!(v[0], 10);
-            assert_eq!(v[1], 10);
-        }
-
-        // Test on-heap from_elem.
-        v = vec![20; 6];
-        {
-            let v = v.as_slice();
-            assert_eq!(v[0], 20);
-            assert_eq!(v[1], 20);
-            assert_eq!(v[2], 20);
-            assert_eq!(v[3], 20);
-            assert_eq!(v[4], 20);
-            assert_eq!(v[5], 20);
-        }
-    }
-
-    #[test]
-    fn test_is_empty() {
-        let xs: [i32; 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 = vec![11];
-        assert_eq!(a.get(1), None);
-        a = vec![11, 12];
-        assert_eq!(a.get(1).unwrap(), &12);
-        a = vec![11, 12, 13];
-        assert_eq!(a.get(1).unwrap(), &12);
-    }
-
-    #[test]
-    fn test_first() {
-        let mut a = vec![];
-        assert_eq!(a.first(), None);
-        a = vec![11];
-        assert_eq!(a.first().unwrap(), &11);
-        a = vec![11, 12];
-        assert_eq!(a.first().unwrap(), &11);
-    }
-
-    #[test]
-    fn test_first_mut() {
-        let mut a = vec![];
-        assert_eq!(a.first_mut(), None);
-        a = vec![11];
-        assert_eq!(*a.first_mut().unwrap(), 11);
-        a = vec![11, 12];
-        assert_eq!(*a.first_mut().unwrap(), 11);
-    }
-
-    #[test]
-    fn test_tail() {
-        let mut a = vec![11];
-        let b: &[i32] = &[];
-        assert_eq!(a.tail(), b);
-        a = vec![11, 12];
-        let b: &[i32] = &[12];
-        assert_eq!(a.tail(), b);
-    }
-
-    #[test]
-    fn test_tail_mut() {
-        let mut a = vec![11];
-        let b: &mut [i32] = &mut [];
-        assert!(a.tail_mut() == b);
-        a = vec![11, 12];
-        let b: &mut [_] = &mut [12];
-        assert!(a.tail_mut() == b);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_tail_empty() {
-        let a = Vec::<i32>::new();
-        a.tail();
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_tail_mut_empty() {
-        let mut a = Vec::<i32>::new();
-        a.tail_mut();
-    }
-
-    #[test]
-    fn test_init() {
-        let mut a = vec![11];
-        let b: &[i32] = &[];
-        assert_eq!(a.init(), b);
-        a = vec![11, 12];
-        let b: &[_] = &[11];
-        assert_eq!(a.init(), b);
-    }
-
-    #[test]
-    fn test_init_mut() {
-        let mut a = vec![11];
-        let b: &mut [i32] = &mut [];
-        assert!(a.init_mut() == b);
-        a = vec![11, 12];
-        let b: &mut [_] = &mut [11];
-        assert!(a.init_mut() == b);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_init_empty() {
-        let a = Vec::<i32>::new();
-        a.init();
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_init_mut_empty() {
-        let mut a = Vec::<i32>::new();
-        a.init_mut();
-    }
-
-    #[test]
-    fn test_last() {
-        let mut a = vec![];
-        assert_eq!(a.last(), None);
-        a = vec![11];
-        assert_eq!(a.last().unwrap(), &11);
-        a = vec![11, 12];
-        assert_eq!(a.last().unwrap(), &12);
-    }
-
-    #[test]
-    fn test_last_mut() {
-        let mut a = vec![];
-        assert_eq!(a.last_mut(), None);
-        a = vec![11];
-        assert_eq!(*a.last_mut().unwrap(), 11);
-        a = vec![11, 12];
-        assert_eq!(*a.last_mut().unwrap(), 12);
-    }
-
-    #[test]
-    fn test_slice() {
-        // Test fixed length vector.
-        let vec_fixed = [1, 2, 3, 4];
-        let v_a = vec_fixed[1..vec_fixed.len()].to_vec();
-        assert_eq!(v_a.len(), 3);
-
-        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[1..3].to_vec();
-        assert_eq!(v_b.len(), 2);
-
-        assert_eq!(v_b[0], 2);
-        assert_eq!(v_b[1], 3);
-
-        // Test `Box<[T]>`
-        let vec_unique = vec![1, 2, 3, 4, 5, 6];
-        let v_d = vec_unique[1..6].to_vec();
-        assert_eq!(v_d.len(), 5);
-
-        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[..], vec);
-        let b: &[_] = &[3, 4];
-        assert_eq!(&vec[2..], b);
-        let b: &[_] = &[];
-        assert_eq!(&vec[4..], b);
-    }
-
-    #[test]
-    fn test_slice_to() {
-        let vec: &[_] = &[1, 2, 3, 4];
-        assert_eq!(&vec[..4], vec);
-        let b: &[_] = &[1, 2];
-        assert_eq!(&vec[..2], b);
-        let b: &[_] = &[];
-        assert_eq!(&vec[..0], b);
-    }
-
-
-    #[test]
-    fn test_pop() {
-        let mut v = vec![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 = vec![1, 2, 3, 4, 5];
-        let mut e = v.swap_remove(0);
-        assert_eq!(e, 1);
-        assert_eq!(v, [5, 2, 3, 4]);
-        e = v.swap_remove(3);
-        assert_eq!(e, 4);
-        assert_eq!(v, [5, 2, 3]);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_swap_remove_fail() {
-        let mut v = vec![1];
-        let _ = v.swap_remove(0);
-        let _ = v.swap_remove(0);
-    }
-
-    #[test]
-    fn test_swap_remove_noncopyable() {
-        // Tests that we don't accidentally run destructors twice.
-        let mut v: Vec<Box<_>> = Vec::new();
-        v.push(box 0u8);
-        v.push(box 0u8);
-        v.push(box 0u8);
-        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 = vec![];
-        v.push(1);
-        assert_eq!(v.len(), 1);
-        assert_eq!(v[0], 1);
-
-        // Test on-heap push().
-        v.push(2);
-        assert_eq!(v.len(), 2);
-        assert_eq!(v[0], 1);
-        assert_eq!(v[1], 2);
-    }
-
-    #[test]
-    fn test_truncate() {
-        let mut v: Vec<Box<_>> = vec![box 6,box 5,box 4];
-        v.truncate(1);
-        let v = v;
-        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: Vec<Box<_>> = vec![box 6,box 5,box 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: Vec<i32>, b: Vec<i32>) {
-            let mut v = a;
-            v.dedup();
-            assert_eq!(v, b);
-        }
-        case(vec![], vec![]);
-        case(vec![1], vec![1]);
-        case(vec![1,1], vec![1]);
-        case(vec![1,2,3], vec![1,2,3]);
-        case(vec![1,1,2,3], vec![1,2,3]);
-        case(vec![1,2,2,3], vec![1,2,3]);
-        case(vec![1,2,3,3], vec![1,2,3]);
-        case(vec![1,1,2,2,2,3,3], vec![1,2,3]);
-    }
-
-    #[test]
-    fn test_dedup_unique() {
-        let mut v0: Vec<Box<_>> = vec![box 1, box 1, box 2, box 3];
-        v0.dedup();
-        let mut v1: Vec<Box<_>> = vec![box 1, box 2, box 2, box 3];
-        v1.dedup();
-        let mut v2: Vec<Box<_>> = vec![box 1, box 2, box 3, box 3];
-        v2.dedup();
-        /*
-         * If the boxed pointers were leaked or otherwise misused, valgrind
-         * and/or rt should raise errors.
-         */
-    }
-
-    #[test]
-    fn test_dedup_shared() {
-        let mut v0: Vec<Box<_>> = vec![box 1, box 1, box 2, box 3];
-        v0.dedup();
-        let mut v1: Vec<Box<_>> = vec![box 1, box 2, box 2, box 3];
-        v1.dedup();
-        let mut v2: Vec<Box<_>> = vec![box 1, box 2, box 3, box 3];
-        v2.dedup();
-        /*
-         * If the pointers were leaked or otherwise misused, valgrind and/or
-         * rt should raise errors.
-         */
-    }
-
-    #[test]
-    fn test_retain() {
-        let mut v = vec![1, 2, 3, 4, 5];
-        v.retain(is_odd);
-        assert_eq!(v, [1, 3, 5]);
-    }
-
-    #[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]),
-                _ => panic!(),
-            }
-        }
-    }
-
-    #[test]
-    fn test_permutations() {
-        {
-            let v: [i32; 0] = [];
-            let mut it = v.permutations();
-            let (min_size, max_opt) = it.size_hint();
-            assert_eq!(min_size, 1);
-            assert_eq!(max_opt.unwrap(), 1);
-            assert_eq!(it.next(), Some(v.to_vec()));
-            assert_eq!(it.next(), None);
-        }
-        {
-            let v = ["Hello".to_string()];
-            let mut it = v.permutations();
-            let (min_size, max_opt) = it.size_hint();
-            assert_eq!(min_size, 1);
-            assert_eq!(max_opt.unwrap(), 1);
-            assert_eq!(it.next(), Some(v.to_vec()));
-            assert_eq!(it.next(), None);
-        }
-        {
-            let v = [1, 2, 3];
-            let mut it = v.permutations();
-            let (min_size, max_opt) = it.size_hint();
-            assert_eq!(min_size, 3*2);
-            assert_eq!(max_opt.unwrap(), 3*2);
-            assert_eq!(it.next(), Some(vec![1,2,3]));
-            assert_eq!(it.next(), Some(vec![1,3,2]));
-            assert_eq!(it.next(), Some(vec![3,1,2]));
-            let (min_size, max_opt) = it.size_hint();
-            assert_eq!(min_size, 3);
-            assert_eq!(max_opt.unwrap(), 3);
-            assert_eq!(it.next(), Some(vec![3,2,1]));
-            assert_eq!(it.next(), Some(vec![2,3,1]));
-            assert_eq!(it.next(), Some(vec![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;
-            let mut it = v.permutations();
-            let (min_size, max_opt) = it.size_hint();
-            for _perm in it.by_ref() {
-                amt += 1;
-            }
-            assert_eq!(amt, it.swaps.swaps_made);
-            assert_eq!(amt, min_size);
-            assert_eq!(amt, 2 * 3 * 4 * 5 * 6);
-            assert_eq!(amt, max_opt.unwrap());
-        }
-    }
-
-    #[test]
-    fn test_lexicographic_permutations() {
-        let v : &mut[_] = &mut[1, 2, 3, 4, 5];
-        assert!(v.prev_permutation() == false);
-        assert!(v.next_permutation());
-        let b: &mut[_] = &mut[1, 2, 3, 5, 4];
-        assert!(v == b);
-        assert!(v.prev_permutation());
-        let b: &mut[_] = &mut[1, 2, 3, 4, 5];
-        assert!(v == b);
-        assert!(v.next_permutation());
-        assert!(v.next_permutation());
-        let b: &mut[_] = &mut[1, 2, 4, 3, 5];
-        assert!(v == b);
-        assert!(v.next_permutation());
-        let b: &mut[_] = &mut[1, 2, 4, 5, 3];
-        assert!(v == b);
-
-        let v : &mut[_] = &mut[1, 0, 0, 0];
-        assert!(v.next_permutation() == false);
-        assert!(v.prev_permutation());
-        let b: &mut[_] = &mut[0, 1, 0, 0];
-        assert!(v == b);
-        assert!(v.prev_permutation());
-        let b: &mut[_] = &mut[0, 0, 1, 0];
-        assert!(v == b);
-        assert!(v.prev_permutation());
-        let b: &mut[_] = &mut[0, 0, 0, 1];
-        assert!(v == b);
-        assert!(v.prev_permutation() == false);
-    }
-
-    #[test]
-    fn test_lexicographic_permutations_empty_and_short() {
-        let empty : &mut[i32] = &mut[];
-        assert!(empty.next_permutation() == false);
-        let b: &mut[i32] = &mut[];
-        assert!(empty == b);
-        assert!(empty.prev_permutation() == false);
-        assert!(empty == b);
-
-        let one_elem : &mut[_] = &mut[4];
-        assert!(one_elem.prev_permutation() == false);
-        let b: &mut[_] = &mut[4];
-        assert!(one_elem == b);
-        assert!(one_elem.next_permutation() == false);
-        assert!(one_elem == b);
-
-        let two_elem : &mut[_] = &mut[1, 2];
-        assert!(two_elem.prev_permutation() == false);
-        let b : &mut[_] = &mut[1, 2];
-        let c : &mut[_] = &mut[2, 1];
-        assert!(two_elem == b);
-        assert!(two_elem.next_permutation());
-        assert!(two_elem == c);
-        assert!(two_elem.next_permutation() == false);
-        assert!(two_elem == c);
-        assert!(two_elem.prev_permutation());
-        assert!(two_elem == b);
-        assert!(two_elem.prev_permutation() == false);
-        assert!(two_elem == b);
-    }
-
-    #[test]
-    fn test_position_elem() {
-        assert!([].position_elem(&1).is_none());
-
-        let v1 = vec![1, 2, 3, 3, 2, 5];
-        assert_eq!(v1.position_elem(&1), Some(0));
-        assert_eq!(v1.position_elem(&2), Some(1));
-        assert_eq!(v1.position_elem(&5), Some(5));
-        assert!(v1.position_elem(&4).is_none());
-    }
-
-    #[test]
-    fn test_binary_search() {
-        assert_eq!([1,2,3,4,5].binary_search(&5).ok(), Some(4));
-        assert_eq!([1,2,3,4,5].binary_search(&4).ok(), Some(3));
-        assert_eq!([1,2,3,4,5].binary_search(&3).ok(), Some(2));
-        assert_eq!([1,2,3,4,5].binary_search(&2).ok(), Some(1));
-        assert_eq!([1,2,3,4,5].binary_search(&1).ok(), Some(0));
-
-        assert_eq!([2,4,6,8,10].binary_search(&1).ok(), None);
-        assert_eq!([2,4,6,8,10].binary_search(&5).ok(), None);
-        assert_eq!([2,4,6,8,10].binary_search(&4).ok(), Some(1));
-        assert_eq!([2,4,6,8,10].binary_search(&10).ok(), Some(4));
-
-        assert_eq!([2,4,6,8].binary_search(&1).ok(), None);
-        assert_eq!([2,4,6,8].binary_search(&5).ok(), None);
-        assert_eq!([2,4,6,8].binary_search(&4).ok(), Some(1));
-        assert_eq!([2,4,6,8].binary_search(&8).ok(), Some(3));
-
-        assert_eq!([2,4,6].binary_search(&1).ok(), None);
-        assert_eq!([2,4,6].binary_search(&5).ok(), None);
-        assert_eq!([2,4,6].binary_search(&4).ok(), Some(1));
-        assert_eq!([2,4,6].binary_search(&6).ok(), Some(2));
-
-        assert_eq!([2,4].binary_search(&1).ok(), None);
-        assert_eq!([2,4].binary_search(&5).ok(), None);
-        assert_eq!([2,4].binary_search(&2).ok(), Some(0));
-        assert_eq!([2,4].binary_search(&4).ok(), Some(1));
-
-        assert_eq!([2].binary_search(&1).ok(), None);
-        assert_eq!([2].binary_search(&5).ok(), None);
-        assert_eq!([2].binary_search(&2).ok(), Some(0));
-
-        assert_eq!([].binary_search(&1).ok(), None);
-        assert_eq!([].binary_search(&5).ok(), None);
-
-        assert!([1,1,1,1,1].binary_search(&1).ok() != None);
-        assert!([1,1,1,1,2].binary_search(&1).ok() != None);
-        assert!([1,1,1,2,2].binary_search(&1).ok() != None);
-        assert!([1,1,2,2,2].binary_search(&1).ok() != None);
-        assert_eq!([1,2,2,2,2].binary_search(&1).ok(), Some(0));
-
-        assert_eq!([1,2,3,4,5].binary_search(&6).ok(), None);
-        assert_eq!([1,2,3,4,5].binary_search(&0).ok(), None);
-    }
-
-    #[test]
-    fn test_reverse() {
-        let mut v = vec![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 = Vec::<i32>::new();
-        v3.reverse();
-        assert!(v3.is_empty());
-    }
-
-    #[test]
-    fn test_sort() {
-        for len in 4..25 {
-            for _ in 0..100 {
-                let mut v: Vec<_> = thread_rng().gen_iter::<i32>().take(len).collect();
-                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 panic
-        let mut v: [i32; 0] = [];
-        v.sort();
-
-        let mut v = [0xDEADBEEFu64];
-        v.sort();
-        assert!(v == [0xDEADBEEF]);
-    }
-
-    #[test]
-    fn test_sort_stability() {
-        for len in 4..25 {
-            for _ in 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: Vec<_> = (0..len).map(|_| {
-                        let n = thread_rng().gen::<usize>() % 10;
-                        counts[n] += 1;
-                        (n, counts[n])
-                    }).collect();
-
-                // 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_concat() {
-        let v: [Vec<i32>; 0] = [];
-        let c = v.concat();
-        assert_eq!(c, []);
-        let d = [vec![1], vec![2, 3]].concat();
-        assert_eq!(d, [1, 2, 3]);
-
-        let v: &[&[_]] = &[&[1], &[2, 3]];
-        assert_eq!(v.connect(&0), [1, 0, 2, 3]);
-        let v: &[&[_]] = &[&[1], &[2], &[3]];
-        assert_eq!(v.connect(&0), [1, 0, 2, 0, 3]);
-    }
-
-    #[test]
-    fn test_connect() {
-        let v: [Vec<i32>; 0] = [];
-        assert_eq!(v.connect(&0), []);
-        assert_eq!([vec![1], vec![2, 3]].connect(&0), [1, 0, 2, 3]);
-        assert_eq!([vec![1], vec![2], vec![3]].connect(&0), [1, 0, 2, 0, 3]);
-
-        let v: [&[_]; 2] = [&[1], &[2, 3]];
-        assert_eq!(v.connect(&0), [1, 0, 2, 3]);
-        let v: [&[_]; 3] = [&[1], &[2], &[3]];
-        assert_eq!(v.connect(&0), [1, 0, 2, 0, 3]);
-    }
-
-    #[test]
-    fn test_insert() {
-        let mut a = vec![1, 2, 4];
-        a.insert(2, 3);
-        assert_eq!(a, [1, 2, 3, 4]);
-
-        let mut a = vec![1, 2, 3];
-        a.insert(0, 0);
-        assert_eq!(a, [0, 1, 2, 3]);
-
-        let mut a = vec![1, 2, 3];
-        a.insert(3, 4);
-        assert_eq!(a, [1, 2, 3, 4]);
-
-        let mut a = vec![];
-        a.insert(0, 1);
-        assert_eq!(a, [1]);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_insert_oob() {
-        let mut a = vec![1, 2, 3];
-        a.insert(4, 5);
-    }
-
-    #[test]
-    fn test_remove() {
-        let mut a = vec![1, 2, 3, 4];
-
-        assert_eq!(a.remove(2), 3);
-        assert_eq!(a, [1, 2, 4]);
-
-        assert_eq!(a.remove(2), 4);
-        assert_eq!(a, [1, 2]);
-
-        assert_eq!(a.remove(0), 1);
-        assert_eq!(a, [2]);
-
-        assert_eq!(a.remove(0), 2);
-        assert_eq!(a, []);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_remove_fail() {
-        let mut a = vec![1];
-        let _ = a.remove(0);
-        let _ = a.remove(0);
-    }
-
-    #[test]
-    fn test_capacity() {
-        let mut v = vec![0];
-        v.reserve_exact(10);
-        assert!(v.capacity() >= 11);
-    }
-
-    #[test]
-    fn test_slice_2() {
-        let v = vec![1, 2, 3, 4, 5];
-        let v = v.slice(1, 3);
-        assert_eq!(v.len(), 2);
-        assert_eq!(v[0], 2);
-        assert_eq!(v[1], 3);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_permute_fail() {
-        let v: [(Box<_>, Rc<_>); 4] =
-            [(box 0, Rc::new(0)), (box 0, Rc::new(0)),
-             (box 0, Rc::new(0)), (box 0, Rc::new(0))];
-        let mut i = 0;
-        for _ in v.permutations() {
-            if i == 2 {
-                panic!()
-            }
-            i += 1;
-        }
-    }
-
-    #[test]
-    fn test_total_ord() {
-        let c = &[1, 2, 3];
-        [1, 2, 3, 4][..].cmp(c) == Greater;
-        let c = &[1, 2, 3, 4];
-        [1, 2, 3][..].cmp(c) == Less;
-        let c = &[1, 2, 3, 6];
-        [1, 2, 3, 4][..].cmp(c) == Equal;
-        let c = &[1, 2, 3, 4, 5, 6];
-        [1, 2, 3, 4, 5, 5, 5, 5][..].cmp(c) == Less;
-        let c = &[1, 2, 3, 4];
-        [2, 2][..].cmp(c) == Greater;
-    }
-
-    #[test]
-    fn test_iterator() {
-        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() {
-        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() {
-        let mut xs = [1, 2, 5, 10, 11];
-        assert_eq!(xs.iter().size_hint(), (5, Some(5)));
-        assert_eq!(xs.iter_mut().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() {
-        let mut xs = [1, 2, 3, 4, 5];
-        for x in &mut xs {
-            *x += 1;
-        }
-        assert!(xs == [2, 3, 4, 5, 6])
-    }
-
-    #[test]
-    fn test_rev_iterator() {
-
-        let xs = [1, 2, 5, 10, 11];
-        let ys = [11, 10, 5, 2, 1];
-        let mut i = 0;
-        for &x in xs.iter().rev() {
-            assert_eq!(x, ys[i]);
-            i += 1;
-        }
-        assert_eq!(i, 5);
-    }
-
-    #[test]
-    fn test_mut_rev_iterator() {
-        let mut xs = [1, 2, 3, 4, 5];
-        for (i,x) in xs.iter_mut().rev().enumerate() {
-            *x += i;
-        }
-        assert!(xs == [5, 5, 5, 5, 5])
-    }
-
-    #[test]
-    fn test_move_iterator() {
-        let xs = vec![1,2,3,4,5];
-        assert_eq!(xs.into_iter().fold(0, |a: usize, b: usize| 10*a + b), 12345);
-    }
-
-    #[test]
-    fn test_move_rev_iterator() {
-        let xs = vec![1,2,3,4,5];
-        assert_eq!(xs.into_iter().rev().fold(0, |a: usize, b: usize| 10*a + b), 54321);
-    }
-
-    #[test]
-    fn test_splitator() {
-        let xs = &[1,2,3,4,5];
-
-        let splits: &[&[_]] = &[&[1], &[3], &[5]];
-        assert_eq!(xs.split(|x| *x % 2 == 0).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[], &[2,3,4,5]];
-        assert_eq!(xs.split(|x| *x == 1).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[1,2,3,4], &[]];
-        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[1,2,3,4,5]];
-        assert_eq!(xs.split(|x| *x == 10).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[], &[], &[], &[], &[], &[]];
-        assert_eq!(xs.split(|_| true).collect::<Vec<&[i32]>>(),
-                   splits);
-
-        let xs: &[i32] = &[];
-        let splits: &[&[i32]] = &[&[]];
-        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[i32]>>(), splits);
-    }
-
-    #[test]
-    fn test_splitnator() {
-        let xs = &[1,2,3,4,5];
-
-        let splits: &[&[_]] = &[&[1,2,3,4,5]];
-        assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[1], &[3,4,5]];
-        assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[], &[], &[], &[4,5]];
-        assert_eq!(xs.splitn(3, |_| true).collect::<Vec<_>>(),
-                   splits);
-
-        let xs: &[i32] = &[];
-        let splits: &[&[i32]] = &[&[]];
-        assert_eq!(xs.splitn(1, |x| *x == 5).collect::<Vec<_>>(), splits);
-    }
-
-    #[test]
-    fn test_splitnator_mut() {
-        let xs = &mut [1,2,3,4,5];
-
-        let splits: &[&mut[_]] = &[&mut [1,2,3,4,5]];
-        assert_eq!(xs.splitn_mut(0, |x| *x % 2 == 0).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&mut[_]] = &[&mut [1], &mut [3,4,5]];
-        assert_eq!(xs.splitn_mut(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&mut[_]] = &[&mut [], &mut [], &mut [], &mut [4,5]];
-        assert_eq!(xs.splitn_mut(3, |_| true).collect::<Vec<_>>(),
-                   splits);
-
-        let xs: &mut [i32] = &mut [];
-        let splits: &[&mut[i32]] = &[&mut []];
-        assert_eq!(xs.splitn_mut(1, |x| *x == 5).collect::<Vec<_>>(),
-                   splits);
-    }
-
-    #[test]
-    fn test_rsplitator() {
-        let xs = &[1,2,3,4,5];
-
-        let splits: &[&[_]] = &[&[5], &[3], &[1]];
-        assert_eq!(xs.split(|x| *x % 2 == 0).rev().collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[2,3,4,5], &[]];
-        assert_eq!(xs.split(|x| *x == 1).rev().collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[], &[1,2,3,4]];
-        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[1,2,3,4,5]];
-        assert_eq!(xs.split(|x| *x == 10).rev().collect::<Vec<_>>(),
-                   splits);
-
-        let xs: &[i32] = &[];
-        let splits: &[&[i32]] = &[&[]];
-        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[i32]>>(), splits);
-    }
-
-    #[test]
-    fn test_rsplitnator() {
-        let xs = &[1,2,3,4,5];
-
-        let splits: &[&[_]] = &[&[1,2,3,4,5]];
-        assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[5], &[1,2,3]];
-        assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
-                   splits);
-        let splits: &[&[_]] = &[&[], &[], &[], &[1,2]];
-        assert_eq!(xs.rsplitn(3, |_| true).collect::<Vec<_>>(),
-                   splits);
-
-        let xs: &[i32]  = &[];
-        let splits: &[&[i32]] = &[&[]];
-        assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<Vec<&[i32]>>(), splits);
-    }
-
-    #[test]
-    fn test_windowsator() {
-        let v = &[1,2,3,4];
-
-        let wins: &[&[_]] = &[&[1,2], &[2,3], &[3,4]];
-        assert_eq!(v.windows(2).collect::<Vec<_>>(), wins);
-
-        let wins: &[&[_]] = &[&[1,2,3], &[2,3,4]];
-        assert_eq!(v.windows(3).collect::<Vec<_>>(), wins);
-        assert!(v.windows(6).next().is_none());
-
-        let wins: &[&[_]] = &[&[3,4], &[2,3], &[1,2]];
-        assert_eq!(v.windows(2).rev().collect::<Vec<&[_]>>(), wins);
-        let mut it = v.windows(2);
-        assert_eq!(it.indexable(), 3);
-        let win: &[_] = &[1,2];
-        assert_eq!(it.idx(0).unwrap(), win);
-        let win: &[_] = &[2,3];
-        assert_eq!(it.idx(1).unwrap(), win);
-        let win: &[_] = &[3,4];
-        assert_eq!(it.idx(2).unwrap(), win);
-        assert_eq!(it.idx(3), None);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_windowsator_0() {
-        let v = &[1,2,3,4];
-        let _it = v.windows(0);
-    }
-
-    #[test]
-    fn test_chunksator() {
-        use core::iter::ExactSizeIterator;
-
-        let v = &[1,2,3,4,5];
-
-        assert_eq!(v.chunks(2).len(), 3);
-
-        let chunks: &[&[_]] = &[&[1,2], &[3,4], &[5]];
-        assert_eq!(v.chunks(2).collect::<Vec<_>>(), chunks);
-        let chunks: &[&[_]] = &[&[1,2,3], &[4,5]];
-        assert_eq!(v.chunks(3).collect::<Vec<_>>(), chunks);
-        let chunks: &[&[_]] = &[&[1,2,3,4,5]];
-        assert_eq!(v.chunks(6).collect::<Vec<_>>(), chunks);
-
-        let chunks: &[&[_]] = &[&[5], &[3,4], &[1,2]];
-        assert_eq!(v.chunks(2).rev().collect::<Vec<_>>(), chunks);
-        let mut it = v.chunks(2);
-        assert_eq!(it.indexable(), 3);
-
-        let chunk: &[_] = &[1,2];
-        assert_eq!(it.idx(0).unwrap(), chunk);
-        let chunk: &[_] = &[3,4];
-        assert_eq!(it.idx(1).unwrap(), chunk);
-        let chunk: &[_] = &[5];
-        assert_eq!(it.idx(2).unwrap(), chunk);
-        assert_eq!(it.idx(3), None);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_chunksator_0() {
-        let v = &[1,2,3,4];
-        let _it = v.chunks(0);
-    }
-
-    #[test]
-    fn test_move_from() {
-        let mut a = [1,2,3,4,5];
-        let b = vec![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 = vec![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 = vec![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 = vec![5,6,7,8,9,0];
-        assert_eq!(a[2..4].move_from(b,1,6), 2);
-        assert!(a == [1,2,6,7,5]);
-    }
-
-    #[test]
-    fn test_reverse_part() {
-        let mut values = [1,2,3,4,5];
-        values[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), x_str);
-            })
-        }
-        let empty = Vec::<i32>::new();
-        test_show_vec!(empty, "[]");
-        test_show_vec!(vec![1], "[1]");
-        test_show_vec!(vec![1, 2, 3], "[1, 2, 3]");
-        test_show_vec!(vec![vec![], vec![1], vec![1, 1]],
-                       "[[], [1], [1, 1]]");
-
-        let empty_mut: &mut [i32] = &mut[];
-        test_show_vec!(empty_mut, "[]");
-        let v = &mut[1];
-        test_show_vec!(v, "[1]");
-        let v = &mut[1, 2, 3];
-        test_show_vec!(v, "[1, 2, 3]");
-        let v: &mut[&mut[_]] = &mut[&mut[], &mut[1], &mut[1, 1]];
-        test_show_vec!(v, "[[], [1], [1, 1]]");
-    }
-
-    #[test]
-    fn test_vec_default() {
-        macro_rules! t {
-            ($ty:ty) => {{
-                let v: $ty = Default::default();
-                assert!(v.is_empty());
-            }}
-        }
-
-        t!(&[i32]);
-        t!(Vec<i32>);
-    }
-
-    #[test]
-    fn test_bytes_set_memory() {
-        use slice::bytes::MutableByteVector;
-        let mut values = [1,2,3,4,5];
-        values[0..5].set_memory(0xAB);
-        assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
-        values[2..4].set_memory(0xFF);
-        assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_overflow_does_not_cause_segfault() {
-        let mut v = vec![];
-        v.reserve_exact(-1);
-        v.push(1);
-        v.push(2);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_overflow_does_not_cause_segfault_managed() {
-        let mut v = vec![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.split_at_mut(2);
-            {
-                let left: &[_] = left;
-                assert!(left[..left.len()] == [1, 2]);
-            }
-            for p in left {
-                *p += 1;
-            }
-
-            {
-                let right: &[_] = right;
-                assert!(right[..right.len()] == [3, 4, 5]);
-            }
-            for p in right {
-                *p += 2;
-            }
-        }
-
-        assert!(values == [2, 3, 5, 6, 7]);
-    }
-
-    #[derive(Clone, PartialEq)]
-    struct Foo;
-
-    #[test]
-    fn test_iter_zero_sized() {
-        let mut v = vec![Foo, Foo, Foo];
-        assert_eq!(v.len(), 3);
-        let mut cnt = 0;
-
-        for f in &v {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 3);
-
-        for f in &v[1..3] {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 5);
-
-        for f in &mut v {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 8);
-
-        for f in v {
-            assert!(f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 11);
-
-        let xs: [Foo; 3] = [Foo, Foo, Foo];
-        cnt = 0;
-        for f in &xs {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert!(cnt == 3);
-    }
-
-    #[test]
-    fn test_shrink_to_fit() {
-        let mut xs = vec![0, 1, 2, 3];
-        for i in 4..100 {
-            xs.push(i)
-        }
-        assert_eq!(xs.capacity(), 128);
-        xs.shrink_to_fit();
-        assert_eq!(xs.capacity(), 100);
-        assert_eq!(xs, (0..100).collect::<Vec<_>>());
-    }
-
-    #[test]
-    fn test_starts_with() {
-        assert!(b"foobar".starts_with(b"foo"));
-        assert!(!b"foobar".starts_with(b"oob"));
-        assert!(!b"foobar".starts_with(b"bar"));
-        assert!(!b"foo".starts_with(b"foobar"));
-        assert!(!b"bar".starts_with(b"foobar"));
-        assert!(b"foobar".starts_with(b"foobar"));
-        let empty: &[u8] = &[];
-        assert!(empty.starts_with(empty));
-        assert!(!empty.starts_with(b"foo"));
-        assert!(b"foobar".starts_with(empty));
-    }
-
-    #[test]
-    fn test_ends_with() {
-        assert!(b"foobar".ends_with(b"bar"));
-        assert!(!b"foobar".ends_with(b"oba"));
-        assert!(!b"foobar".ends_with(b"foo"));
-        assert!(!b"foo".ends_with(b"foobar"));
-        assert!(!b"bar".ends_with(b"foobar"));
-        assert!(b"foobar".ends_with(b"foobar"));
-        let empty: &[u8] = &[];
-        assert!(empty.ends_with(empty));
-        assert!(!empty.ends_with(b"foo"));
-        assert!(b"foobar".ends_with(empty));
-    }
-
-    #[test]
-    fn test_mut_splitator() {
-        let mut xs = [0,1,0,2,3,0,0,4,5,0];
-        assert_eq!(xs.split_mut(|x| *x == 0).count(), 6);
-        for slice in xs.split_mut(|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.split_mut(|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.split_mut(|x| *x == 0).rev().take(4) {
-            slice.reverse();
-        }
-        assert!(xs == [1,2,0,4,3,0,0,6,5,0]);
-    }
-
-    #[test]
-    fn test_get_mut() {
-        let mut v = [0,1,2];
-        assert_eq!(v.get_mut(3), None);
-        v.get_mut(1).map(|e| *e = 7);
-        assert_eq!(v[1], 7);
-        let mut x = 2;
-        assert_eq!(v.get_mut(2), Some(&mut x));
-    }
-
-    #[test]
-    fn test_mut_chunks() {
-        use core::iter::ExactSizeIterator;
-
-        let mut v = [0, 1, 2, 3, 4, 5, 6];
-        assert_eq!(v.chunks_mut(2).len(), 4);
-        for (i, chunk) in v.chunks_mut(3).enumerate() {
-            for x in chunk {
-                *x = i as u8;
-            }
-        }
-        let result = [0, 0, 0, 1, 1, 1, 2];
-        assert!(v == result);
-    }
-
-    #[test]
-    fn test_mut_chunks_rev() {
-        let mut v = [0, 1, 2, 3, 4, 5, 6];
-        for (i, chunk) in v.chunks_mut(3).rev().enumerate() {
-            for x in chunk {
-                *x = i as u8;
-            }
-        }
-        let result = [2, 2, 2, 1, 1, 1, 0];
-        assert!(v == result);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_mut_chunks_0() {
-        let mut v = [1, 2, 3, 4];
-        let _it = v.chunks_mut(0);
-    }
-
-    #[test]
-    fn test_mut_last() {
-        let mut x = [1, 2, 3, 4, 5];
-        let h = x.last_mut();
-        assert_eq!(*h.unwrap(), 5);
-
-        let y: &mut [i32] = &mut [];
-        assert!(y.last_mut().is_none());
-    }
-
-    #[test]
-    fn test_to_vec() {
-        let xs: Box<_> = box [1, 2, 3];
-        let ys = xs.to_vec();
-        assert_eq!(ys, [1, 2, 3]);
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    use prelude::*;
-    use core::mem;
-    use core::ptr;
-    use core::iter::repeat;
-    use std::rand::{weak_rng, Rng};
-    use test::{Bencher, black_box};
-
-    #[bench]
-    fn iterator(b: &mut Bencher) {
-        // peculiar numbers to stop LLVM from optimising the summation
-        // out.
-        let v: Vec<_> = (0..100).map(|i| i ^ (i << 1) ^ (i >> 1)).collect();
-
-        b.iter(|| {
-            let mut sum = 0;
-            for x in &v {
-                sum += *x;
-            }
-            // sum == 11806, to stop dead code elimination.
-            if sum == 0 {panic!()}
-        })
-    }
-
-    #[bench]
-    fn mut_iterator(b: &mut Bencher) {
-        let mut v: Vec<_> = repeat(0).take(100).collect();
-
-        b.iter(|| {
-            let mut i = 0;
-            for x in &mut v {
-                *x = i;
-                i += 1;
-            }
-        })
-    }
-
-    #[bench]
-    fn concat(b: &mut Bencher) {
-        let xss: Vec<Vec<i32>> =
-            (0..100).map(|i| (0..i).collect()).collect();
-        b.iter(|| {
-            xss.concat();
-        });
-    }
-
-    #[bench]
-    fn connect(b: &mut Bencher) {
-        let xss: Vec<Vec<i32>> =
-            (0..100).map(|i| (0..i).collect()).collect();
-        b.iter(|| {
-            xss.connect(&0)
-        });
-    }
-
-    #[bench]
-    fn push(b: &mut Bencher) {
-        let mut vec = Vec::<i32>::new();
-        b.iter(|| {
-            vec.push(0);
-            black_box(&vec);
-        });
-    }
-
-    #[bench]
-    fn starts_with_same_vector(b: &mut Bencher) {
-        let vec: Vec<_> = (0..100).collect();
-        b.iter(|| {
-            vec.starts_with(&vec)
-        })
-    }
-
-    #[bench]
-    fn starts_with_single_element(b: &mut Bencher) {
-        let vec: Vec<_> = vec![0];
-        b.iter(|| {
-            vec.starts_with(&vec)
-        })
-    }
-
-    #[bench]
-    fn starts_with_diff_one_element_at_end(b: &mut Bencher) {
-        let vec: Vec<_> = (0..100).collect();
-        let mut match_vec: Vec<_> = (0..99).collect();
-        match_vec.push(0);
-        b.iter(|| {
-            vec.starts_with(&match_vec)
-        })
-    }
-
-    #[bench]
-    fn ends_with_same_vector(b: &mut Bencher) {
-        let vec: Vec<_> = (0..100).collect();
-        b.iter(|| {
-            vec.ends_with(&vec)
-        })
-    }
-
-    #[bench]
-    fn ends_with_single_element(b: &mut Bencher) {
-        let vec: Vec<_> = vec![0];
-        b.iter(|| {
-            vec.ends_with(&vec)
-        })
-    }
-
-    #[bench]
-    fn ends_with_diff_one_element_at_beginning(b: &mut Bencher) {
-        let vec: Vec<_> = (0..100).collect();
-        let mut match_vec: Vec<_> = (0..100).collect();
-        match_vec[0] = 200;
-        b.iter(|| {
-            vec.starts_with(&match_vec)
-        })
-    }
-
-    #[bench]
-    fn contains_last_element(b: &mut Bencher) {
-        let vec: Vec<_> = (0..100).collect();
-        b.iter(|| {
-            vec.contains(&99)
-        })
-    }
-
-    #[bench]
-    fn zero_1kb_from_elem(b: &mut Bencher) {
-        b.iter(|| {
-            repeat(0u8).take(1024).collect::<Vec<_>>()
-        });
-    }
-
-    #[bench]
-    fn zero_1kb_set_memory(b: &mut Bencher) {
-        b.iter(|| {
-            let mut v = Vec::<u8>::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_loop_set(b: &mut Bencher) {
-        b.iter(|| {
-            let mut v = Vec::<u8>::with_capacity(1024);
-            unsafe {
-                v.set_len(1024);
-            }
-            for i in 0..1024 {
-                v[i] = 0;
-            }
-        });
-    }
-
-    #[bench]
-    fn zero_1kb_mut_iter(b: &mut Bencher) {
-        b.iter(|| {
-            let mut v = Vec::<u8>::with_capacity(1024);
-            unsafe {
-                v.set_len(1024);
-            }
-            for x in &mut v {
-                *x = 0;
-            }
-            v
-        });
-    }
-
-    #[bench]
-    fn random_inserts(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v: Vec<_> = repeat((0, 0)).take(30).collect();
-            for _ in 0..100 {
-                let l = v.len();
-                v.insert(rng.gen::<usize>() % (l + 1),
-                         (1, 1));
-            }
-        })
-    }
-    #[bench]
-    fn random_removes(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v: Vec<_> = repeat((0, 0)).take(130).collect();
-            for _ in 0..100 {
-                let l = v.len();
-                v.remove(rng.gen::<usize>() % l);
-            }
-        })
-    }
-
-    #[bench]
-    fn sort_random_small(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v: Vec<_> = rng.gen_iter::<u64>().take(5).collect();
-            v.sort();
-        });
-        b.bytes = 5 * mem::size_of::<u64>() as u64;
-    }
-
-    #[bench]
-    fn sort_random_medium(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v: Vec<_> = rng.gen_iter::<u64>().take(100).collect();
-            v.sort();
-        });
-        b.bytes = 100 * mem::size_of::<u64>() as u64;
-    }
-
-    #[bench]
-    fn sort_random_large(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v: Vec<_> = rng.gen_iter::<u64>().take(10000).collect();
-            v.sort();
-        });
-        b.bytes = 10000 * mem::size_of::<u64>() as u64;
-    }
-
-    #[bench]
-    fn sort_sorted(b: &mut Bencher) {
-        let mut v: Vec<_> = (0..10000).collect();
-        b.iter(|| {
-            v.sort();
-        });
-        b.bytes = (v.len() * mem::size_of_val(&v[0])) as u64;
-    }
-
-    type BigSortable = (u64, u64, u64, u64);
-
-    #[bench]
-    fn sort_big_random_small(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v = rng.gen_iter::<BigSortable>().take(5)
-                           .collect::<Vec<BigSortable>>();
-            v.sort();
-        });
-        b.bytes = 5 * mem::size_of::<BigSortable>() as u64;
-    }
-
-    #[bench]
-    fn sort_big_random_medium(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v = rng.gen_iter::<BigSortable>().take(100)
-                           .collect::<Vec<BigSortable>>();
-            v.sort();
-        });
-        b.bytes = 100 * mem::size_of::<BigSortable>() as u64;
-    }
-
-    #[bench]
-    fn sort_big_random_large(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v = rng.gen_iter::<BigSortable>().take(10000)
-                           .collect::<Vec<BigSortable>>();
-            v.sort();
-        });
-        b.bytes = 10000 * mem::size_of::<BigSortable>() as u64;
-    }
-
-    #[bench]
-    fn sort_big_sorted(b: &mut Bencher) {
-        let mut v: Vec<BigSortable> = (0..10000).map(|i| (i, i, i, i)).collect();
-        b.iter(|| {
-            v.sort();
-        });
-        b.bytes = (v.len() * mem::size_of_val(&v[0])) as u64;
-    }
-}
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index f749f54f2e4..b2273646b95 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -59,17 +59,21 @@ use self::DecompositionType::*;
 use core::clone::Clone;
 use core::iter::AdditiveIterator;
 use core::iter::{Iterator, IteratorExt, Extend};
+#[cfg(stage0)]
 use core::ops::Index;
+#[cfg(stage0)]
 use core::ops::RangeFull;
 use core::option::Option::{self, Some, None};
 use core::result::Result;
 use core::slice::AsSlice;
 use core::str as core_str;
+#[cfg(stage0)]
 use unicode::char::CharExt;
 use unicode::str::{UnicodeStr, Utf16Encoder};
 
 use vec_deque::VecDeque;
 use borrow::{Borrow, ToOwned};
+#[cfg(stage0)]
 use slice::SliceExt;
 use string::String;
 use unicode;
@@ -415,6 +419,7 @@ Section: CowString
 Section: Trait implementations
 */
 
+#[cfg(stage0)]
 /// Any string that can be represented as a slice.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait StrExt: Index<RangeFull, Output = str> {
@@ -1539,6 +1544,7 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     }
 }
 
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl StrExt for str {
     fn slice(&self, begin: usize, end: usize) -> &str {
@@ -1554,1667 +1560,1135 @@ impl StrExt for str {
     }
 }
 
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-
-    use core::iter::AdditiveIterator;
-    use super::from_utf8;
-    use super::Utf8Error;
-
-    #[test]
-    fn test_le() {
-        assert!("" <= "");
-        assert!("" <= "foo");
-        assert!("foo" <= "foo");
-        assert!("foo" != "bar");
-    }
-
-    #[test]
-    fn test_len() {
-        assert_eq!("".len(), 0);
-        assert_eq!("hello world".len(), 11);
-        assert_eq!("\x63".len(), 1);
-        assert_eq!("\u{a2}".len(), 2);
-        assert_eq!("\u{3c0}".len(), 2);
-        assert_eq!("\u{2620}".len(), 3);
-        assert_eq!("\u{1d11e}".len(), 4);
-
-        assert_eq!("".chars().count(), 0);
-        assert_eq!("hello world".chars().count(), 11);
-        assert_eq!("\x63".chars().count(), 1);
-        assert_eq!("\u{a2}".chars().count(), 1);
-        assert_eq!("\u{3c0}".chars().count(), 1);
-        assert_eq!("\u{2620}".chars().count(), 1);
-        assert_eq!("\u{1d11e}".chars().count(), 1);
-        assert_eq!("ประเทศไทย中华Việt Nam".chars().count(), 19);
-
-        assert_eq!("hello".width(false), 10);
-        assert_eq!("hello".width(true), 10);
-        assert_eq!("\0\0\0\0\0".width(false), 0);
-        assert_eq!("\0\0\0\0\0".width(true), 0);
-        assert_eq!("".width(false), 0);
-        assert_eq!("".width(true), 0);
-        assert_eq!("\u{2081}\u{2082}\u{2083}\u{2084}".width(false), 4);
-        assert_eq!("\u{2081}\u{2082}\u{2083}\u{2084}".width(true), 8);
-    }
-
-    #[test]
-    fn test_find() {
-        assert_eq!("hello".find('l'), Some(2));
-        assert_eq!("hello".find(|c:char| c == 'o'), Some(4));
-        assert!("hello".find('x').is_none());
-        assert!("hello".find(|c:char| c == 'x').is_none());
-        assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30));
-        assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30));
-    }
-
-    #[test]
-    fn test_rfind() {
-        assert_eq!("hello".rfind('l'), Some(3));
-        assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4));
-        assert!("hello".rfind('x').is_none());
-        assert!("hello".rfind(|c:char| c == 'x').is_none());
-        assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30));
-        assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30));
-    }
-
-    #[test]
-    fn test_collect() {
-        let empty = String::from_str("");
-        let s: String = empty.chars().collect();
-        assert_eq!(empty, s);
-        let data = String::from_str("ประเทศไทย中");
-        let s: String = data.chars().collect();
-        assert_eq!(data, s);
-    }
-
-    #[test]
-    fn test_into_bytes() {
-        let data = String::from_str("asdf");
-        let buf = data.into_bytes();
-        assert_eq!(b"asdf", buf);
-    }
-
-    #[test]
-    fn test_find_str() {
-        // byte positions
-        assert_eq!("".find_str(""), Some(0));
-        assert!("banana".find_str("apple pie").is_none());
-
-        let data = "abcabc";
-        assert_eq!(data[0..6].find_str("ab"), Some(0));
-        assert_eq!(data[2..6].find_str("ab"), Some(3 - 2));
-        assert!(data[2..4].find_str("ab").is_none());
-
-        let string = "ประเทศไทย中华Việt Nam";
-        let mut data = String::from_str(string);
-        data.push_str(string);
-        assert!(data.find_str("ไท华").is_none());
-        assert_eq!(data[0..43].find_str(""), Some(0));
-        assert_eq!(data[6..43].find_str(""), Some(6 - 6));
-
-        assert_eq!(data[0..43].find_str("ประ"), Some( 0));
-        assert_eq!(data[0..43].find_str("ทศไ"), Some(12));
-        assert_eq!(data[0..43].find_str("ย中"), Some(24));
-        assert_eq!(data[0..43].find_str("iệt"), Some(34));
-        assert_eq!(data[0..43].find_str("Nam"), Some(40));
-
-        assert_eq!(data[43..86].find_str("ประ"), Some(43 - 43));
-        assert_eq!(data[43..86].find_str("ทศไ"), Some(55 - 43));
-        assert_eq!(data[43..86].find_str("ย中"), Some(67 - 43));
-        assert_eq!(data[43..86].find_str("iệt"), Some(77 - 43));
-        assert_eq!(data[43..86].find_str("Nam"), Some(83 - 43));
-    }
-
-    #[test]
-    fn test_slice_chars() {
-        fn t(a: &str, b: &str, start: usize) {
-            assert_eq!(a.slice_chars(start, start + b.chars().count()), b);
-        }
-        t("", "", 0);
-        t("hello", "llo", 2);
-        t("hello", "el", 1);
-        t("αβλ", "β", 1);
-        t("αβλ", "", 3);
-        assert_eq!("ะเทศไท", "ประเทศไทย中华Việt Nam".slice_chars(2, 8));
-    }
-
-    fn s(x: &str) -> String { x.to_string() }
-
-    macro_rules! test_concat {
-        ($expected: expr, $string: expr) => {
-            {
-                let s: String = $string.concat();
-                assert_eq!($expected, s);
-            }
-        }
-    }
-
-    #[test]
-    fn test_concat_for_different_types() {
-        test_concat!("ab", vec![s("a"), s("b")]);
-        test_concat!("ab", vec!["a", "b"]);
-        test_concat!("ab", vec!["a", "b"]);
-        test_concat!("ab", vec![s("a"), s("b")]);
+#[cfg(not(stage0))]
+/// Any string that can be represented as a slice.
+#[lang = "str"]
+#[cfg(not(test))]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl str {
+    /// Escapes each char in `s` with `char::escape_default`.
+    #[unstable(feature = "collections",
+               reason = "return type may change to be an iterator")]
+    pub fn escape_default(&self) -> String {
+        self.chars().flat_map(|c| c.escape_default()).collect()
     }
 
-    #[test]
-    fn test_concat_for_different_lengths() {
-        let empty: &[&str] = &[];
-        test_concat!("", empty);
-        test_concat!("a", ["a"]);
-        test_concat!("ab", ["a", "b"]);
-        test_concat!("abc", ["", "a", "bc"]);
+    /// Escapes each char in `s` with `char::escape_unicode`.
+    #[unstable(feature = "collections",
+               reason = "return type may change to be an iterator")]
+    pub fn escape_unicode(&self) -> String {
+        self.chars().flat_map(|c| c.escape_unicode()).collect()
     }
 
-    macro_rules! test_connect {
-        ($expected: expr, $string: expr, $delim: expr) => {
-            {
-                let s = $string.connect($delim);
-                assert_eq!($expected, s);
-            }
+    /// Replaces all occurrences of one string with another.
+    ///
+    /// `replace` takes two arguments, a sub-`&str` to find in `self`, and a second `&str` to
+    /// replace it with. If the original `&str` isn't found, no change occurs.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = "this is old";
+    ///
+    /// assert_eq!(s.replace("old", "new"), "this is new");
+    /// ```
+    ///
+    /// When a `&str` isn't found:
+    ///
+    /// ```
+    /// let s = "this is old";
+    /// assert_eq!(s.replace("cookie monster", "little lamb"), s);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn replace(&self, from: &str, to: &str) -> String {
+        let mut result = String::new();
+        let mut last_end = 0;
+        for (start, end) in self.match_indices(from) {
+            result.push_str(unsafe { self.slice_unchecked(last_end, start) });
+            result.push_str(to);
+            last_end = end;
         }
+        result.push_str(unsafe { self.slice_unchecked(last_end, self.len()) });
+        result
     }
 
-    #[test]
-    fn test_connect_for_different_types() {
-        test_connect!("a-b", ["a", "b"], "-");
-        let hyphen = "-".to_string();
-        test_connect!("a-b", [s("a"), s("b")], &*hyphen);
-        test_connect!("a-b", vec!["a", "b"], &*hyphen);
-        test_connect!("a-b", &*vec!["a", "b"], "-");
-        test_connect!("a-b", vec![s("a"), s("b")], "-");
-    }
-
-    #[test]
-    fn test_connect_for_different_lengths() {
-        let empty: &[&str] = &[];
-        test_connect!("", empty, "-");
-        test_connect!("a", ["a"], "-");
-        test_connect!("a-b", ["a", "b"], "-");
-        test_connect!("-a-bc", ["", "a", "bc"], "-");
-    }
-
-    #[test]
-    fn test_unsafe_slice() {
-        assert_eq!("ab", unsafe {"abc".slice_unchecked(0, 2)});
-        assert_eq!("bc", unsafe {"abc".slice_unchecked(1, 3)});
-        assert_eq!("", unsafe {"abc".slice_unchecked(1, 1)});
-        fn a_million_letter_a() -> String {
-            let mut i = 0;
-            let mut rs = String::new();
-            while i < 100000 {
-                rs.push_str("aaaaaaaaaa");
-                i += 1;
-            }
-            rs
-        }
-        fn half_a_million_letter_a() -> String {
-            let mut i = 0;
-            let mut rs = String::new();
-            while i < 100000 {
-                rs.push_str("aaaaa");
-                i += 1;
-            }
-            rs
-        }
-        let letters = a_million_letter_a();
-        assert!(half_a_million_letter_a() ==
-            unsafe {String::from_str(letters.slice_unchecked(
-                                     0,
-                                     500000))});
-    }
-
-    #[test]
-    fn test_starts_with() {
-        assert!(("".starts_with("")));
-        assert!(("abc".starts_with("")));
-        assert!(("abc".starts_with("a")));
-        assert!((!"a".starts_with("abc")));
-        assert!((!"".starts_with("abc")));
-        assert!((!"ödd".starts_with("-")));
-        assert!(("ödd".starts_with("öd")));
-    }
-
-    #[test]
-    fn test_ends_with() {
-        assert!(("".ends_with("")));
-        assert!(("abc".ends_with("")));
-        assert!(("abc".ends_with("c")));
-        assert!((!"a".ends_with("abc")));
-        assert!((!"".ends_with("abc")));
-        assert!((!"ddö".ends_with("-")));
-        assert!(("ddö".ends_with("dö")));
-    }
-
-    #[test]
-    fn test_is_empty() {
-        assert!("".is_empty());
-        assert!(!"a".is_empty());
-    }
-
-    #[test]
-    fn test_replace() {
-        let a = "a";
-        assert_eq!("".replace(a, "b"), String::from_str(""));
-        assert_eq!("a".replace(a, "b"), String::from_str("b"));
-        assert_eq!("ab".replace(a, "b"), String::from_str("bb"));
-        let test = "test";
-        assert!(" test test ".replace(test, "toast") ==
-            String::from_str(" toast toast "));
-        assert_eq!(" test test ".replace(test, ""), String::from_str("   "));
-    }
-
-    #[test]
-    fn test_replace_2a() {
-        let data = "ประเทศไทย中华";
-        let repl = "دولة الكويت";
-
-        let a = "ประเ";
-        let a2 = "دولة الكويتทศไทย中华";
-        assert_eq!(data.replace(a, repl), a2);
-    }
-
-    #[test]
-    fn test_replace_2b() {
-        let data = "ประเทศไทย中华";
-        let repl = "دولة الكويت";
-
-        let b = "ะเ";
-        let b2 = "ปรدولة الكويتทศไทย中华";
-        assert_eq!(data.replace(b, repl), b2);
-    }
-
-    #[test]
-    fn test_replace_2c() {
-        let data = "ประเทศไทย中华";
-        let repl = "دولة الكويت";
-
-        let c = "中华";
-        let c2 = "ประเทศไทยدولة الكويت";
-        assert_eq!(data.replace(c, repl), c2);
-    }
-
-    #[test]
-    fn test_replace_2d() {
-        let data = "ประเทศไทย中华";
-        let repl = "دولة الكويت";
-
-        let d = "ไท华";
-        assert_eq!(data.replace(d, repl), data);
-    }
-
-    #[test]
-    fn test_slice() {
-        assert_eq!("ab", "abc".slice(0, 2));
-        assert_eq!("bc", "abc".slice(1, 3));
-        assert_eq!("", "abc".slice(1, 1));
-        assert_eq!("\u{65e5}", "\u{65e5}\u{672c}".slice(0, 3));
-
-        let data = "ประเทศไทย中华";
-        assert_eq!("ป", data.slice(0, 3));
-        assert_eq!("ร", data.slice(3, 6));
-        assert_eq!("", data.slice(3, 3));
-        assert_eq!("华", data.slice(30, 33));
-
-        fn a_million_letter_x() -> String {
-            let mut i = 0;
-            let mut rs = String::new();
-            while i < 100000 {
-                rs.push_str("华华华华华华华华华华");
-                i += 1;
-            }
-            rs
-        }
-        fn half_a_million_letter_x() -> String {
-            let mut i = 0;
-            let mut rs = String::new();
-            while i < 100000 {
-                rs.push_str("华华华华华");
-                i += 1;
-            }
-            rs
-        }
-        let letters = a_million_letter_x();
-        assert!(half_a_million_letter_x() ==
-            String::from_str(letters.slice(0, 3 * 500000)));
-    }
-
-    #[test]
-    fn test_slice_2() {
-        let ss = "中华Việt Nam";
-
-        assert_eq!("华", ss.slice(3, 6));
-        assert_eq!("Việt Nam", ss.slice(6, 16));
-
-        assert_eq!("ab", "abc".slice(0, 2));
-        assert_eq!("bc", "abc".slice(1, 3));
-        assert_eq!("", "abc".slice(1, 1));
-
-        assert_eq!("中", ss.slice(0, 3));
-        assert_eq!("华V", ss.slice(3, 7));
-        assert_eq!("", ss.slice(3, 3));
-        /*0: 中
-          3: 华
-          6: V
-          7: i
-          8: ệ
-         11: t
-         12:
-         13: N
-         14: a
-         15: m */
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_slice_fail() {
-        "中华Việt Nam".slice(0, 2);
-    }
-
-    #[test]
-    fn test_slice_from() {
-        assert_eq!("abcd".slice_from(0), "abcd");
-        assert_eq!("abcd".slice_from(2), "cd");
-        assert_eq!("abcd".slice_from(4), "");
-    }
-    #[test]
-    fn test_slice_to() {
-        assert_eq!("abcd".slice_to(0), "");
-        assert_eq!("abcd".slice_to(2), "ab");
-        assert_eq!("abcd".slice_to(4), "abcd");
-    }
-
-    #[test]
-    fn test_trim_left_matches() {
-        let v: &[char] = &[];
-        assert_eq!(" *** foo *** ".trim_left_matches(v), " *** foo *** ");
-        let chars: &[char] = &['*', ' '];
-        assert_eq!(" *** foo *** ".trim_left_matches(chars), "foo *** ");
-        assert_eq!(" ***  *** ".trim_left_matches(chars), "");
-        assert_eq!("foo *** ".trim_left_matches(chars), "foo *** ");
-
-        assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
-        let chars: &[char] = &['1', '2'];
-        assert_eq!("12foo1bar12".trim_left_matches(chars), "foo1bar12");
-        assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123");
-    }
-
-    #[test]
-    fn test_trim_right_matches() {
-        let v: &[char] = &[];
-        assert_eq!(" *** foo *** ".trim_right_matches(v), " *** foo *** ");
-        let chars: &[char] = &['*', ' '];
-        assert_eq!(" *** foo *** ".trim_right_matches(chars), " *** foo");
-        assert_eq!(" ***  *** ".trim_right_matches(chars), "");
-        assert_eq!(" *** foo".trim_right_matches(chars), " *** foo");
-
-        assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
-        let chars: &[char] = &['1', '2'];
-        assert_eq!("12foo1bar12".trim_right_matches(chars), "12foo1bar");
-        assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar");
-    }
-
-    #[test]
-    fn test_trim_matches() {
-        let v: &[char] = &[];
-        assert_eq!(" *** foo *** ".trim_matches(v), " *** foo *** ");
-        let chars: &[char] = &['*', ' '];
-        assert_eq!(" *** foo *** ".trim_matches(chars), "foo");
-        assert_eq!(" ***  *** ".trim_matches(chars), "");
-        assert_eq!("foo".trim_matches(chars), "foo");
-
-        assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
-        let chars: &[char] = &['1', '2'];
-        assert_eq!("12foo1bar12".trim_matches(chars), "foo1bar");
-        assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar");
-    }
-
-    #[test]
-    fn test_trim_left() {
-        assert_eq!("".trim_left(), "");
-        assert_eq!("a".trim_left(), "a");
-        assert_eq!("    ".trim_left(), "");
-        assert_eq!("     blah".trim_left(), "blah");
-        assert_eq!("   \u{3000}  wut".trim_left(), "wut");
-        assert_eq!("hey ".trim_left(), "hey ");
-    }
-
-    #[test]
-    fn test_trim_right() {
-        assert_eq!("".trim_right(), "");
-        assert_eq!("a".trim_right(), "a");
-        assert_eq!("    ".trim_right(), "");
-        assert_eq!("blah     ".trim_right(), "blah");
-        assert_eq!("wut   \u{3000}  ".trim_right(), "wut");
-        assert_eq!(" hey".trim_right(), " hey");
-    }
-
-    #[test]
-    fn test_trim() {
-        assert_eq!("".trim(), "");
-        assert_eq!("a".trim(), "a");
-        assert_eq!("    ".trim(), "");
-        assert_eq!("    blah     ".trim(), "blah");
-        assert_eq!("\nwut   \u{3000}  ".trim(), "wut");
-        assert_eq!(" hey dude ".trim(), "hey dude");
-    }
-
-    #[test]
-    fn test_is_whitespace() {
-        assert!("".chars().all(|c| c.is_whitespace()));
-        assert!(" ".chars().all(|c| c.is_whitespace()));
-        assert!("\u{2009}".chars().all(|c| c.is_whitespace())); // Thin space
-        assert!("  \n\t   ".chars().all(|c| c.is_whitespace()));
-        assert!(!"   _   ".chars().all(|c| c.is_whitespace()));
-    }
-
-    #[test]
-    fn test_slice_shift_char() {
-        let data = "ประเทศไทย中";
-        assert_eq!(data.slice_shift_char(), Some(('ป', "ระเทศไทย中")));
-    }
-
-    #[test]
-    fn test_slice_shift_char_2() {
-        let empty = "";
-        assert_eq!(empty.slice_shift_char(), None);
-    }
-
-    #[test]
-    fn test_is_utf8() {
-        // deny overlong encodings
-        assert!(from_utf8(&[0xc0, 0x80]).is_err());
-        assert!(from_utf8(&[0xc0, 0xae]).is_err());
-        assert!(from_utf8(&[0xe0, 0x80, 0x80]).is_err());
-        assert!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err());
-        assert!(from_utf8(&[0xe0, 0x81, 0x81]).is_err());
-        assert!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err());
-        assert!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err());
-
-        // deny surrogates
-        assert!(from_utf8(&[0xED, 0xA0, 0x80]).is_err());
-        assert!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err());
-
-        assert!(from_utf8(&[0xC2, 0x80]).is_ok());
-        assert!(from_utf8(&[0xDF, 0xBF]).is_ok());
-        assert!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok());
-        assert!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok());
-        assert!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok());
-        assert!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok());
-        assert!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok());
-        assert!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok());
-    }
-
-    #[test]
-    fn test_is_utf16() {
-        use unicode::str::is_utf16;
-        macro_rules! pos {
-            ($($e:expr),*) => { { $(assert!(is_utf16($e));)* } }
-        }
-
-        // non-surrogates
-        pos!(&[0x0000],
-             &[0x0001, 0x0002],
-             &[0xD7FF],
-             &[0xE000]);
-
-        // surrogate pairs (randomly generated with Python 3's
-        // .encode('utf-16be'))
-        pos!(&[0xdb54, 0xdf16, 0xd880, 0xdee0, 0xdb6a, 0xdd45],
-             &[0xd91f, 0xdeb1, 0xdb31, 0xdd84, 0xd8e2, 0xde14],
-             &[0xdb9f, 0xdc26, 0xdb6f, 0xde58, 0xd850, 0xdfae]);
-
-        // mixtures (also random)
-        pos!(&[0xd921, 0xdcc2, 0x002d, 0x004d, 0xdb32, 0xdf65],
-             &[0xdb45, 0xdd2d, 0x006a, 0xdacd, 0xddfe, 0x0006],
-             &[0x0067, 0xd8ff, 0xddb7, 0x000f, 0xd900, 0xdc80]);
-
-        // negative tests
-        macro_rules! neg {
-            ($($e:expr),*) => { { $(assert!(!is_utf16($e));)* } }
-        }
-
-        neg!(
-            // surrogate + regular unit
-            &[0xdb45, 0x0000],
-            // surrogate + lead surrogate
-            &[0xd900, 0xd900],
-            // unterminated surrogate
-            &[0xd8ff],
-            // trail surrogate without a lead
-            &[0xddb7]);
-
-        // random byte sequences that Python 3's .decode('utf-16be')
-        // failed on
-        neg!(&[0x5b3d, 0x0141, 0xde9e, 0x8fdc, 0xc6e7],
-             &[0xdf5a, 0x82a5, 0x62b9, 0xb447, 0x92f3],
-             &[0xda4e, 0x42bc, 0x4462, 0xee98, 0xc2ca],
-             &[0xbe00, 0xb04a, 0x6ecb, 0xdd89, 0xe278],
-             &[0x0465, 0xab56, 0xdbb6, 0xa893, 0x665e],
-             &[0x6b7f, 0x0a19, 0x40f4, 0xa657, 0xdcc5],
-             &[0x9b50, 0xda5e, 0x24ec, 0x03ad, 0x6dee],
-             &[0x8d17, 0xcaa7, 0xf4ae, 0xdf6e, 0xbed7],
-             &[0xdaee, 0x2584, 0x7d30, 0xa626, 0x121a],
-             &[0xd956, 0x4b43, 0x7570, 0xccd6, 0x4f4a],
-             &[0x9dcf, 0x1b49, 0x4ba5, 0xfce9, 0xdffe],
-             &[0x6572, 0xce53, 0xb05a, 0xf6af, 0xdacf],
-             &[0x1b90, 0x728c, 0x9906, 0xdb68, 0xf46e],
-             &[0x1606, 0xbeca, 0xbe76, 0x860f, 0xdfa5],
-             &[0x8b4f, 0xde7a, 0xd220, 0x9fac, 0x2b6f],
-             &[0xb8fe, 0xebbe, 0xda32, 0x1a5f, 0x8b8b],
-             &[0x934b, 0x8956, 0xc434, 0x1881, 0xddf7],
-             &[0x5a95, 0x13fc, 0xf116, 0xd89b, 0x93f9],
-             &[0xd640, 0x71f1, 0xdd7d, 0x77eb, 0x1cd8],
-             &[0x348b, 0xaef0, 0xdb2c, 0xebf1, 0x1282],
-             &[0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]);
-    }
-
-    #[test]
-    fn test_as_bytes() {
-        // no null
-        let v = [
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109
-        ];
-        let b: &[u8] = &[];
-        assert_eq!("".as_bytes(), b);
-        assert_eq!("abc".as_bytes(), b"abc");
-        assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_as_bytes_fail() {
-        // Don't double free. (I'm not sure if this exercises the
-        // original problem code path anymore.)
-        let s = String::from_str("");
-        let _bytes = s.as_bytes();
-        panic!();
-    }
-
-    #[test]
-    fn test_as_ptr() {
-        let buf = "hello".as_ptr();
-        unsafe {
-            assert_eq!(*buf.offset(0), b'h');
-            assert_eq!(*buf.offset(1), b'e');
-            assert_eq!(*buf.offset(2), b'l');
-            assert_eq!(*buf.offset(3), b'l');
-            assert_eq!(*buf.offset(4), b'o');
+    /// Returns an iterator over the string in Unicode Normalization Form D
+    /// (canonical decomposition).
+    #[inline]
+    #[unstable(feature = "collections",
+               reason = "this functionality may be moved to libunicode")]
+    pub fn nfd_chars(&self) -> Decompositions {
+        Decompositions {
+            iter: self[..].chars(),
+            buffer: Vec::new(),
+            sorted: false,
+            kind: Canonical
         }
     }
 
-    #[test]
-    fn test_subslice_offset() {
-        let a = "kernelsprite";
-        let b = &a[7..a.len()];
-        let c = &a[0..a.len() - 6];
-        assert_eq!(a.subslice_offset(b), 7);
-        assert_eq!(a.subslice_offset(c), 0);
-
-        let string = "a\nb\nc";
-        let lines: Vec<&str> = string.lines().collect();
-        assert_eq!(string.subslice_offset(lines[0]), 0);
-        assert_eq!(string.subslice_offset(lines[1]), 2);
-        assert_eq!(string.subslice_offset(lines[2]), 4);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_subslice_offset_2() {
-        let a = "alchemiter";
-        let b = "cruxtruder";
-        a.subslice_offset(b);
-    }
-
-    #[test]
-    fn vec_str_conversions() {
-        let s1: String = String::from_str("All mimsy were the borogoves");
-
-        let v: Vec<u8> = s1.as_bytes().to_vec();
-        let s2: String = String::from_str(from_utf8(&v).unwrap());
-        let mut i = 0;
-        let n1 = s1.len();
-        let n2 = v.len();
-        assert_eq!(n1, n2);
-        while i < n1 {
-            let a: u8 = s1.as_bytes()[i];
-            let b: u8 = s2.as_bytes()[i];
-            debug!("{}", a);
-            debug!("{}", b);
-            assert_eq!(a, b);
-            i += 1;
+    /// Returns an iterator over the string in Unicode Normalization Form KD
+    /// (compatibility decomposition).
+    #[inline]
+    #[unstable(feature = "collections",
+               reason = "this functionality may be moved to libunicode")]
+    pub fn nfkd_chars(&self) -> Decompositions {
+        Decompositions {
+            iter: self[..].chars(),
+            buffer: Vec::new(),
+            sorted: false,
+            kind: Compatible
         }
     }
 
-    #[test]
-    fn test_contains() {
-        assert!("abcde".contains("bcd"));
-        assert!("abcde".contains("abcd"));
-        assert!("abcde".contains("bcde"));
-        assert!("abcde".contains(""));
-        assert!("".contains(""));
-        assert!(!"abcde".contains("def"));
-        assert!(!"".contains("a"));
-
-        let data = "ประเทศไทย中华Việt Nam";
-        assert!(data.contains("ประเ"));
-        assert!(data.contains("ะเ"));
-        assert!(data.contains("中华"));
-        assert!(!data.contains("ไท华"));
-    }
-
-    #[test]
-    fn test_contains_char() {
-        assert!("abc".contains_char('b'));
-        assert!("a".contains_char('a'));
-        assert!(!"abc".contains_char('d'));
-        assert!(!"".contains_char('a'));
-    }
-
-    #[test]
-    fn test_char_at() {
-        let s = "ศไทย中华Việt Nam";
-        let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-        let mut pos = 0;
-        for ch in &v {
-            assert!(s.char_at(pos) == *ch);
-            pos += ch.to_string().len();
+    /// An Iterator over the string in Unicode Normalization Form C
+    /// (canonical decomposition followed by canonical composition).
+    #[inline]
+    #[unstable(feature = "collections",
+               reason = "this functionality may be moved to libunicode")]
+    pub fn nfc_chars(&self) -> Recompositions {
+        Recompositions {
+            iter: self.nfd_chars(),
+            state: Composing,
+            buffer: VecDeque::new(),
+            composee: None,
+            last_ccc: None
         }
     }
 
-    #[test]
-    fn test_char_at_reverse() {
-        let s = "ศไทย中华Việt Nam";
-        let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-        let mut pos = s.len();
-        for ch in v.iter().rev() {
-            assert!(s.char_at_reverse(pos) == *ch);
-            pos -= ch.to_string().len();
+    /// An Iterator over the string in Unicode Normalization Form KC
+    /// (compatibility decomposition followed by canonical composition).
+    #[inline]
+    #[unstable(feature = "collections",
+               reason = "this functionality may be moved to libunicode")]
+    pub fn nfkc_chars(&self) -> Recompositions {
+        Recompositions {
+            iter: self.nfkd_chars(),
+            state: Composing,
+            buffer: VecDeque::new(),
+            composee: None,
+            last_ccc: None
         }
     }
 
-    #[test]
-    fn test_escape_unicode() {
-        assert_eq!("abc".escape_unicode(),
-                   String::from_str("\\u{61}\\u{62}\\u{63}"));
-        assert_eq!("a c".escape_unicode(),
-                   String::from_str("\\u{61}\\u{20}\\u{63}"));
-        assert_eq!("\r\n\t".escape_unicode(),
-                   String::from_str("\\u{d}\\u{a}\\u{9}"));
-        assert_eq!("'\"\\".escape_unicode(),
-                   String::from_str("\\u{27}\\u{22}\\u{5c}"));
-        assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(),
-                   String::from_str("\\u{0}\\u{1}\\u{fe}\\u{ff}"));
-        assert_eq!("\u{100}\u{ffff}".escape_unicode(),
-                   String::from_str("\\u{100}\\u{ffff}"));
-        assert_eq!("\u{10000}\u{10ffff}".escape_unicode(),
-                   String::from_str("\\u{10000}\\u{10ffff}"));
-        assert_eq!("ab\u{fb00}".escape_unicode(),
-                   String::from_str("\\u{61}\\u{62}\\u{fb00}"));
-        assert_eq!("\u{1d4ea}\r".escape_unicode(),
-                   String::from_str("\\u{1d4ea}\\u{d}"));
-    }
-
-    #[test]
-    fn test_escape_default() {
-        assert_eq!("abc".escape_default(), String::from_str("abc"));
-        assert_eq!("a c".escape_default(), String::from_str("a c"));
-        assert_eq!("\r\n\t".escape_default(), String::from_str("\\r\\n\\t"));
-        assert_eq!("'\"\\".escape_default(), String::from_str("\\'\\\"\\\\"));
-        assert_eq!("\u{100}\u{ffff}".escape_default(),
-                   String::from_str("\\u{100}\\u{ffff}"));
-        assert_eq!("\u{10000}\u{10ffff}".escape_default(),
-                   String::from_str("\\u{10000}\\u{10ffff}"));
-        assert_eq!("ab\u{fb00}".escape_default(),
-                   String::from_str("ab\\u{fb00}"));
-        assert_eq!("\u{1d4ea}\r".escape_default(),
-                   String::from_str("\\u{1d4ea}\\r"));
-    }
-
-    #[test]
-    fn test_total_ord() {
-        "1234".cmp("123") == Greater;
-        "123".cmp("1234") == Less;
-        "1234".cmp("1234") == Equal;
-        "12345555".cmp("123456") == Less;
-        "22".cmp("1234") == Greater;
-    }
-
-    #[test]
-    fn test_char_range_at() {
-        let data = "b¢€𤭢𤭢€¢b";
-        assert_eq!('b', data.char_range_at(0).ch);
-        assert_eq!('¢', data.char_range_at(1).ch);
-        assert_eq!('€', data.char_range_at(3).ch);
-        assert_eq!('𤭢', data.char_range_at(6).ch);
-        assert_eq!('𤭢', data.char_range_at(10).ch);
-        assert_eq!('€', data.char_range_at(14).ch);
-        assert_eq!('¢', data.char_range_at(17).ch);
-        assert_eq!('b', data.char_range_at(19).ch);
-    }
-
-    #[test]
-    fn test_char_range_at_reverse_underflow() {
-        assert_eq!("abc".char_range_at_reverse(0).next, 0);
-    }
-
-    #[test]
-    fn test_iterator() {
-        let s = "ศไทย中华Việt Nam";
-        let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-
-        let mut pos = 0;
-        let it = s.chars();
-
-        for c in it {
-            assert_eq!(c, v[pos]);
-            pos += 1;
-        }
-        assert_eq!(pos, v.len());
+    /// Returns `true` if `self` contains another `&str`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert!("bananas".contains("nana"));
+    ///
+    /// assert!(!"bananas".contains("foobar"));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
+        core_str::StrExt::contains(&self[..], pat)
     }
 
-    #[test]
-    fn test_rev_iterator() {
-        let s = "ศไทย中华Việt Nam";
-        let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
-
-        let mut pos = 0;
-        let it = s.chars().rev();
-
-        for c in it {
-            assert_eq!(c, v[pos]);
-            pos += 1;
-        }
-        assert_eq!(pos, v.len());
+    /// Returns `true` if `self` contains a `char`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert!("hello".contains_char('e'));
+    ///
+    /// assert!(!"hello".contains_char('z'));
+    /// ```
+    #[unstable(feature = "collections")]
+    #[deprecated(since = "1.0.0", reason = "use `contains()` with a char")]
+    pub fn contains_char<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
+        core_str::StrExt::contains_char(&self[..], pat)
     }
 
-    #[test]
-    fn test_chars_decoding() {
-        let mut bytes = [0; 4];
-        for c in (0..0x110000).filter_map(|c| ::core::char::from_u32(c)) {
-            let len = c.encode_utf8(&mut bytes).unwrap_or(0);
-            let s = ::core::str::from_utf8(&bytes[..len]).unwrap();
-            if Some(c) != s.chars().next() {
-                panic!("character {:x}={} does not decode correctly", c as u32, c);
-            }
-        }
+    /// An iterator over the codepoints of `self`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v: Vec<char> = "abc åäö".chars().collect();
+    ///
+    /// assert_eq!(v, ['a', 'b', 'c', ' ', 'å', 'ä', 'ö']);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn chars(&self) -> Chars {
+        core_str::StrExt::chars(&self[..])
     }
 
-    #[test]
-    fn test_chars_rev_decoding() {
-        let mut bytes = [0; 4];
-        for c in (0..0x110000).filter_map(|c| ::core::char::from_u32(c)) {
-            let len = c.encode_utf8(&mut bytes).unwrap_or(0);
-            let s = ::core::str::from_utf8(&bytes[..len]).unwrap();
-            if Some(c) != s.chars().rev().next() {
-                panic!("character {:x}={} does not decode correctly", c as u32, c);
-            }
-        }
+    /// An iterator over the bytes of `self`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v: Vec<u8> = "bors".bytes().collect();
+    ///
+    /// assert_eq!(v, b"bors".to_vec());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn bytes(&self) -> Bytes {
+        core_str::StrExt::bytes(&self[..])
     }
 
-    #[test]
-    fn test_iterator_clone() {
-        let s = "ศไทย中华Việt Nam";
-        let mut it = s.chars();
-        it.next();
-        assert!(it.clone().zip(it).all(|(x,y)| x == y));
+    /// An iterator over the characters of `self` and their byte offsets.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v: Vec<(usize, char)> = "abc".char_indices().collect();
+    /// let b = vec![(0, 'a'), (1, 'b'), (2, 'c')];
+    ///
+    /// assert_eq!(v, b);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn char_indices(&self) -> CharIndices {
+        core_str::StrExt::char_indices(&self[..])
     }
 
-    #[test]
-    fn test_bytesator() {
-        let s = "ศไทย中华Việt Nam";
-        let v = [
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109
-        ];
-        let mut pos = 0;
-
-        for b in s.bytes() {
-            assert_eq!(b, v[pos]);
-            pos += 1;
-        }
+    /// An iterator over substrings of `self`, separated by characters
+    /// matched by a pattern.
+    ///
+    /// The pattern can be a simple `&str`, or a closure that determines
+    /// the split.
+    ///
+    /// # Examples
+    ///
+    /// Simple `&str` patterns:
+    ///
+    /// ```
+    /// let v: Vec<&str> = "Mary had a little lamb".split(' ').collect();
+    /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
+    ///
+    /// let v: Vec<&str> = "".split('X').collect();
+    /// assert_eq!(v, [""]);
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
+    /// let v: Vec<&str> = "abc1def2ghi".split(|c: char| c.is_numeric()).collect();
+    /// assert_eq!(v, ["abc", "def", "ghi"]);
+    ///
+    /// let v: Vec<&str> = "lionXXtigerXleopard".split('X').collect();
+    /// assert_eq!(v, ["lion", "", "tiger", "leopard"]);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
+        core_str::StrExt::split(&self[..], pat)
     }
 
-    #[test]
-    fn test_bytes_revator() {
-        let s = "ศไทย中华Việt Nam";
-        let v = [
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109
-        ];
-        let mut pos = v.len();
-
-        for b in s.bytes().rev() {
-            pos -= 1;
-            assert_eq!(b, v[pos]);
-        }
+    /// An iterator over substrings of `self`, separated by characters matched by a pattern,
+    /// restricted to splitting at most `count` times.
+    ///
+    /// The pattern can be a simple `&str`, or a closure that determines
+    /// the split.
+    ///
+    /// # Examples
+    ///
+    /// Simple `&str` patterns:
+    ///
+    /// ```
+    /// let v: Vec<&str> = "Mary had a little lambda".splitn(2, ' ').collect();
+    /// assert_eq!(v, ["Mary", "had", "a little lambda"]);
+    ///
+    /// let v: Vec<&str> = "lionXXtigerXleopard".splitn(2, 'X').collect();
+    /// assert_eq!(v, ["lion", "", "tigerXleopard"]);
+    ///
+    /// let v: Vec<&str> = "abcXdef".splitn(0, 'X').collect();
+    /// assert_eq!(v, ["abcXdef"]);
+    ///
+    /// let v: Vec<&str> = "".splitn(1, 'X').collect();
+    /// assert_eq!(v, [""]);
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
+    /// let v: Vec<&str> = "abc1def2ghi".splitn(1, |c: char| c.is_numeric()).collect();
+    /// assert_eq!(v, ["abc", "def2ghi"]);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P> {
+        core_str::StrExt::splitn(&self[..], count, pat)
     }
 
-    #[test]
-    fn test_char_indicesator() {
-        let s = "ศไทย中华Việt Nam";
-        let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
-        let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-
-        let mut pos = 0;
-        let it = s.char_indices();
-
-        for c in it {
-            assert_eq!(c, (p[pos], v[pos]));
-            pos += 1;
-        }
-        assert_eq!(pos, v.len());
-        assert_eq!(pos, p.len());
+    /// An iterator over substrings of `self`, separated by characters
+    /// matched by a pattern.
+    ///
+    /// Equivalent to `split`, except that the trailing substring is skipped if empty.
+    ///
+    /// The pattern can be a simple `&str`, or a closure that determines
+    /// the split.
+    ///
+    /// # Examples
+    ///
+    /// Simple `&str` patterns:
+    ///
+    /// ```
+    /// let v: Vec<&str> = "A.B.".split_terminator('.').collect();
+    /// assert_eq!(v, ["A", "B"]);
+    ///
+    /// let v: Vec<&str> = "A..B..".split_terminator('.').collect();
+    /// assert_eq!(v, ["A", "", "B", ""]);
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
+    /// let v: Vec<&str> = "abc1def2ghi3".split_terminator(|c: char| c.is_numeric()).collect();
+    /// assert_eq!(v, ["abc", "def", "ghi"]);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
+        core_str::StrExt::split_terminator(&self[..], pat)
     }
 
-    #[test]
-    fn test_char_indices_revator() {
-        let s = "ศไทย中华Việt Nam";
-        let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
-        let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
-
-        let mut pos = 0;
-        let it = s.char_indices().rev();
-
-        for c in it {
-            assert_eq!(c, (p[pos], v[pos]));
-            pos += 1;
-        }
-        assert_eq!(pos, v.len());
-        assert_eq!(pos, p.len());
+    /// An iterator over substrings of `self`, separated by characters matched by a pattern,
+    /// starting from the end of the string.
+    ///
+    /// Restricted to splitting at most `count` times.
+    ///
+    /// The pattern can be a simple `&str`, or a closure that determines the split.
+    ///
+    /// # Examples
+    ///
+    /// Simple `&str` patterns:
+    ///
+    /// ```
+    /// let v: Vec<&str> = "Mary had a little lamb".rsplitn(2, ' ').collect();
+    /// assert_eq!(v, ["lamb", "little", "Mary had a"]);
+    ///
+    /// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(2, 'X').collect();
+    /// assert_eq!(v, ["leopard", "tiger", "lionX"]);
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
+    /// let v: Vec<&str> = "abc1def2ghi".rsplitn(1, |c: char| c.is_numeric()).collect();
+    /// assert_eq!(v, ["ghi", "abc1def"]);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P> {
+        core_str::StrExt::rsplitn(&self[..], count, pat)
     }
 
-    #[test]
-    fn test_splitn_char_iterator() {
-        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
-        let split: Vec<&str> = data.splitn(3, ' ').collect();
-        assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
-
-        let split: Vec<&str> = data.splitn(3, |c: char| c == ' ').collect();
-        assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
-
-        // Unicode
-        let split: Vec<&str> = data.splitn(3, 'ä').collect();
-        assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
-
-        let split: Vec<&str> = data.splitn(3, |c: char| c == 'ä').collect();
-        assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
+    /// An iterator over the start and end indices of the disjoint matches of a `&str` within
+    /// `self`.
+    ///
+    /// That is, each returned value `(start, end)` satisfies `self.slice(start, end) == sep`. For
+    /// matches of `sep` within `self` that overlap, only the indices corresponding to the first
+    /// match are returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v: Vec<(usize, usize)> = "abcXXXabcYYYabc".match_indices("abc").collect();
+    /// assert_eq!(v, [(0,3), (6,9), (12,15)]);
+    ///
+    /// let v: Vec<(usize, usize)> = "1abcabc2".match_indices("abc").collect();
+    /// assert_eq!(v, [(1,4), (4,7)]);
+    ///
+    /// let v: Vec<(usize, usize)> = "ababa".match_indices("aba").collect();
+    /// assert_eq!(v, [(0, 3)]); // only the first `aba`
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "might have its iterator type changed")]
+    // NB: Right now MatchIndices yields `(usize, usize)`,
+    // but it would be more consistent and useful to return `(usize, &str)`
+    pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
+        core_str::StrExt::match_indices(&self[..], pat)
     }
 
-    #[test]
-    fn test_split_char_iterator_no_trailing() {
-        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
-        let split: Vec<&str> = data.split('\n').collect();
-        assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
-
-        let split: Vec<&str> = data.split_terminator('\n').collect();
-        assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
+    /// An iterator over the substrings of `self` separated by a `&str`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let v: Vec<&str> = "abcXXXabcYYYabc".split_str("abc").collect();
+    /// assert_eq!(v, ["", "XXX", "YYY", ""]);
+    ///
+    /// let v: Vec<&str> = "1abcabc2".split_str("abc").collect();
+    /// assert_eq!(v, ["1", "", "2"]);
+    /// ```
+    #[unstable(feature = "collections")]
+    #[deprecated(since = "1.0.0", reason = "use `split()` with a `&str`")]
+    #[allow(deprecated) /* for SplitStr */]
+    pub fn split_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitStr<'a, P> {
+        core_str::StrExt::split_str(&self[..], pat)
     }
 
-    #[test]
-    fn test_words() {
-        let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
-        let words: Vec<&str> = data.words().collect();
-        assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
+    /// An iterator over the lines of a string, separated by `\n`.
+    ///
+    /// This does not include the empty string after a trailing `\n`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let four_lines = "foo\nbar\n\nbaz";
+    /// let v: Vec<&str> = four_lines.lines().collect();
+    ///
+    /// assert_eq!(v, ["foo", "bar", "", "baz"]);
+    /// ```
+    ///
+    /// Leaving off the trailing character:
+    ///
+    /// ```
+    /// let four_lines = "foo\nbar\n\nbaz\n";
+    /// let v: Vec<&str> = four_lines.lines().collect();
+    ///
+    /// assert_eq!(v, ["foo", "bar", "", "baz"]);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn lines(&self) -> Lines {
+        core_str::StrExt::lines(&self[..])
     }
 
-    #[test]
-    fn test_nfd_chars() {
-        macro_rules! t {
-            ($input: expr, $expected: expr) => {
-                assert_eq!($input.nfd_chars().collect::<String>(), $expected);
-            }
-        }
-        t!("abc", "abc");
-        t!("\u{1e0b}\u{1c4}", "d\u{307}\u{1c4}");
-        t!("\u{2026}", "\u{2026}");
-        t!("\u{2126}", "\u{3a9}");
-        t!("\u{1e0b}\u{323}", "d\u{323}\u{307}");
-        t!("\u{1e0d}\u{307}", "d\u{323}\u{307}");
-        t!("a\u{301}", "a\u{301}");
-        t!("\u{301}a", "\u{301}a");
-        t!("\u{d4db}", "\u{1111}\u{1171}\u{11b6}");
-        t!("\u{ac1c}", "\u{1100}\u{1162}");
-    }
-
-    #[test]
-    fn test_nfkd_chars() {
-        macro_rules! t {
-            ($input: expr, $expected: expr) => {
-                assert_eq!($input.nfkd_chars().collect::<String>(), $expected);
-            }
-        }
-        t!("abc", "abc");
-        t!("\u{1e0b}\u{1c4}", "d\u{307}DZ\u{30c}");
-        t!("\u{2026}", "...");
-        t!("\u{2126}", "\u{3a9}");
-        t!("\u{1e0b}\u{323}", "d\u{323}\u{307}");
-        t!("\u{1e0d}\u{307}", "d\u{323}\u{307}");
-        t!("a\u{301}", "a\u{301}");
-        t!("\u{301}a", "\u{301}a");
-        t!("\u{d4db}", "\u{1111}\u{1171}\u{11b6}");
-        t!("\u{ac1c}", "\u{1100}\u{1162}");
-    }
-
-    #[test]
-    fn test_nfc_chars() {
-        macro_rules! t {
-            ($input: expr, $expected: expr) => {
-                assert_eq!($input.nfc_chars().collect::<String>(), $expected);
-            }
-        }
-        t!("abc", "abc");
-        t!("\u{1e0b}\u{1c4}", "\u{1e0b}\u{1c4}");
-        t!("\u{2026}", "\u{2026}");
-        t!("\u{2126}", "\u{3a9}");
-        t!("\u{1e0b}\u{323}", "\u{1e0d}\u{307}");
-        t!("\u{1e0d}\u{307}", "\u{1e0d}\u{307}");
-        t!("a\u{301}", "\u{e1}");
-        t!("\u{301}a", "\u{301}a");
-        t!("\u{d4db}", "\u{d4db}");
-        t!("\u{ac1c}", "\u{ac1c}");
-        t!("a\u{300}\u{305}\u{315}\u{5ae}b", "\u{e0}\u{5ae}\u{305}\u{315}b");
-    }
-
-    #[test]
-    fn test_nfkc_chars() {
-        macro_rules! t {
-            ($input: expr, $expected: expr) => {
-                assert_eq!($input.nfkc_chars().collect::<String>(), $expected);
-            }
-        }
-        t!("abc", "abc");
-        t!("\u{1e0b}\u{1c4}", "\u{1e0b}D\u{17d}");
-        t!("\u{2026}", "...");
-        t!("\u{2126}", "\u{3a9}");
-        t!("\u{1e0b}\u{323}", "\u{1e0d}\u{307}");
-        t!("\u{1e0d}\u{307}", "\u{1e0d}\u{307}");
-        t!("a\u{301}", "\u{e1}");
-        t!("\u{301}a", "\u{301}a");
-        t!("\u{d4db}", "\u{d4db}");
-        t!("\u{ac1c}", "\u{ac1c}");
-        t!("a\u{300}\u{305}\u{315}\u{5ae}b", "\u{e0}\u{5ae}\u{305}\u{315}b");
-    }
-
-    #[test]
-    fn test_lines() {
-        let data = "\nMäry häd ä little lämb\n\nLittle lämb\n";
-        let lines: Vec<&str> = data.lines().collect();
-        assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
-
-        let data = "\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
-        let lines: Vec<&str> = data.lines().collect();
-        assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
-    }
-
-    #[test]
-    fn test_graphemes() {
-        use core::iter::order;
-        // official Unicode test data
-        // from http://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.txt
-        let test_same: [(_, &[_]); 325] = [
-            ("\u{20}\u{20}", &["\u{20}", "\u{20}"]),
-            ("\u{20}\u{308}\u{20}", &["\u{20}\u{308}", "\u{20}"]),
-            ("\u{20}\u{D}", &["\u{20}", "\u{D}"]),
-            ("\u{20}\u{308}\u{D}", &["\u{20}\u{308}", "\u{D}"]),
-            ("\u{20}\u{A}", &["\u{20}", "\u{A}"]),
-            ("\u{20}\u{308}\u{A}", &["\u{20}\u{308}", "\u{A}"]),
-            ("\u{20}\u{1}", &["\u{20}", "\u{1}"]),
-            ("\u{20}\u{308}\u{1}", &["\u{20}\u{308}", "\u{1}"]),
-            ("\u{20}\u{300}", &["\u{20}\u{300}"]),
-            ("\u{20}\u{308}\u{300}", &["\u{20}\u{308}\u{300}"]),
-            ("\u{20}\u{1100}", &["\u{20}", "\u{1100}"]),
-            ("\u{20}\u{308}\u{1100}", &["\u{20}\u{308}", "\u{1100}"]),
-            ("\u{20}\u{1160}", &["\u{20}", "\u{1160}"]),
-            ("\u{20}\u{308}\u{1160}", &["\u{20}\u{308}", "\u{1160}"]),
-            ("\u{20}\u{11A8}", &["\u{20}", "\u{11A8}"]),
-            ("\u{20}\u{308}\u{11A8}", &["\u{20}\u{308}", "\u{11A8}"]),
-            ("\u{20}\u{AC00}", &["\u{20}", "\u{AC00}"]),
-            ("\u{20}\u{308}\u{AC00}", &["\u{20}\u{308}", "\u{AC00}"]),
-            ("\u{20}\u{AC01}", &["\u{20}", "\u{AC01}"]),
-            ("\u{20}\u{308}\u{AC01}", &["\u{20}\u{308}", "\u{AC01}"]),
-            ("\u{20}\u{1F1E6}", &["\u{20}", "\u{1F1E6}"]),
-            ("\u{20}\u{308}\u{1F1E6}", &["\u{20}\u{308}", "\u{1F1E6}"]),
-            ("\u{20}\u{378}", &["\u{20}", "\u{378}"]),
-            ("\u{20}\u{308}\u{378}", &["\u{20}\u{308}", "\u{378}"]),
-            ("\u{D}\u{20}", &["\u{D}", "\u{20}"]),
-            ("\u{D}\u{308}\u{20}", &["\u{D}", "\u{308}", "\u{20}"]),
-            ("\u{D}\u{D}", &["\u{D}", "\u{D}"]),
-            ("\u{D}\u{308}\u{D}", &["\u{D}", "\u{308}", "\u{D}"]),
-            ("\u{D}\u{A}", &["\u{D}\u{A}"]),
-            ("\u{D}\u{308}\u{A}", &["\u{D}", "\u{308}", "\u{A}"]),
-            ("\u{D}\u{1}", &["\u{D}", "\u{1}"]),
-            ("\u{D}\u{308}\u{1}", &["\u{D}", "\u{308}", "\u{1}"]),
-            ("\u{D}\u{300}", &["\u{D}", "\u{300}"]),
-            ("\u{D}\u{308}\u{300}", &["\u{D}", "\u{308}\u{300}"]),
-            ("\u{D}\u{903}", &["\u{D}", "\u{903}"]),
-            ("\u{D}\u{1100}", &["\u{D}", "\u{1100}"]),
-            ("\u{D}\u{308}\u{1100}", &["\u{D}", "\u{308}", "\u{1100}"]),
-            ("\u{D}\u{1160}", &["\u{D}", "\u{1160}"]),
-            ("\u{D}\u{308}\u{1160}", &["\u{D}", "\u{308}", "\u{1160}"]),
-            ("\u{D}\u{11A8}", &["\u{D}", "\u{11A8}"]),
-            ("\u{D}\u{308}\u{11A8}", &["\u{D}", "\u{308}", "\u{11A8}"]),
-            ("\u{D}\u{AC00}", &["\u{D}", "\u{AC00}"]),
-            ("\u{D}\u{308}\u{AC00}", &["\u{D}", "\u{308}", "\u{AC00}"]),
-            ("\u{D}\u{AC01}", &["\u{D}", "\u{AC01}"]),
-            ("\u{D}\u{308}\u{AC01}", &["\u{D}", "\u{308}", "\u{AC01}"]),
-            ("\u{D}\u{1F1E6}", &["\u{D}", "\u{1F1E6}"]),
-            ("\u{D}\u{308}\u{1F1E6}", &["\u{D}", "\u{308}", "\u{1F1E6}"]),
-            ("\u{D}\u{378}", &["\u{D}", "\u{378}"]),
-            ("\u{D}\u{308}\u{378}", &["\u{D}", "\u{308}", "\u{378}"]),
-            ("\u{A}\u{20}", &["\u{A}", "\u{20}"]),
-            ("\u{A}\u{308}\u{20}", &["\u{A}", "\u{308}", "\u{20}"]),
-            ("\u{A}\u{D}", &["\u{A}", "\u{D}"]),
-            ("\u{A}\u{308}\u{D}", &["\u{A}", "\u{308}", "\u{D}"]),
-            ("\u{A}\u{A}", &["\u{A}", "\u{A}"]),
-            ("\u{A}\u{308}\u{A}", &["\u{A}", "\u{308}", "\u{A}"]),
-            ("\u{A}\u{1}", &["\u{A}", "\u{1}"]),
-            ("\u{A}\u{308}\u{1}", &["\u{A}", "\u{308}", "\u{1}"]),
-            ("\u{A}\u{300}", &["\u{A}", "\u{300}"]),
-            ("\u{A}\u{308}\u{300}", &["\u{A}", "\u{308}\u{300}"]),
-            ("\u{A}\u{903}", &["\u{A}", "\u{903}"]),
-            ("\u{A}\u{1100}", &["\u{A}", "\u{1100}"]),
-            ("\u{A}\u{308}\u{1100}", &["\u{A}", "\u{308}", "\u{1100}"]),
-            ("\u{A}\u{1160}", &["\u{A}", "\u{1160}"]),
-            ("\u{A}\u{308}\u{1160}", &["\u{A}", "\u{308}", "\u{1160}"]),
-            ("\u{A}\u{11A8}", &["\u{A}", "\u{11A8}"]),
-            ("\u{A}\u{308}\u{11A8}", &["\u{A}", "\u{308}", "\u{11A8}"]),
-            ("\u{A}\u{AC00}", &["\u{A}", "\u{AC00}"]),
-            ("\u{A}\u{308}\u{AC00}", &["\u{A}", "\u{308}", "\u{AC00}"]),
-            ("\u{A}\u{AC01}", &["\u{A}", "\u{AC01}"]),
-            ("\u{A}\u{308}\u{AC01}", &["\u{A}", "\u{308}", "\u{AC01}"]),
-            ("\u{A}\u{1F1E6}", &["\u{A}", "\u{1F1E6}"]),
-            ("\u{A}\u{308}\u{1F1E6}", &["\u{A}", "\u{308}", "\u{1F1E6}"]),
-            ("\u{A}\u{378}", &["\u{A}", "\u{378}"]),
-            ("\u{A}\u{308}\u{378}", &["\u{A}", "\u{308}", "\u{378}"]),
-            ("\u{1}\u{20}", &["\u{1}", "\u{20}"]),
-            ("\u{1}\u{308}\u{20}", &["\u{1}", "\u{308}", "\u{20}"]),
-            ("\u{1}\u{D}", &["\u{1}", "\u{D}"]),
-            ("\u{1}\u{308}\u{D}", &["\u{1}", "\u{308}", "\u{D}"]),
-            ("\u{1}\u{A}", &["\u{1}", "\u{A}"]),
-            ("\u{1}\u{308}\u{A}", &["\u{1}", "\u{308}", "\u{A}"]),
-            ("\u{1}\u{1}", &["\u{1}", "\u{1}"]),
-            ("\u{1}\u{308}\u{1}", &["\u{1}", "\u{308}", "\u{1}"]),
-            ("\u{1}\u{300}", &["\u{1}", "\u{300}"]),
-            ("\u{1}\u{308}\u{300}", &["\u{1}", "\u{308}\u{300}"]),
-            ("\u{1}\u{903}", &["\u{1}", "\u{903}"]),
-            ("\u{1}\u{1100}", &["\u{1}", "\u{1100}"]),
-            ("\u{1}\u{308}\u{1100}", &["\u{1}", "\u{308}", "\u{1100}"]),
-            ("\u{1}\u{1160}", &["\u{1}", "\u{1160}"]),
-            ("\u{1}\u{308}\u{1160}", &["\u{1}", "\u{308}", "\u{1160}"]),
-            ("\u{1}\u{11A8}", &["\u{1}", "\u{11A8}"]),
-            ("\u{1}\u{308}\u{11A8}", &["\u{1}", "\u{308}", "\u{11A8}"]),
-            ("\u{1}\u{AC00}", &["\u{1}", "\u{AC00}"]),
-            ("\u{1}\u{308}\u{AC00}", &["\u{1}", "\u{308}", "\u{AC00}"]),
-            ("\u{1}\u{AC01}", &["\u{1}", "\u{AC01}"]),
-            ("\u{1}\u{308}\u{AC01}", &["\u{1}", "\u{308}", "\u{AC01}"]),
-            ("\u{1}\u{1F1E6}", &["\u{1}", "\u{1F1E6}"]),
-            ("\u{1}\u{308}\u{1F1E6}", &["\u{1}", "\u{308}", "\u{1F1E6}"]),
-            ("\u{1}\u{378}", &["\u{1}", "\u{378}"]),
-            ("\u{1}\u{308}\u{378}", &["\u{1}", "\u{308}", "\u{378}"]),
-            ("\u{300}\u{20}", &["\u{300}", "\u{20}"]),
-            ("\u{300}\u{308}\u{20}", &["\u{300}\u{308}", "\u{20}"]),
-            ("\u{300}\u{D}", &["\u{300}", "\u{D}"]),
-            ("\u{300}\u{308}\u{D}", &["\u{300}\u{308}", "\u{D}"]),
-            ("\u{300}\u{A}", &["\u{300}", "\u{A}"]),
-            ("\u{300}\u{308}\u{A}", &["\u{300}\u{308}", "\u{A}"]),
-            ("\u{300}\u{1}", &["\u{300}", "\u{1}"]),
-            ("\u{300}\u{308}\u{1}", &["\u{300}\u{308}", "\u{1}"]),
-            ("\u{300}\u{300}", &["\u{300}\u{300}"]),
-            ("\u{300}\u{308}\u{300}", &["\u{300}\u{308}\u{300}"]),
-            ("\u{300}\u{1100}", &["\u{300}", "\u{1100}"]),
-            ("\u{300}\u{308}\u{1100}", &["\u{300}\u{308}", "\u{1100}"]),
-            ("\u{300}\u{1160}", &["\u{300}", "\u{1160}"]),
-            ("\u{300}\u{308}\u{1160}", &["\u{300}\u{308}", "\u{1160}"]),
-            ("\u{300}\u{11A8}", &["\u{300}", "\u{11A8}"]),
-            ("\u{300}\u{308}\u{11A8}", &["\u{300}\u{308}", "\u{11A8}"]),
-            ("\u{300}\u{AC00}", &["\u{300}", "\u{AC00}"]),
-            ("\u{300}\u{308}\u{AC00}", &["\u{300}\u{308}", "\u{AC00}"]),
-            ("\u{300}\u{AC01}", &["\u{300}", "\u{AC01}"]),
-            ("\u{300}\u{308}\u{AC01}", &["\u{300}\u{308}", "\u{AC01}"]),
-            ("\u{300}\u{1F1E6}", &["\u{300}", "\u{1F1E6}"]),
-            ("\u{300}\u{308}\u{1F1E6}", &["\u{300}\u{308}", "\u{1F1E6}"]),
-            ("\u{300}\u{378}", &["\u{300}", "\u{378}"]),
-            ("\u{300}\u{308}\u{378}", &["\u{300}\u{308}", "\u{378}"]),
-            ("\u{903}\u{20}", &["\u{903}", "\u{20}"]),
-            ("\u{903}\u{308}\u{20}", &["\u{903}\u{308}", "\u{20}"]),
-            ("\u{903}\u{D}", &["\u{903}", "\u{D}"]),
-            ("\u{903}\u{308}\u{D}", &["\u{903}\u{308}", "\u{D}"]),
-            ("\u{903}\u{A}", &["\u{903}", "\u{A}"]),
-            ("\u{903}\u{308}\u{A}", &["\u{903}\u{308}", "\u{A}"]),
-            ("\u{903}\u{1}", &["\u{903}", "\u{1}"]),
-            ("\u{903}\u{308}\u{1}", &["\u{903}\u{308}", "\u{1}"]),
-            ("\u{903}\u{300}", &["\u{903}\u{300}"]),
-            ("\u{903}\u{308}\u{300}", &["\u{903}\u{308}\u{300}"]),
-            ("\u{903}\u{1100}", &["\u{903}", "\u{1100}"]),
-            ("\u{903}\u{308}\u{1100}", &["\u{903}\u{308}", "\u{1100}"]),
-            ("\u{903}\u{1160}", &["\u{903}", "\u{1160}"]),
-            ("\u{903}\u{308}\u{1160}", &["\u{903}\u{308}", "\u{1160}"]),
-            ("\u{903}\u{11A8}", &["\u{903}", "\u{11A8}"]),
-            ("\u{903}\u{308}\u{11A8}", &["\u{903}\u{308}", "\u{11A8}"]),
-            ("\u{903}\u{AC00}", &["\u{903}", "\u{AC00}"]),
-            ("\u{903}\u{308}\u{AC00}", &["\u{903}\u{308}", "\u{AC00}"]),
-            ("\u{903}\u{AC01}", &["\u{903}", "\u{AC01}"]),
-            ("\u{903}\u{308}\u{AC01}", &["\u{903}\u{308}", "\u{AC01}"]),
-            ("\u{903}\u{1F1E6}", &["\u{903}", "\u{1F1E6}"]),
-            ("\u{903}\u{308}\u{1F1E6}", &["\u{903}\u{308}", "\u{1F1E6}"]),
-            ("\u{903}\u{378}", &["\u{903}", "\u{378}"]),
-            ("\u{903}\u{308}\u{378}", &["\u{903}\u{308}", "\u{378}"]),
-            ("\u{1100}\u{20}", &["\u{1100}", "\u{20}"]),
-            ("\u{1100}\u{308}\u{20}", &["\u{1100}\u{308}", "\u{20}"]),
-            ("\u{1100}\u{D}", &["\u{1100}", "\u{D}"]),
-            ("\u{1100}\u{308}\u{D}", &["\u{1100}\u{308}", "\u{D}"]),
-            ("\u{1100}\u{A}", &["\u{1100}", "\u{A}"]),
-            ("\u{1100}\u{308}\u{A}", &["\u{1100}\u{308}", "\u{A}"]),
-            ("\u{1100}\u{1}", &["\u{1100}", "\u{1}"]),
-            ("\u{1100}\u{308}\u{1}", &["\u{1100}\u{308}", "\u{1}"]),
-            ("\u{1100}\u{300}", &["\u{1100}\u{300}"]),
-            ("\u{1100}\u{308}\u{300}", &["\u{1100}\u{308}\u{300}"]),
-            ("\u{1100}\u{1100}", &["\u{1100}\u{1100}"]),
-            ("\u{1100}\u{308}\u{1100}", &["\u{1100}\u{308}", "\u{1100}"]),
-            ("\u{1100}\u{1160}", &["\u{1100}\u{1160}"]),
-            ("\u{1100}\u{308}\u{1160}", &["\u{1100}\u{308}", "\u{1160}"]),
-            ("\u{1100}\u{11A8}", &["\u{1100}", "\u{11A8}"]),
-            ("\u{1100}\u{308}\u{11A8}", &["\u{1100}\u{308}", "\u{11A8}"]),
-            ("\u{1100}\u{AC00}", &["\u{1100}\u{AC00}"]),
-            ("\u{1100}\u{308}\u{AC00}", &["\u{1100}\u{308}", "\u{AC00}"]),
-            ("\u{1100}\u{AC01}", &["\u{1100}\u{AC01}"]),
-            ("\u{1100}\u{308}\u{AC01}", &["\u{1100}\u{308}", "\u{AC01}"]),
-            ("\u{1100}\u{1F1E6}", &["\u{1100}", "\u{1F1E6}"]),
-            ("\u{1100}\u{308}\u{1F1E6}", &["\u{1100}\u{308}", "\u{1F1E6}"]),
-            ("\u{1100}\u{378}", &["\u{1100}", "\u{378}"]),
-            ("\u{1100}\u{308}\u{378}", &["\u{1100}\u{308}", "\u{378}"]),
-            ("\u{1160}\u{20}", &["\u{1160}", "\u{20}"]),
-            ("\u{1160}\u{308}\u{20}", &["\u{1160}\u{308}", "\u{20}"]),
-            ("\u{1160}\u{D}", &["\u{1160}", "\u{D}"]),
-            ("\u{1160}\u{308}\u{D}", &["\u{1160}\u{308}", "\u{D}"]),
-            ("\u{1160}\u{A}", &["\u{1160}", "\u{A}"]),
-            ("\u{1160}\u{308}\u{A}", &["\u{1160}\u{308}", "\u{A}"]),
-            ("\u{1160}\u{1}", &["\u{1160}", "\u{1}"]),
-            ("\u{1160}\u{308}\u{1}", &["\u{1160}\u{308}", "\u{1}"]),
-            ("\u{1160}\u{300}", &["\u{1160}\u{300}"]),
-            ("\u{1160}\u{308}\u{300}", &["\u{1160}\u{308}\u{300}"]),
-            ("\u{1160}\u{1100}", &["\u{1160}", "\u{1100}"]),
-            ("\u{1160}\u{308}\u{1100}", &["\u{1160}\u{308}", "\u{1100}"]),
-            ("\u{1160}\u{1160}", &["\u{1160}\u{1160}"]),
-            ("\u{1160}\u{308}\u{1160}", &["\u{1160}\u{308}", "\u{1160}"]),
-            ("\u{1160}\u{11A8}", &["\u{1160}\u{11A8}"]),
-            ("\u{1160}\u{308}\u{11A8}", &["\u{1160}\u{308}", "\u{11A8}"]),
-            ("\u{1160}\u{AC00}", &["\u{1160}", "\u{AC00}"]),
-            ("\u{1160}\u{308}\u{AC00}", &["\u{1160}\u{308}", "\u{AC00}"]),
-            ("\u{1160}\u{AC01}", &["\u{1160}", "\u{AC01}"]),
-            ("\u{1160}\u{308}\u{AC01}", &["\u{1160}\u{308}", "\u{AC01}"]),
-            ("\u{1160}\u{1F1E6}", &["\u{1160}", "\u{1F1E6}"]),
-            ("\u{1160}\u{308}\u{1F1E6}", &["\u{1160}\u{308}", "\u{1F1E6}"]),
-            ("\u{1160}\u{378}", &["\u{1160}", "\u{378}"]),
-            ("\u{1160}\u{308}\u{378}", &["\u{1160}\u{308}", "\u{378}"]),
-            ("\u{11A8}\u{20}", &["\u{11A8}", "\u{20}"]),
-            ("\u{11A8}\u{308}\u{20}", &["\u{11A8}\u{308}", "\u{20}"]),
-            ("\u{11A8}\u{D}", &["\u{11A8}", "\u{D}"]),
-            ("\u{11A8}\u{308}\u{D}", &["\u{11A8}\u{308}", "\u{D}"]),
-            ("\u{11A8}\u{A}", &["\u{11A8}", "\u{A}"]),
-            ("\u{11A8}\u{308}\u{A}", &["\u{11A8}\u{308}", "\u{A}"]),
-            ("\u{11A8}\u{1}", &["\u{11A8}", "\u{1}"]),
-            ("\u{11A8}\u{308}\u{1}", &["\u{11A8}\u{308}", "\u{1}"]),
-            ("\u{11A8}\u{300}", &["\u{11A8}\u{300}"]),
-            ("\u{11A8}\u{308}\u{300}", &["\u{11A8}\u{308}\u{300}"]),
-            ("\u{11A8}\u{1100}", &["\u{11A8}", "\u{1100}"]),
-            ("\u{11A8}\u{308}\u{1100}", &["\u{11A8}\u{308}", "\u{1100}"]),
-            ("\u{11A8}\u{1160}", &["\u{11A8}", "\u{1160}"]),
-            ("\u{11A8}\u{308}\u{1160}", &["\u{11A8}\u{308}", "\u{1160}"]),
-            ("\u{11A8}\u{11A8}", &["\u{11A8}\u{11A8}"]),
-            ("\u{11A8}\u{308}\u{11A8}", &["\u{11A8}\u{308}", "\u{11A8}"]),
-            ("\u{11A8}\u{AC00}", &["\u{11A8}", "\u{AC00}"]),
-            ("\u{11A8}\u{308}\u{AC00}", &["\u{11A8}\u{308}", "\u{AC00}"]),
-            ("\u{11A8}\u{AC01}", &["\u{11A8}", "\u{AC01}"]),
-            ("\u{11A8}\u{308}\u{AC01}", &["\u{11A8}\u{308}", "\u{AC01}"]),
-            ("\u{11A8}\u{1F1E6}", &["\u{11A8}", "\u{1F1E6}"]),
-            ("\u{11A8}\u{308}\u{1F1E6}", &["\u{11A8}\u{308}", "\u{1F1E6}"]),
-            ("\u{11A8}\u{378}", &["\u{11A8}", "\u{378}"]),
-            ("\u{11A8}\u{308}\u{378}", &["\u{11A8}\u{308}", "\u{378}"]),
-            ("\u{AC00}\u{20}", &["\u{AC00}", "\u{20}"]),
-            ("\u{AC00}\u{308}\u{20}", &["\u{AC00}\u{308}", "\u{20}"]),
-            ("\u{AC00}\u{D}", &["\u{AC00}", "\u{D}"]),
-            ("\u{AC00}\u{308}\u{D}", &["\u{AC00}\u{308}", "\u{D}"]),
-            ("\u{AC00}\u{A}", &["\u{AC00}", "\u{A}"]),
-            ("\u{AC00}\u{308}\u{A}", &["\u{AC00}\u{308}", "\u{A}"]),
-            ("\u{AC00}\u{1}", &["\u{AC00}", "\u{1}"]),
-            ("\u{AC00}\u{308}\u{1}", &["\u{AC00}\u{308}", "\u{1}"]),
-            ("\u{AC00}\u{300}", &["\u{AC00}\u{300}"]),
-            ("\u{AC00}\u{308}\u{300}", &["\u{AC00}\u{308}\u{300}"]),
-            ("\u{AC00}\u{1100}", &["\u{AC00}", "\u{1100}"]),
-            ("\u{AC00}\u{308}\u{1100}", &["\u{AC00}\u{308}", "\u{1100}"]),
-            ("\u{AC00}\u{1160}", &["\u{AC00}\u{1160}"]),
-            ("\u{AC00}\u{308}\u{1160}", &["\u{AC00}\u{308}", "\u{1160}"]),
-            ("\u{AC00}\u{11A8}", &["\u{AC00}\u{11A8}"]),
-            ("\u{AC00}\u{308}\u{11A8}", &["\u{AC00}\u{308}", "\u{11A8}"]),
-            ("\u{AC00}\u{AC00}", &["\u{AC00}", "\u{AC00}"]),
-            ("\u{AC00}\u{308}\u{AC00}", &["\u{AC00}\u{308}", "\u{AC00}"]),
-            ("\u{AC00}\u{AC01}", &["\u{AC00}", "\u{AC01}"]),
-            ("\u{AC00}\u{308}\u{AC01}", &["\u{AC00}\u{308}", "\u{AC01}"]),
-            ("\u{AC00}\u{1F1E6}", &["\u{AC00}", "\u{1F1E6}"]),
-            ("\u{AC00}\u{308}\u{1F1E6}", &["\u{AC00}\u{308}", "\u{1F1E6}"]),
-            ("\u{AC00}\u{378}", &["\u{AC00}", "\u{378}"]),
-            ("\u{AC00}\u{308}\u{378}", &["\u{AC00}\u{308}", "\u{378}"]),
-            ("\u{AC01}\u{20}", &["\u{AC01}", "\u{20}"]),
-            ("\u{AC01}\u{308}\u{20}", &["\u{AC01}\u{308}", "\u{20}"]),
-            ("\u{AC01}\u{D}", &["\u{AC01}", "\u{D}"]),
-            ("\u{AC01}\u{308}\u{D}", &["\u{AC01}\u{308}", "\u{D}"]),
-            ("\u{AC01}\u{A}", &["\u{AC01}", "\u{A}"]),
-            ("\u{AC01}\u{308}\u{A}", &["\u{AC01}\u{308}", "\u{A}"]),
-            ("\u{AC01}\u{1}", &["\u{AC01}", "\u{1}"]),
-            ("\u{AC01}\u{308}\u{1}", &["\u{AC01}\u{308}", "\u{1}"]),
-            ("\u{AC01}\u{300}", &["\u{AC01}\u{300}"]),
-            ("\u{AC01}\u{308}\u{300}", &["\u{AC01}\u{308}\u{300}"]),
-            ("\u{AC01}\u{1100}", &["\u{AC01}", "\u{1100}"]),
-            ("\u{AC01}\u{308}\u{1100}", &["\u{AC01}\u{308}", "\u{1100}"]),
-            ("\u{AC01}\u{1160}", &["\u{AC01}", "\u{1160}"]),
-            ("\u{AC01}\u{308}\u{1160}", &["\u{AC01}\u{308}", "\u{1160}"]),
-            ("\u{AC01}\u{11A8}", &["\u{AC01}\u{11A8}"]),
-            ("\u{AC01}\u{308}\u{11A8}", &["\u{AC01}\u{308}", "\u{11A8}"]),
-            ("\u{AC01}\u{AC00}", &["\u{AC01}", "\u{AC00}"]),
-            ("\u{AC01}\u{308}\u{AC00}", &["\u{AC01}\u{308}", "\u{AC00}"]),
-            ("\u{AC01}\u{AC01}", &["\u{AC01}", "\u{AC01}"]),
-            ("\u{AC01}\u{308}\u{AC01}", &["\u{AC01}\u{308}", "\u{AC01}"]),
-            ("\u{AC01}\u{1F1E6}", &["\u{AC01}", "\u{1F1E6}"]),
-            ("\u{AC01}\u{308}\u{1F1E6}", &["\u{AC01}\u{308}", "\u{1F1E6}"]),
-            ("\u{AC01}\u{378}", &["\u{AC01}", "\u{378}"]),
-            ("\u{AC01}\u{308}\u{378}", &["\u{AC01}\u{308}", "\u{378}"]),
-            ("\u{1F1E6}\u{20}", &["\u{1F1E6}", "\u{20}"]),
-            ("\u{1F1E6}\u{308}\u{20}", &["\u{1F1E6}\u{308}", "\u{20}"]),
-            ("\u{1F1E6}\u{D}", &["\u{1F1E6}", "\u{D}"]),
-            ("\u{1F1E6}\u{308}\u{D}", &["\u{1F1E6}\u{308}", "\u{D}"]),
-            ("\u{1F1E6}\u{A}", &["\u{1F1E6}", "\u{A}"]),
-            ("\u{1F1E6}\u{308}\u{A}", &["\u{1F1E6}\u{308}", "\u{A}"]),
-            ("\u{1F1E6}\u{1}", &["\u{1F1E6}", "\u{1}"]),
-            ("\u{1F1E6}\u{308}\u{1}", &["\u{1F1E6}\u{308}", "\u{1}"]),
-            ("\u{1F1E6}\u{300}", &["\u{1F1E6}\u{300}"]),
-            ("\u{1F1E6}\u{308}\u{300}", &["\u{1F1E6}\u{308}\u{300}"]),
-            ("\u{1F1E6}\u{1100}", &["\u{1F1E6}", "\u{1100}"]),
-            ("\u{1F1E6}\u{308}\u{1100}", &["\u{1F1E6}\u{308}", "\u{1100}"]),
-            ("\u{1F1E6}\u{1160}", &["\u{1F1E6}", "\u{1160}"]),
-            ("\u{1F1E6}\u{308}\u{1160}", &["\u{1F1E6}\u{308}", "\u{1160}"]),
-            ("\u{1F1E6}\u{11A8}", &["\u{1F1E6}", "\u{11A8}"]),
-            ("\u{1F1E6}\u{308}\u{11A8}", &["\u{1F1E6}\u{308}", "\u{11A8}"]),
-            ("\u{1F1E6}\u{AC00}", &["\u{1F1E6}", "\u{AC00}"]),
-            ("\u{1F1E6}\u{308}\u{AC00}", &["\u{1F1E6}\u{308}", "\u{AC00}"]),
-            ("\u{1F1E6}\u{AC01}", &["\u{1F1E6}", "\u{AC01}"]),
-            ("\u{1F1E6}\u{308}\u{AC01}", &["\u{1F1E6}\u{308}", "\u{AC01}"]),
-            ("\u{1F1E6}\u{1F1E6}", &["\u{1F1E6}\u{1F1E6}"]),
-            ("\u{1F1E6}\u{308}\u{1F1E6}", &["\u{1F1E6}\u{308}", "\u{1F1E6}"]),
-            ("\u{1F1E6}\u{378}", &["\u{1F1E6}", "\u{378}"]),
-            ("\u{1F1E6}\u{308}\u{378}", &["\u{1F1E6}\u{308}", "\u{378}"]),
-            ("\u{378}\u{20}", &["\u{378}", "\u{20}"]),
-            ("\u{378}\u{308}\u{20}", &["\u{378}\u{308}", "\u{20}"]),
-            ("\u{378}\u{D}", &["\u{378}", "\u{D}"]),
-            ("\u{378}\u{308}\u{D}", &["\u{378}\u{308}", "\u{D}"]),
-            ("\u{378}\u{A}", &["\u{378}", "\u{A}"]),
-            ("\u{378}\u{308}\u{A}", &["\u{378}\u{308}", "\u{A}"]),
-            ("\u{378}\u{1}", &["\u{378}", "\u{1}"]),
-            ("\u{378}\u{308}\u{1}", &["\u{378}\u{308}", "\u{1}"]),
-            ("\u{378}\u{300}", &["\u{378}\u{300}"]),
-            ("\u{378}\u{308}\u{300}", &["\u{378}\u{308}\u{300}"]),
-            ("\u{378}\u{1100}", &["\u{378}", "\u{1100}"]),
-            ("\u{378}\u{308}\u{1100}", &["\u{378}\u{308}", "\u{1100}"]),
-            ("\u{378}\u{1160}", &["\u{378}", "\u{1160}"]),
-            ("\u{378}\u{308}\u{1160}", &["\u{378}\u{308}", "\u{1160}"]),
-            ("\u{378}\u{11A8}", &["\u{378}", "\u{11A8}"]),
-            ("\u{378}\u{308}\u{11A8}", &["\u{378}\u{308}", "\u{11A8}"]),
-            ("\u{378}\u{AC00}", &["\u{378}", "\u{AC00}"]),
-            ("\u{378}\u{308}\u{AC00}", &["\u{378}\u{308}", "\u{AC00}"]),
-            ("\u{378}\u{AC01}", &["\u{378}", "\u{AC01}"]),
-            ("\u{378}\u{308}\u{AC01}", &["\u{378}\u{308}", "\u{AC01}"]),
-            ("\u{378}\u{1F1E6}", &["\u{378}", "\u{1F1E6}"]),
-            ("\u{378}\u{308}\u{1F1E6}", &["\u{378}\u{308}", "\u{1F1E6}"]),
-            ("\u{378}\u{378}", &["\u{378}", "\u{378}"]),
-            ("\u{378}\u{308}\u{378}", &["\u{378}\u{308}", "\u{378}"]),
-            ("\u{61}\u{1F1E6}\u{62}", &["\u{61}", "\u{1F1E6}", "\u{62}"]),
-            ("\u{1F1F7}\u{1F1FA}", &["\u{1F1F7}\u{1F1FA}"]),
-            ("\u{1F1F7}\u{1F1FA}\u{1F1F8}", &["\u{1F1F7}\u{1F1FA}\u{1F1F8}"]),
-            ("\u{1F1F7}\u{1F1FA}\u{1F1F8}\u{1F1EA}",
-            &["\u{1F1F7}\u{1F1FA}\u{1F1F8}\u{1F1EA}"]),
-            ("\u{1F1F7}\u{1F1FA}\u{200B}\u{1F1F8}\u{1F1EA}",
-             &["\u{1F1F7}\u{1F1FA}", "\u{200B}", "\u{1F1F8}\u{1F1EA}"]),
-            ("\u{1F1E6}\u{1F1E7}\u{1F1E8}", &["\u{1F1E6}\u{1F1E7}\u{1F1E8}"]),
-            ("\u{1F1E6}\u{200D}\u{1F1E7}\u{1F1E8}", &["\u{1F1E6}\u{200D}",
-             "\u{1F1E7}\u{1F1E8}"]),
-            ("\u{1F1E6}\u{1F1E7}\u{200D}\u{1F1E8}",
-             &["\u{1F1E6}\u{1F1E7}\u{200D}", "\u{1F1E8}"]),
-            ("\u{20}\u{200D}\u{646}", &["\u{20}\u{200D}", "\u{646}"]),
-            ("\u{646}\u{200D}\u{20}", &["\u{646}\u{200D}", "\u{20}"]),
-        ];
-
-        let test_diff: [(_, &[_], &[_]); 23] = [
-            ("\u{20}\u{903}", &["\u{20}\u{903}"], &["\u{20}", "\u{903}"]), ("\u{20}\u{308}\u{903}",
-            &["\u{20}\u{308}\u{903}"], &["\u{20}\u{308}", "\u{903}"]), ("\u{D}\u{308}\u{903}",
-            &["\u{D}", "\u{308}\u{903}"], &["\u{D}", "\u{308}", "\u{903}"]), ("\u{A}\u{308}\u{903}",
-            &["\u{A}", "\u{308}\u{903}"], &["\u{A}", "\u{308}", "\u{903}"]), ("\u{1}\u{308}\u{903}",
-            &["\u{1}", "\u{308}\u{903}"], &["\u{1}", "\u{308}", "\u{903}"]), ("\u{300}\u{903}",
-            &["\u{300}\u{903}"], &["\u{300}", "\u{903}"]), ("\u{300}\u{308}\u{903}",
-            &["\u{300}\u{308}\u{903}"], &["\u{300}\u{308}", "\u{903}"]), ("\u{903}\u{903}",
-            &["\u{903}\u{903}"], &["\u{903}", "\u{903}"]), ("\u{903}\u{308}\u{903}",
-            &["\u{903}\u{308}\u{903}"], &["\u{903}\u{308}", "\u{903}"]), ("\u{1100}\u{903}",
-            &["\u{1100}\u{903}"], &["\u{1100}", "\u{903}"]), ("\u{1100}\u{308}\u{903}",
-            &["\u{1100}\u{308}\u{903}"], &["\u{1100}\u{308}", "\u{903}"]), ("\u{1160}\u{903}",
-            &["\u{1160}\u{903}"], &["\u{1160}", "\u{903}"]), ("\u{1160}\u{308}\u{903}",
-            &["\u{1160}\u{308}\u{903}"], &["\u{1160}\u{308}", "\u{903}"]), ("\u{11A8}\u{903}",
-            &["\u{11A8}\u{903}"], &["\u{11A8}", "\u{903}"]), ("\u{11A8}\u{308}\u{903}",
-            &["\u{11A8}\u{308}\u{903}"], &["\u{11A8}\u{308}", "\u{903}"]), ("\u{AC00}\u{903}",
-            &["\u{AC00}\u{903}"], &["\u{AC00}", "\u{903}"]), ("\u{AC00}\u{308}\u{903}",
-            &["\u{AC00}\u{308}\u{903}"], &["\u{AC00}\u{308}", "\u{903}"]), ("\u{AC01}\u{903}",
-            &["\u{AC01}\u{903}"], &["\u{AC01}", "\u{903}"]), ("\u{AC01}\u{308}\u{903}",
-            &["\u{AC01}\u{308}\u{903}"], &["\u{AC01}\u{308}", "\u{903}"]), ("\u{1F1E6}\u{903}",
-            &["\u{1F1E6}\u{903}"], &["\u{1F1E6}", "\u{903}"]), ("\u{1F1E6}\u{308}\u{903}",
-            &["\u{1F1E6}\u{308}\u{903}"], &["\u{1F1E6}\u{308}", "\u{903}"]), ("\u{378}\u{903}",
-            &["\u{378}\u{903}"], &["\u{378}", "\u{903}"]), ("\u{378}\u{308}\u{903}",
-            &["\u{378}\u{308}\u{903}"], &["\u{378}\u{308}", "\u{903}"]),
-        ];
-
-        for &(s, g) in &test_same[..] {
-            // test forward iterator
-            assert!(order::equals(s.graphemes(true), g.iter().cloned()));
-            assert!(order::equals(s.graphemes(false), g.iter().cloned()));
-
-            // test reverse iterator
-            assert!(order::equals(s.graphemes(true).rev(), g.iter().rev().cloned()));
-            assert!(order::equals(s.graphemes(false).rev(), g.iter().rev().cloned()));
-        }
-
-        for &(s, gt, gf) in &test_diff {
-            // test forward iterator
-            assert!(order::equals(s.graphemes(true), gt.iter().cloned()));
-            assert!(order::equals(s.graphemes(false), gf.iter().cloned()));
-
-            // test reverse iterator
-            assert!(order::equals(s.graphemes(true).rev(), gt.iter().rev().cloned()));
-            assert!(order::equals(s.graphemes(false).rev(), gf.iter().rev().cloned()));
-        }
-
-        // test the indices iterators
-        let s = "a̐éö̲\r\n";
-        let gr_inds = s.grapheme_indices(true).collect::<Vec<(usize, &str)>>();
-        let b: &[_] = &[(0, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
-        assert_eq!(gr_inds, b);
-        let gr_inds = s.grapheme_indices(true).rev().collect::<Vec<(usize, &str)>>();
-        let b: &[_] = &[(11, "\r\n"), (6, "ö̲"), (3, "é"), (0, "a̐")];
-        assert_eq!(gr_inds, b);
-        let mut gr_inds_iter = s.grapheme_indices(true);
-        {
-            let gr_inds = gr_inds_iter.by_ref();
-            let e1 = gr_inds.size_hint();
-            assert_eq!(e1, (1, Some(13)));
-            let c = gr_inds.count();
-            assert_eq!(c, 4);
-        }
-        let e2 = gr_inds_iter.size_hint();
-        assert_eq!(e2, (0, Some(0)));
-
-        // make sure the reverse iterator does the right thing with "\n" at beginning of string
-        let s = "\n\r\n\r";
-        let gr = s.graphemes(true).rev().collect::<Vec<&str>>();
-        let b: &[_] = &["\r", "\r\n", "\n"];
-        assert_eq!(gr, b);
+    /// An iterator over the lines of a string, separated by either `\n` or `\r\n`.
+    ///
+    /// As with `.lines()`, this does not include an empty trailing line.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let four_lines = "foo\r\nbar\n\r\nbaz";
+    /// let v: Vec<&str> = four_lines.lines_any().collect();
+    ///
+    /// assert_eq!(v, ["foo", "bar", "", "baz"]);
+    /// ```
+    ///
+    /// Leaving off the trailing character:
+    ///
+    /// ```
+    /// let four_lines = "foo\r\nbar\n\r\nbaz\n";
+    /// let v: Vec<&str> = four_lines.lines_any().collect();
+    ///
+    /// assert_eq!(v, ["foo", "bar", "", "baz"]);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn lines_any(&self) -> LinesAny {
+        core_str::StrExt::lines_any(&self[..])
     }
 
-    #[test]
-    fn test_split_strator() {
-        fn t(s: &str, sep: &str, u: &[&str]) {
-            let v: Vec<&str> = s.split_str(sep).collect();
-            assert_eq!(v, u);
-        }
-        t("--1233345--", "12345", &["--1233345--"]);
-        t("abc::hello::there", "::", &["abc", "hello", "there"]);
-        t("::hello::there", "::", &["", "hello", "there"]);
-        t("hello::there::", "::", &["hello", "there", ""]);
-        t("::hello::there::", "::", &["", "hello", "there", ""]);
-        t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
-        t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
-        t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
-        t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
-        t("", ".", &[""]);
-        t("zz", "zz", &["",""]);
-        t("ok", "z", &["ok"]);
-        t("zzz", "zz", &["","z"]);
-        t("zzzzz", "zz", &["","","z"]);
-    }
-
-    #[test]
-    fn test_str_default() {
-        use core::default::Default;
-        fn t<S: Default + Str>() {
-            let s: S = Default::default();
-            assert_eq!(s.as_slice(), "");
-        }
-
-        t::<&str>();
-        t::<String>();
+    /// Deprecated: use `s[a .. b]` instead.
+    #[unstable(feature = "collections",
+               reason = "use slice notation [a..b] instead")]
+    #[deprecated(since = "1.0.0", reason = "use slice notation [a..b] instead")]
+    pub fn slice(&self, begin: usize, end: usize) -> &str {
+        &self[begin..end]
     }
 
-    #[test]
-    fn test_str_container() {
-        fn sum_len(v: &[&str]) -> usize {
-            v.iter().map(|x| x.len()).sum()
-        }
-
-        let s = String::from_str("01234");
-        assert_eq!(5, sum_len(&["012", "", "34"]));
-        assert_eq!(5, sum_len(&[&String::from_str("01"),
-                                &String::from_str("2"),
-                                &String::from_str("34"),
-                                &String::from_str("")]));
-        assert_eq!(5, sum_len(&[&s]));
+    /// Deprecated: use `s[a..]` instead.
+    #[unstable(feature = "collections",
+               reason = "use slice notation [a..b] instead")]
+    #[deprecated(since = "1.0.0", reason = "use slice notation [a..] instead")]
+    pub fn slice_from(&self, begin: usize) -> &str {
+        &self[begin..]
     }
 
-    #[test]
-    fn test_str_from_utf8() {
-        let xs = b"hello";
-        assert_eq!(from_utf8(xs), Ok("hello"));
-
-        let xs = "ศไทย中华Việt Nam".as_bytes();
-        assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam"));
-
-        let xs = b"hello\xFF";
-        assert_eq!(from_utf8(xs), Err(Utf8Error::TooShort));
+    /// Deprecated: use `s[..a]` instead.
+    #[unstable(feature = "collections",
+               reason = "use slice notation [a..b] instead")]
+    #[deprecated(since = "1.0.0", reason = "use slice notation [..a] instead")]
+    pub fn slice_to(&self, end: usize) -> &str {
+        &self[..end]
     }
-}
-
-#[cfg(test)]
-mod bench {
-    use super::*;
-    use prelude::{SliceExt, IteratorExt, SliceConcatExt};
-    use test::Bencher;
-    use test::black_box;
 
-    #[bench]
-    fn char_iterator(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-
-        b.iter(|| s.chars().count());
+    /// Returns a slice of the string from the character range [`begin`..`end`).
+    ///
+    /// That is, start at the `begin`-th code point of the string and continue
+    /// to the `end`-th code point. This does not detect or handle edge cases
+    /// such as leaving a combining character as the first code point of the
+    /// string.
+    ///
+    /// Due to the design of UTF-8, this operation is `O(end)`. See `slice`,
+    /// `slice_to` and `slice_from` for `O(1)` variants that use byte indices
+    /// rather than code point indices.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `begin` > `end` or the either `begin` or `end` are beyond the
+    /// last character of the string.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    ///
+    /// assert_eq!(s.slice_chars(0, 4), "Löwe");
+    /// assert_eq!(s.slice_chars(5, 7), "老虎");
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "may have yet to prove its worth")]
+    pub fn slice_chars(&self, begin: usize, end: usize) -> &str {
+        core_str::StrExt::slice_chars(&self[..], begin, end)
     }
 
-    #[bench]
-    fn char_iterator_for(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-
-        b.iter(|| {
-            for ch in s.chars() { black_box(ch); }
-        });
+    /// Takes a bytewise slice from a string.
+    ///
+    /// Returns the substring from [`begin`..`end`).
+    ///
+    /// # Unsafety
+    ///
+    /// Caller must check both UTF-8 character boundaries and the boundaries of the entire slice as
+    /// well.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    ///
+    /// unsafe {
+    ///     assert_eq!(s.slice_unchecked(0, 21), "Löwe 老虎 Léopard");
+    /// }
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
+        core_str::StrExt::slice_unchecked(&self[..], begin, end)
     }
 
-    #[bench]
-    fn char_iterator_ascii(b: &mut Bencher) {
-        let s = "Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb";
-
-        b.iter(|| s.chars().count());
+    /// Returns `true` if the given `&str` is a prefix of the string.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert!("banana".starts_with("ba"));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
+        core_str::StrExt::starts_with(&self[..], pat)
     }
 
-    #[bench]
-    fn char_iterator_rev(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-
-        b.iter(|| s.chars().rev().count());
+    /// Returns true if the given `&str` is a suffix of the string.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// assert!("banana".ends_with("nana"));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        core_str::StrExt::ends_with(&self[..], pat)
     }
 
-    #[bench]
-    fn char_iterator_rev_for(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+    /// Returns a string with all pre- and suffixes that match a pattern repeatedly removed.
+    ///
+    /// The pattern can be a simple `&str`, or a closure that determines the split.
+    ///
+    /// # Examples
+    ///
+    /// Simple `&str` patterns:
+    ///
+    /// ```
+    /// assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
+    ///
+    /// let x: &[_] = &['1', '2'];
+    /// assert_eq!("12foo1bar12".trim_matches(x), "foo1bar");
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
+    /// assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
+        where P::Searcher: DoubleEndedSearcher<'a>
+    {
+        core_str::StrExt::trim_matches(&self[..], pat)
+    }
 
-        b.iter(|| {
-            for ch in s.chars().rev() { black_box(ch); }
-        });
+    /// Returns a string with all prefixes that match a pattern repeatedly removed.
+    ///
+    /// The pattern can be a simple `&str`, or a closure that determines the split.
+    ///
+    /// # Examples
+    ///
+    /// Simple `&str` patterns:
+    ///
+    /// ```
+    /// assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
+    ///
+    /// let x: &[_] = &['1', '2'];
+    /// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12");
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
+    /// assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
+        core_str::StrExt::trim_left_matches(&self[..], pat)
     }
 
-    #[bench]
-    fn char_indicesator(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-        let len = s.chars().count();
+    /// Returns a string with all suffixes that match a pattern repeatedly removed.
+    ///
+    /// The pattern can be a simple `&str`, or a closure that determines the split.
+    ///
+    /// # Examples
+    ///
+    /// Simple `&str` patterns:
+    ///
+    /// ```
+    /// assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
+    /// let x: &[_] = &['1', '2'];
+    /// assert_eq!("12foo1bar12".trim_right_matches(x), "12foo1bar");
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
+    /// assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        core_str::StrExt::trim_right_matches(&self[..], pat)
+    }
 
-        b.iter(|| assert_eq!(s.char_indices().count(), len));
+    /// Check that `index`-th byte lies at the start and/or end of a UTF-8 code point sequence.
+    ///
+    /// The start and end of the string (when `index == self.len()`) are considered to be
+    /// boundaries.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `index` is greater than `self.len()`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    /// assert!(s.is_char_boundary(0));
+    /// // start of `老`
+    /// assert!(s.is_char_boundary(6));
+    /// assert!(s.is_char_boundary(s.len()));
+    ///
+    /// // second byte of `ö`
+    /// assert!(!s.is_char_boundary(2));
+    ///
+    /// // third byte of `老`
+    /// assert!(!s.is_char_boundary(8));
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "naming is uncertain with container conventions")]
+    pub fn is_char_boundary(&self, index: usize) -> bool {
+        core_str::StrExt::is_char_boundary(&self[..], index)
     }
 
-    #[bench]
-    fn char_indicesator_rev(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-        let len = s.chars().count();
+    /// Given a byte position, return the next char and its index.
+    ///
+    /// This can be used to iterate over the Unicode characters of a string.
+    ///
+    /// # Panics
+    ///
+    /// If `i` is greater than or equal to the length of the string.
+    /// If `i` is not the index of the beginning of a valid UTF-8 character.
+    ///
+    /// # Examples
+    ///
+    /// This example manually iterates through the characters of a string; this should normally be
+    /// done by `.chars()` or `.char_indices()`.
+    ///
+    /// ```
+    /// use std::str::CharRange;
+    ///
+    /// let s = "中华Việt Nam";
+    /// let mut i = 0;
+    /// while i < s.len() {
+    ///     let CharRange {ch, next} = s.char_range_at(i);
+    ///     println!("{}: {}", i, ch);
+    ///     i = next;
+    /// }
+    /// ```
+    ///
+    /// This outputs:
+    ///
+    /// ```text
+    /// 0: 中
+    /// 3: 华
+    /// 6: V
+    /// 7: i
+    /// 8: ệ
+    /// 11: t
+    /// 12:
+    /// 13: N
+    /// 14: a
+    /// 15: m
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "naming is uncertain with container conventions")]
+    pub fn char_range_at(&self, start: usize) -> CharRange {
+        core_str::StrExt::char_range_at(&self[..], start)
+    }
 
-        b.iter(|| assert_eq!(s.char_indices().rev().count(), len));
+    /// Given a byte position, return the previous `char` and its position.
+    ///
+    /// This function can be used to iterate over a Unicode string in reverse.
+    ///
+    /// Returns 0 for next index if called on start index 0.
+    ///
+    /// # Panics
+    ///
+    /// If `i` is greater than the length of the string.
+    /// If `i` is not an index following a valid UTF-8 character.
+    ///
+    /// # Examples
+    ///
+    /// This example manually iterates through the characters of a string; this should normally be
+    /// done by `.chars().rev()` or `.char_indices()`.
+    ///
+    /// ```
+    /// use std::str::CharRange;
+    ///
+    /// let s = "中华Việt Nam";
+    /// let mut i = s.len();
+    /// while i > 0 {
+    ///     let CharRange {ch, next} = s.char_range_at_reverse(i);
+    ///     println!("{}: {}", i, ch);
+    ///     i = next;
+    /// }
+    /// ```
+    ///
+    /// This outputs:
+    ///
+    /// ```text
+    /// 16: m
+    /// 15: a
+    /// 14: N
+    /// 13:
+    /// 12: t
+    /// 11: ệ
+    /// 8: i
+    /// 7: V
+    /// 6: 华
+    /// 3: 中
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "naming is uncertain with container conventions")]
+    pub fn char_range_at_reverse(&self, start: usize) -> CharRange {
+        core_str::StrExt::char_range_at_reverse(&self[..], start)
     }
 
-    #[bench]
-    fn split_unicode_ascii(b: &mut Bencher) {
-        let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
+    /// Given a byte position, return the `char` at that position.
+    ///
+    /// # Panics
+    ///
+    /// If `i` is greater than or equal to the length of the string.
+    /// If `i` is not the index of the beginning of a valid UTF-8 character.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = "abπc";
+    /// assert_eq!(s.char_at(1), 'b');
+    /// assert_eq!(s.char_at(2), 'π');
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "naming is uncertain with container conventions")]
+    pub fn char_at(&self, i: usize) -> char {
+        core_str::StrExt::char_at(&self[..], i)
+    }
 
-        b.iter(|| assert_eq!(s.split('V').count(), 3));
+    /// Given a byte position, return the `char` at that position, counting from the end.
+    ///
+    /// # Panics
+    ///
+    /// If `i` is greater than the length of the string.
+    /// If `i` is not an index following a valid UTF-8 character.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = "abπc";
+    /// assert_eq!(s.char_at_reverse(1), 'a');
+    /// assert_eq!(s.char_at_reverse(2), 'b');
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "naming is uncertain with container conventions")]
+    pub fn char_at_reverse(&self, i: usize) -> char {
+        core_str::StrExt::char_at_reverse(&self[..], i)
     }
 
-    #[bench]
-    fn split_ascii(b: &mut Bencher) {
-        let s = "Mary had a little lamb, Little lamb, little-lamb.";
-        let len = s.split(' ').count();
+    /// Convert `self` to a byte slice.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert_eq!("bors".as_bytes(), b"bors");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn as_bytes(&self) -> &[u8] {
+        core_str::StrExt::as_bytes(&self[..])
+    }
 
-        b.iter(|| assert_eq!(s.split(' ').count(), len));
+    /// Returns the byte index of the first character of `self` that matches the pattern, if it
+    /// exists.
+    ///
+    /// Returns `None` if it doesn't exist.
+    ///
+    /// The pattern can be a simple `&str`, or a closure that determines the split.
+    ///
+    /// # Examples
+    ///
+    /// Simple `&str` patterns:
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    ///
+    /// assert_eq!(s.find('L'), Some(0));
+    /// assert_eq!(s.find('é'), Some(14));
+    ///
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    ///
+    /// assert_eq!(s.find(|c: char| c.is_whitespace()), Some(5));
+    /// ```
+    ///
+    /// Not finding the pattern:
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    /// let x: &[_] = &['1', '2'];
+    ///
+    /// assert_eq!(s.find(x), None);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
+        core_str::StrExt::find(&self[..], pat)
     }
 
-    #[bench]
-    fn split_extern_fn(b: &mut Bencher) {
-        let s = "Mary had a little lamb, Little lamb, little-lamb.";
-        let len = s.split(' ').count();
-        fn pred(c: char) -> bool { c == ' ' }
+    /// Returns the byte index of the last character of `self` that matches the pattern, if it
+    /// exists.
+    ///
+    /// Returns `None` if it doesn't exist.
+    ///
+    /// The pattern can be a simple `&str`, or a closure that determines the split.
+    ///
+    /// # Examples
+    ///
+    /// Simple `&str` patterns:
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    ///
+    /// assert_eq!(s.rfind('L'), Some(13));
+    /// assert_eq!(s.rfind('é'), Some(14));
+    /// ```
+    ///
+    /// More complex patterns with a lambda:
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    ///
+    /// assert_eq!(s.rfind(|c: char| c.is_whitespace()), Some(12));
+    /// ```
+    ///
+    /// Not finding the pattern:
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    /// let x: &[_] = &['1', '2'];
+    ///
+    /// assert_eq!(s.rfind(x), None);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
+        where P::Searcher: ReverseSearcher<'a>
+    {
+        core_str::StrExt::rfind(&self[..], pat)
+    }
 
-        b.iter(|| assert_eq!(s.split(pred).count(), len));
+    /// Returns the byte index of the first matching substring if it exists.
+    ///
+    /// Returns `None` if it doesn't exist.
+    ///
+    /// The pattern can be a simple `&str`, or a closure that determines the split.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    ///
+    /// assert_eq!(s.find_str("老虎 L"), Some(6));
+    /// assert_eq!(s.find_str("muffin man"), None);
+    /// ```
+    #[unstable(feature = "collections")]
+    #[deprecated(since = "1.0.0", reason = "use `find()` with a `&str`")]
+    pub fn find_str<'a, P: Pattern<'a>>(&'a self, needle: P) -> Option<usize> {
+        core_str::StrExt::find_str(&self[..], needle)
     }
 
-    #[bench]
-    fn split_closure(b: &mut Bencher) {
-        let s = "Mary had a little lamb, Little lamb, little-lamb.";
-        let len = s.split(' ').count();
+    /// Retrieves the first character from a `&str` and returns it.
+    ///
+    /// This does not allocate a new string; instead, it returns a slice that points one character
+    /// beyond the character that was shifted.
+    ///
+    /// If the slice does not contain any characters, None is returned instead.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = "Löwe 老虎 Léopard";
+    /// let (c, s1) = s.slice_shift_char().unwrap();
+    ///
+    /// assert_eq!(c, 'L');
+    /// assert_eq!(s1, "öwe 老虎 Léopard");
+    ///
+    /// let (c, s2) = s1.slice_shift_char().unwrap();
+    ///
+    /// assert_eq!(c, 'ö');
+    /// assert_eq!(s2, "we 老虎 Léopard");
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "awaiting conventions about shifting and slices")]
+    pub fn slice_shift_char(&self) -> Option<(char, &str)> {
+        core_str::StrExt::slice_shift_char(&self[..])
+    }
 
-        b.iter(|| assert_eq!(s.split(|c: char| c == ' ').count(), len));
+    /// Returns the byte offset of an inner slice relative to an enclosing outer slice.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `inner` is not a direct slice contained within self.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let string = "a\nb\nc";
+    /// let lines: Vec<&str> = string.lines().collect();
+    ///
+    /// assert!(string.subslice_offset(lines[0]) == 0); // &"a"
+    /// assert!(string.subslice_offset(lines[1]) == 2); // &"b"
+    /// assert!(string.subslice_offset(lines[2]) == 4); // &"c"
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "awaiting convention about comparability of arbitrary slices")]
+    pub fn subslice_offset(&self, inner: &str) -> usize {
+        core_str::StrExt::subslice_offset(&self[..], inner)
     }
 
-    #[bench]
-    fn split_slice(b: &mut Bencher) {
-        let s = "Mary had a little lamb, Little lamb, little-lamb.";
-        let len = s.split(' ').count();
+    /// Return an unsafe pointer to the `&str`'s buffer.
+    ///
+    /// The caller must ensure that the string outlives this pointer, and that it is not
+    /// reallocated (e.g. by pushing to the string).
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = "Hello";
+    /// let p = s.as_ptr();
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn as_ptr(&self) -> *const u8 {
+        core_str::StrExt::as_ptr(&self[..])
+    }
 
-        let c: &[char] = &[' '];
-        b.iter(|| assert_eq!(s.split(c).count(), len));
+    /// Return an iterator of `u16` over the string encoded as UTF-16.
+    #[unstable(feature = "collections",
+               reason = "this functionality may only be provided by libunicode")]
+    pub fn utf16_units(&self) -> Utf16Units {
+        Utf16Units { encoder: Utf16Encoder::new(self[..].chars()) }
     }
 
-    #[bench]
-    fn bench_connect(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-        let sep = "→";
-        let v = vec![s, s, s, s, s, s, s, s, s, s];
-        b.iter(|| {
-            assert_eq!(v.connect(sep).len(), s.len() * 10 + sep.len() * 9);
-        })
+    /// Returns the length of `self` in bytes.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert_eq!("foo".len(), 3);
+    /// assert_eq!("ƒoo".len(), 4); // fancy f!
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn len(&self) -> usize {
+        core_str::StrExt::len(&self[..])
     }
 
-    #[bench]
-    fn bench_contains_short_short(b: &mut Bencher) {
-        let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
-        let needle = "sit";
+    /// Returns true if this slice has a length of zero bytes.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert!("".is_empty());
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_empty(&self) -> bool {
+        core_str::StrExt::is_empty(&self[..])
+    }
 
-        b.iter(|| {
-            assert!(haystack.contains(needle));
-        })
+    /// Parses `self` into the specified type.
+    ///
+    /// # Failure
+    ///
+    /// Will return `Err` if it's not possible to parse `self` into the type.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// assert_eq!("4".parse::<u32>(), Ok(4));
+    /// ```
+    ///
+    /// Failing:
+    ///
+    /// ```
+    /// assert!("j".parse::<u32>().is_err());
+    /// ```
+    #[inline]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
+        core_str::StrExt::parse(&self[..])
     }
 
-    #[bench]
-    fn bench_contains_short_long(b: &mut Bencher) {
-        let haystack = "\
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
-ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
-eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
-sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
-tempus vel, gravida nec quam.
+    /// Returns an iterator over the [grapheme clusters][graphemes] of `self`.
+    ///
+    /// [graphemes]: http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries
+    ///
+    /// If `is_extended` is true, the iterator is over the *extended grapheme clusters*;
+    /// otherwise, the iterator is over the *legacy grapheme clusters*.
+    /// [UAX#29](http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)
+    /// recommends extended grapheme cluster boundaries for general processing.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let gr1 = "a\u{310}e\u{301}o\u{308}\u{332}".graphemes(true).collect::<Vec<&str>>();
+    /// let b: &[_] = &["a\u{310}", "e\u{301}", "o\u{308}\u{332}"];
+    ///
+    /// assert_eq!(gr1.as_slice(), b);
+    ///
+    /// let gr2 = "a\r\nb🇷🇺🇸🇹".graphemes(true).collect::<Vec<&str>>();
+    /// let b: &[_] = &["a", "\r\n", "b", "🇷🇺🇸🇹"];
+    ///
+    /// assert_eq!(gr2.as_slice(), b);
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "this functionality may only be provided by libunicode")]
+    pub fn graphemes(&self, is_extended: bool) -> Graphemes {
+        UnicodeStr::graphemes(&self[..], is_extended)
+    }
 
-In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
-sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
-diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
-lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
-eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
-interdum. Curabitur ut nisi justo.
+    /// Returns an iterator over the grapheme clusters of `self` and their byte offsets. See
+    /// `graphemes()` for more information.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let gr_inds = "a̐éö̲\r\n".grapheme_indices(true).collect::<Vec<(usize, &str)>>();
+    /// let b: &[_] = &[(0, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
+    ///
+    /// assert_eq!(gr_inds.as_slice(), b);
+    /// ```
+    #[unstable(feature = "collections",
+               reason = "this functionality may only be provided by libunicode")]
+    pub fn grapheme_indices(&self, is_extended: bool) -> GraphemeIndices {
+        UnicodeStr::grapheme_indices(&self[..], is_extended)
+    }
 
-Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
-mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
-lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
-est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
-felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
-ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
-feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
-Aliquam sit amet placerat lorem.
+    /// An iterator over the non-empty words of `self`.
+    ///
+    /// A 'word' is a subsequence separated by any sequence of whitespace. Sequences of whitespace
+    /// are collapsed, so empty "words" are not included.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let some_words = " Mary   had\ta little  \n\t lamb";
+    /// let v: Vec<&str> = some_words.words().collect();
+    ///
+    /// assert_eq!(v, ["Mary", "had", "a", "little", "lamb"]);
+    /// ```
+    #[unstable(feature = "str_words",
+               reason = "the precise algorithm to use is unclear")]
+    pub fn words(&self) -> Words {
+        UnicodeStr::words(&self[..])
+    }
 
-Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
-mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
-Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
-lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
-suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
-cursus accumsan.
+    /// Returns a string's displayed width in columns.
+    ///
+    /// Control characters have zero width.
+    ///
+    /// `is_cjk` determines behavior for characters in the Ambiguous category: if `is_cjk` is
+    /// `true`, these are 2 columns wide; otherwise, they are 1. In CJK locales, `is_cjk` should be
+    /// `true`, else it should be `false`.
+    /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/) recommends that these
+    /// characters be treated as 1 column (i.e., `is_cjk = false`) if the locale is unknown.
+    #[unstable(feature = "collections",
+               reason = "this functionality may only be provided by libunicode")]
+    pub fn width(&self, is_cjk: bool) -> usize {
+        UnicodeStr::width(&self[..], is_cjk)
+    }
 
-Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
-feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
-vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
-leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
-malesuada sollicitudin quam eu fermentum.";
-        let needle = "english";
+    /// Returns a `&str` with leading and trailing whitespace removed.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = " Hello\tworld\t";
+    /// assert_eq!(s.trim(), "Hello\tworld");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn trim(&self) -> &str {
+        UnicodeStr::trim(&self[..])
+    }
 
-        b.iter(|| {
-            assert!(!haystack.contains(needle));
-        })
+    /// Returns a `&str` with leading whitespace removed.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = " Hello\tworld\t";
+    /// assert_eq!(s.trim_left(), "Hello\tworld\t");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn trim_left(&self) -> &str {
+        UnicodeStr::trim_left(&self[..])
     }
 
-    #[bench]
-    fn bench_contains_bad_naive(b: &mut Bencher) {
-        let haystack = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
-        let needle = "aaaaaaaab";
+    /// Returns a `&str` with trailing whitespace removed.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = " Hello\tworld\t";
+    /// assert_eq!(s.trim_right(), " Hello\tworld");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn trim_right(&self) -> &str {
+        UnicodeStr::trim_right(&self[..])
+    }
 
-        b.iter(|| {
-            assert!(!haystack.contains(needle));
-        })
+    /// Returns the lowercase equivalent of this string.
+    ///
+    /// # Examples
+    ///
+    /// let s = "HELLO";
+    /// assert_eq!(s.to_lowercase(), "hello");
+    #[unstable(feature = "collections")]
+    pub fn to_lowercase(&self) -> String {
+        let mut s = String::with_capacity(self.len());
+        s.extend(self[..].chars().flat_map(|c| c.to_lowercase()));
+        return s;
     }
-
-    #[bench]
-    fn bench_contains_equal(b: &mut Bencher) {
-        let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
-        let needle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
-
-        b.iter(|| {
-            assert!(haystack.contains(needle));
-        })
+
+    /// Returns the uppercase equivalent of this string.
+    ///
+    /// # Examples
+    ///
+    /// let s = "hello";
+    /// assert_eq!(s.to_uppercase(), "HELLO");
+    #[unstable(feature = "collections")]
+    pub fn to_uppercase(&self) -> String {
+        let mut s = String::with_capacity(self.len());
+        s.extend(self[..].chars().flat_map(|c| c.to_uppercase()));
+        return s;
     }
 }
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index bae69a08451..d2bc98096f6 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -24,7 +24,7 @@ use core::iter::{IntoIterator, FromIterator};
 use core::mem;
 use core::ops::{self, Deref, Add, Index};
 use core::ptr;
-use core::raw::Slice as RawSlice;
+use core::slice;
 use unicode::str as unicode_str;
 use unicode::str::Utf16Item;
 
@@ -85,6 +85,7 @@ impl String {
         }
     }
 
+    #[cfg(stage0)]
     /// Creates a new string buffer from the given string.
     ///
     /// # Examples
@@ -100,6 +101,33 @@ impl String {
         String { vec: ::slice::SliceExt::to_vec(string.as_bytes()) }
     }
 
+    #[cfg(not(stage0))]
+    /// Creates a new string buffer from the given string.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let s = String::from_str("hello");
+    /// assert_eq!(s.as_slice(), "hello");
+    /// ```
+    #[inline]
+    #[unstable(feature = "collections",
+               reason = "needs investigation to see if to_string() can match perf")]
+    #[cfg(not(test))]
+    pub fn from_str(string: &str) -> String {
+        String { vec: <[_]>::to_vec(string.as_bytes()) }
+    }
+
+    // HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is required for this
+    // method definition, is not available. Since we don't require this method for testing
+    // purposes, I'll just stub it
+    // NB see the slice::hack module in slice.rs for more information
+    #[inline]
+    #[cfg(test)]
+    pub fn from_str(_: &str) -> String {
+        panic!("not available with cfg(test)");
+    }
+
     /// Returns the vector as a string buffer, if possible, taking care not to
     /// copy it.
     ///
@@ -468,11 +496,11 @@ impl String {
         unsafe {
             // Attempt to not use an intermediate buffer by just pushing bytes
             // directly onto this string.
-            let slice = RawSlice {
-                data: self.vec.as_ptr().offset(cur_len as isize),
-                len: 4,
-            };
-            let used = ch.encode_utf8(mem::transmute(slice)).unwrap_or(0);
+            let slice = slice::from_raw_parts_mut (
+                self.vec.as_mut_ptr().offset(cur_len as isize),
+                4
+            );
+            let used = ch.encode_utf8(slice).unwrap_or(0);
             self.vec.set_len(cur_len + used);
         }
     }
@@ -997,450 +1025,3 @@ impl fmt::Write for String {
         Ok(())
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use test::Bencher;
-
-    use str::Utf8Error;
-    use core::iter::repeat;
-    use super::{as_string, CowString};
-
-    #[test]
-    fn test_as_string() {
-        let x = "foo";
-        assert_eq!(x, &**as_string(x));
-    }
-
-    #[test]
-    fn test_from_str() {
-      let owned: Option<::std::string::String> = "string".parse().ok();
-      assert_eq!(owned.as_ref().map(|s| &**s), Some("string"));
-    }
-
-    #[test]
-    fn test_unsized_to_string() {
-        let s: &str = "abc";
-        let _: String = (*s).to_string();
-    }
-
-    #[test]
-    fn test_from_utf8() {
-        let xs = b"hello".to_vec();
-        assert_eq!(String::from_utf8(xs).unwrap(),
-                   String::from_str("hello"));
-
-        let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
-        assert_eq!(String::from_utf8(xs).unwrap(),
-                   String::from_str("ศไทย中华Việt Nam"));
-
-        let xs = b"hello\xFF".to_vec();
-        let err = String::from_utf8(xs).err().unwrap();
-        assert_eq!(err.utf8_error(), Utf8Error::TooShort);
-        assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
-    }
-
-    #[test]
-    fn test_from_utf8_lossy() {
-        let xs = b"hello";
-        let ys: CowString = "hello".into_cow();
-        assert_eq!(String::from_utf8_lossy(xs), ys);
-
-        let xs = "ศไทย中华Việt Nam".as_bytes();
-        let ys: CowString = "ศไทย中华Việt Nam".into_cow();
-        assert_eq!(String::from_utf8_lossy(xs), ys);
-
-        let xs = b"Hello\xC2 There\xFF Goodbye";
-        assert_eq!(String::from_utf8_lossy(xs),
-                   String::from_str("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow());
-
-        let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
-        assert_eq!(String::from_utf8_lossy(xs),
-                   String::from_str("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow());
-
-        let xs = b"\xF5foo\xF5\x80bar";
-        assert_eq!(String::from_utf8_lossy(xs),
-                   String::from_str("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow());
-
-        let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
-        assert_eq!(String::from_utf8_lossy(xs),
-                   String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow());
-
-        let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
-        assert_eq!(String::from_utf8_lossy(xs),
-                   String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow());
-
-        let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
-        assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}\
-                                               foo\u{10000}bar").into_cow());
-
-        // surrogates
-        let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
-        assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}foo\
-                                               \u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow());
-    }
-
-    #[test]
-    fn test_from_utf16() {
-        let pairs =
-            [(String::from_str("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
-              vec![0xd800, 0xdf45, 0xd800, 0xdf3f,
-                0xd800, 0xdf3b, 0xd800, 0xdf46,
-                0xd800, 0xdf39, 0xd800, 0xdf3b,
-                0xd800, 0xdf30, 0x000a]),
-
-             (String::from_str("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
-              vec![0xd801, 0xdc12, 0xd801,
-                0xdc49, 0xd801, 0xdc2e, 0xd801,
-                0xdc40, 0xd801, 0xdc32, 0xd801,
-                0xdc4b, 0x0020, 0xd801, 0xdc0f,
-                0xd801, 0xdc32, 0xd801, 0xdc4d,
-                0x000a]),
-
-             (String::from_str("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
-              vec![0xd800, 0xdf00, 0xd800, 0xdf16,
-                0xd800, 0xdf0b, 0xd800, 0xdf04,
-                0xd800, 0xdf11, 0xd800, 0xdf09,
-                0x00b7, 0xd800, 0xdf0c, 0xd800,
-                0xdf04, 0xd800, 0xdf15, 0xd800,
-                0xdf04, 0xd800, 0xdf0b, 0xd800,
-                0xdf09, 0xd800, 0xdf11, 0x000a ]),
-
-             (String::from_str("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
-              vec![0xd801, 0xdc8b, 0xd801, 0xdc98,
-                0xd801, 0xdc88, 0xd801, 0xdc91,
-                0xd801, 0xdc9b, 0xd801, 0xdc92,
-                0x0020, 0xd801, 0xdc95, 0xd801,
-                0xdc93, 0x0020, 0xd801, 0xdc88,
-                0xd801, 0xdc9a, 0xd801, 0xdc8d,
-                0x0020, 0xd801, 0xdc8f, 0xd801,
-                0xdc9c, 0xd801, 0xdc92, 0xd801,
-                0xdc96, 0xd801, 0xdc86, 0x0020,
-                0xd801, 0xdc95, 0xd801, 0xdc86,
-                0x000a ]),
-             // Issue #12318, even-numbered non-BMP planes
-             (String::from_str("\u{20000}"),
-              vec![0xD840, 0xDC00])];
-
-        for p in &pairs {
-            let (s, u) = (*p).clone();
-            let s_as_utf16 = s.utf16_units().collect::<Vec<u16>>();
-            let u_as_string = String::from_utf16(&u).unwrap();
-
-            assert!(::unicode::str::is_utf16(&u));
-            assert_eq!(s_as_utf16, u);
-
-            assert_eq!(u_as_string, s);
-            assert_eq!(String::from_utf16_lossy(&u), s);
-
-            assert_eq!(String::from_utf16(&s_as_utf16).unwrap(), s);
-            assert_eq!(u_as_string.utf16_units().collect::<Vec<u16>>(), u);
-        }
-    }
-
-    #[test]
-    fn test_utf16_invalid() {
-        // completely positive cases tested above.
-        // lead + eof
-        assert!(String::from_utf16(&[0xD800]).is_err());
-        // lead + lead
-        assert!(String::from_utf16(&[0xD800, 0xD800]).is_err());
-
-        // isolated trail
-        assert!(String::from_utf16(&[0x0061, 0xDC00]).is_err());
-
-        // general
-        assert!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]).is_err());
-    }
-
-    #[test]
-    fn test_from_utf16_lossy() {
-        // completely positive cases tested above.
-        // lead + eof
-        assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from_str("\u{FFFD}"));
-        // lead + lead
-        assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]),
-                   String::from_str("\u{FFFD}\u{FFFD}"));
-
-        // isolated trail
-        assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from_str("a\u{FFFD}"));
-
-        // general
-        assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
-                   String::from_str("\u{FFFD}𐒋\u{FFFD}"));
-    }
-
-    #[test]
-    fn test_push_bytes() {
-        let mut s = String::from_str("ABC");
-        unsafe {
-            let mv = s.as_mut_vec();
-            mv.push_all(&[b'D']);
-        }
-        assert_eq!(s, "ABCD");
-    }
-
-    #[test]
-    fn test_push_str() {
-        let mut s = String::new();
-        s.push_str("");
-        assert_eq!(&s[0..], "");
-        s.push_str("abc");
-        assert_eq!(&s[0..], "abc");
-        s.push_str("ประเทศไทย中华Việt Nam");
-        assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam");
-    }
-
-    #[test]
-    fn test_push() {
-        let mut data = String::from_str("ประเทศไทย中");
-        data.push('华');
-        data.push('b'); // 1 byte
-        data.push('¢'); // 2 byte
-        data.push('€'); // 3 byte
-        data.push('𤭢'); // 4 byte
-        assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
-    }
-
-    #[test]
-    fn test_pop() {
-        let mut data = String::from_str("ประเทศไทย中华b¢€𤭢");
-        assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
-        assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
-        assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
-        assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
-        assert_eq!(data.pop().unwrap(), '华');
-        assert_eq!(data, "ประเทศไทย中");
-    }
-
-    #[test]
-    fn test_str_truncate() {
-        let mut s = String::from_str("12345");
-        s.truncate(5);
-        assert_eq!(s, "12345");
-        s.truncate(3);
-        assert_eq!(s, "123");
-        s.truncate(0);
-        assert_eq!(s, "");
-
-        let mut s = String::from_str("12345");
-        let p = s.as_ptr();
-        s.truncate(3);
-        s.push_str("6");
-        let p_ = s.as_ptr();
-        assert_eq!(p_, p);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_str_truncate_invalid_len() {
-        let mut s = String::from_str("12345");
-        s.truncate(6);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_str_truncate_split_codepoint() {
-        let mut s = String::from_str("\u{FC}"); // ü
-        s.truncate(1);
-    }
-
-    #[test]
-    fn test_str_clear() {
-        let mut s = String::from_str("12345");
-        s.clear();
-        assert_eq!(s.len(), 0);
-        assert_eq!(s, "");
-    }
-
-    #[test]
-    fn test_str_add() {
-        let a = String::from_str("12345");
-        let b = a + "2";
-        let b = b + "2";
-        assert_eq!(b.len(), 7);
-        assert_eq!(b, "1234522");
-    }
-
-    #[test]
-    fn remove() {
-        let mut s = "ศไทย中华Việt Nam; foobar".to_string();;
-        assert_eq!(s.remove(0), 'ศ');
-        assert_eq!(s.len(), 33);
-        assert_eq!(s, "ไทย中华Việt Nam; foobar");
-        assert_eq!(s.remove(17), 'ệ');
-        assert_eq!(s, "ไทย中华Vit Nam; foobar");
-    }
-
-    #[test] #[should_panic]
-    fn remove_bad() {
-        "ศ".to_string().remove(1);
-    }
-
-    #[test]
-    fn insert() {
-        let mut s = "foobar".to_string();
-        s.insert(0, 'ệ');
-        assert_eq!(s, "ệfoobar");
-        s.insert(6, 'ย');
-        assert_eq!(s, "ệfooยbar");
-    }
-
-    #[test] #[should_panic] fn insert_bad1() { "".to_string().insert(1, 't'); }
-    #[test] #[should_panic] fn insert_bad2() { "ệ".to_string().insert(1, 't'); }
-
-    #[test]
-    fn test_slicing() {
-        let s = "foobar".to_string();
-        assert_eq!("foobar", &s[..]);
-        assert_eq!("foo", &s[..3]);
-        assert_eq!("bar", &s[3..]);
-        assert_eq!("oob", &s[1..4]);
-    }
-
-    #[test]
-    fn test_simple_types() {
-        assert_eq!(1.to_string(), "1");
-        assert_eq!((-1).to_string(), "-1");
-        assert_eq!(200.to_string(), "200");
-        assert_eq!(2.to_string(), "2");
-        assert_eq!(true.to_string(), "true");
-        assert_eq!(false.to_string(), "false");
-        assert_eq!(("hi".to_string()).to_string(), "hi");
-    }
-
-    #[test]
-    fn test_vectors() {
-        let x: Vec<i32> = vec![];
-        assert_eq!(format!("{:?}", x), "[]");
-        assert_eq!(format!("{:?}", vec![1]), "[1]");
-        assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
-        assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) ==
-               "[[], [1], [1, 1]]");
-    }
-
-    #[test]
-    fn test_from_iterator() {
-        let s = "ศไทย中华Việt Nam".to_string();
-        let t = "ศไทย中华";
-        let u = "Việt Nam";
-
-        let a: String = s.chars().collect();
-        assert_eq!(s, a);
-
-        let mut b = t.to_string();
-        b.extend(u.chars());
-        assert_eq!(s, b);
-
-        let c: String = vec![t, u].into_iter().collect();
-        assert_eq!(s, c);
-
-        let mut d = t.to_string();
-        d.extend(vec![u].into_iter());
-        assert_eq!(s, d);
-    }
-
-    #[bench]
-    fn bench_with_capacity(b: &mut Bencher) {
-        b.iter(|| {
-            String::with_capacity(100)
-        });
-    }
-
-    #[bench]
-    fn bench_push_str(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-        b.iter(|| {
-            let mut r = String::new();
-            r.push_str(s);
-        });
-    }
-
-    const REPETITIONS: u64 = 10_000;
-
-    #[bench]
-    fn bench_push_str_one_byte(b: &mut Bencher) {
-        b.bytes = REPETITIONS;
-        b.iter(|| {
-            let mut r = String::new();
-            for _ in 0..REPETITIONS {
-                r.push_str("a")
-            }
-        });
-    }
-
-    #[bench]
-    fn bench_push_char_one_byte(b: &mut Bencher) {
-        b.bytes = REPETITIONS;
-        b.iter(|| {
-            let mut r = String::new();
-            for _ in 0..REPETITIONS {
-                r.push('a')
-            }
-        });
-    }
-
-    #[bench]
-    fn bench_push_char_two_bytes(b: &mut Bencher) {
-        b.bytes = REPETITIONS * 2;
-        b.iter(|| {
-            let mut r = String::new();
-            for _ in 0..REPETITIONS {
-                r.push('â')
-            }
-        });
-    }
-
-    #[bench]
-    fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
-        let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
-                  Lorem ipsum dolor sit amet, consectetur. ";
-
-        assert_eq!(100, s.len());
-        b.iter(|| {
-            let _ = String::from_utf8_lossy(s);
-        });
-    }
-
-    #[bench]
-    fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
-        let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
-        assert_eq!(100, s.len());
-        b.iter(|| {
-            let _ = String::from_utf8_lossy(s);
-        });
-    }
-
-    #[bench]
-    fn from_utf8_lossy_invalid(b: &mut Bencher) {
-        let s = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
-        b.iter(|| {
-            let _ = String::from_utf8_lossy(s);
-        });
-    }
-
-    #[bench]
-    fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
-        let s = repeat(0xf5).take(100).collect::<Vec<_>>();
-        b.iter(|| {
-            let _ = String::from_utf8_lossy(&s);
-        });
-    }
-
-    #[bench]
-    fn bench_exact_size_shrink_to_fit(b: &mut Bencher) {
-        let s = "Hello there, the quick brown fox jumped over the lazy dog! \
-                 Lorem ipsum dolor sit amet, consectetur. ";
-        // ensure our operation produces an exact-size string before we benchmark it
-        let mut r = String::with_capacity(s.len());
-        r.push_str(s);
-        assert_eq!(r.len(), r.capacity());
-        b.iter(|| {
-            let mut r = String::with_capacity(s.len());
-            r.push_str(s);
-            r.shrink_to_fit();
-            r
-        });
-    }
-}
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 67594b7c4bc..404179bd484 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -59,12 +59,12 @@ use core::intrinsics::assume;
 use core::iter::{repeat, FromIterator, IntoIterator};
 use core::marker::PhantomData;
 use core::mem;
+#[cfg(stage0)]
 use core::num::{Int, UnsignedInt};
 use core::ops::{Index, IndexMut, Deref, Add};
 use core::ops;
 use core::ptr;
 use core::ptr::Unique;
-use core::raw::Slice as RawSlice;
 use core::slice;
 use core::usize;
 
@@ -435,10 +435,7 @@ impl<T> Vec<T> {
         unsafe {
             let ptr = *self.ptr;
             assume(!ptr.is_null());
-            mem::transmute(RawSlice {
-                data: ptr,
-                len: self.len,
-            })
+            slice::from_raw_parts_mut(ptr, self.len)
         }
     }
 
@@ -1286,8 +1283,23 @@ pub fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T> {
 
 #[unstable(feature = "collections")]
 impl<T:Clone> Clone for Vec<T> {
+    #[cfg(stage0)]
     fn clone(&self) -> Vec<T> { ::slice::SliceExt::to_vec(&**self) }
 
+    #[cfg(not(stage0))]
+    #[cfg(not(test))]
+    fn clone(&self) -> Vec<T> { <[T]>::to_vec(&**self) }
+
+    // HACK(japaric): with cfg(test) the inherent `[T]::to_vec` method, which is required for this
+    // method definition, is not available. Instead use the `slice::to_vec`  function which is only
+    // available with cfg(test)
+    // NB see the slice::hack module in slice.rs for more information
+    #[cfg(not(stage0))]
+    #[cfg(test)]
+    fn clone(&self) -> Vec<T> {
+        ::slice::to_vec(&**self)
+    }
+
     fn clone_from(&mut self, other: &Vec<T>) {
         // drop anything in self that will not be overwritten
         if self.len() > other.len() {
@@ -1560,10 +1572,7 @@ impl<T> AsSlice<T> for Vec<T> {
         unsafe {
             let p = *self.ptr;
             assume(p != 0 as *mut T);
-            mem::transmute(RawSlice {
-                data: p,
-                len: self.len
-            })
+            slice::from_raw_parts(p, self.len)
         }
     }
 }
@@ -1953,991 +1962,3 @@ impl<T,U> Drop for PartialVecZeroSized<T,U> {
         }
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use core::mem::size_of;
-    use core::iter::repeat;
-    use test::Bencher;
-    use super::as_vec;
-
-    struct DropCounter<'a> {
-        count: &'a mut u32
-    }
-
-    #[unsafe_destructor]
-    impl<'a> Drop for DropCounter<'a> {
-        fn drop(&mut self) {
-            *self.count += 1;
-        }
-    }
-
-    #[test]
-    fn test_as_vec() {
-        let xs = [1u8, 2u8, 3u8];
-        assert_eq!(&**as_vec(&xs), xs);
-    }
-
-    #[test]
-    fn test_as_vec_dtor() {
-        let (mut count_x, mut count_y) = (0, 0);
-        {
-            let xs = &[DropCounter { count: &mut count_x }, DropCounter { count: &mut count_y }];
-            assert_eq!(as_vec(xs).len(), 2);
-        }
-        assert_eq!(count_x, 1);
-        assert_eq!(count_y, 1);
-    }
-
-    #[test]
-    fn test_small_vec_struct() {
-        assert!(size_of::<Vec<u8>>() == size_of::<usize>() * 3);
-    }
-
-    #[test]
-    fn test_double_drop() {
-        struct TwoVec<T> {
-            x: Vec<T>,
-            y: Vec<T>
-        }
-
-        let (mut count_x, mut count_y) = (0, 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() {
-        let mut v = Vec::new();
-        assert_eq!(v.capacity(), 0);
-
-        v.reserve(2);
-        assert!(v.capacity() >= 2);
-
-        for i in 0..16 {
-            v.push(i);
-        }
-
-        assert!(v.capacity() >= 16);
-        v.reserve(16);
-        assert!(v.capacity() >= 32);
-
-        v.push(16);
-
-        v.reserve(16);
-        assert!(v.capacity() >= 33)
-    }
-
-    #[test]
-    fn test_extend() {
-        let mut v = Vec::new();
-        let mut w = Vec::new();
-
-        v.extend(0..3);
-        for i in 0..3 { w.push(i) }
-
-        assert_eq!(v, w);
-
-        v.extend(3..10);
-        for i in 3..10 { w.push(i) }
-
-        assert_eq!(v, w);
-    }
-
-    #[test]
-    fn test_slice_from_mut() {
-        let mut values = vec![1, 2, 3, 4, 5];
-        {
-            let slice = &mut values[2 ..];
-            assert!(slice == [3, 4, 5]);
-            for p in slice {
-                *p += 2;
-            }
-        }
-
-        assert!(values == [1, 2, 5, 6, 7]);
-    }
-
-    #[test]
-    fn test_slice_to_mut() {
-        let mut values = vec![1, 2, 3, 4, 5];
-        {
-            let slice = &mut values[.. 2];
-            assert!(slice == [1, 2]);
-            for p in slice {
-                *p += 1;
-            }
-        }
-
-        assert!(values == [2, 3, 3, 4, 5]);
-    }
-
-    #[test]
-    fn test_split_at_mut() {
-        let mut values = vec![1, 2, 3, 4, 5];
-        {
-            let (left, right) = values.split_at_mut(2);
-            {
-                let left: &[_] = left;
-                assert!(&left[..left.len()] == &[1, 2]);
-            }
-            for p in left {
-                *p += 1;
-            }
-
-            {
-                let right: &[_] = right;
-                assert!(&right[..right.len()] == &[3, 4, 5]);
-            }
-            for p in right {
-                *p += 2;
-            }
-        }
-
-        assert_eq!(values, [2, 3, 5, 6, 7]);
-    }
-
-    #[test]
-    fn test_clone() {
-        let v: Vec<i32> = vec![];
-        let w = vec!(1, 2, 3);
-
-        assert_eq!(v, v.clone());
-
-        let z = w.clone();
-        assert_eq!(w, z);
-        // they should be disjoint in memory.
-        assert!(w.as_ptr() != z.as_ptr())
-    }
-
-    #[test]
-    fn test_clone_from() {
-        let mut v = vec!();
-        let three: Vec<Box<_>> = vec!(box 1, box 2, box 3);
-        let two: Vec<Box<_>> = vec!(box 4, box 5);
-        // zero, long
-        v.clone_from(&three);
-        assert_eq!(v, three);
-
-        // equal
-        v.clone_from(&three);
-        assert_eq!(v, three);
-
-        // long, short
-        v.clone_from(&two);
-        assert_eq!(v, two);
-
-        // short, long
-        v.clone_from(&three);
-        assert_eq!(v, three)
-    }
-
-    #[test]
-    fn test_retain() {
-        let mut vec = vec![1, 2, 3, 4];
-        vec.retain(|&x| x % 2 == 0);
-        assert_eq!(vec, [2, 4]);
-    }
-
-    #[test]
-    fn zero_sized_values() {
-        let mut v = Vec::new();
-        assert_eq!(v.len(), 0);
-        v.push(());
-        assert_eq!(v.len(), 1);
-        v.push(());
-        assert_eq!(v.len(), 2);
-        assert_eq!(v.pop(), Some(()));
-        assert_eq!(v.pop(), Some(()));
-        assert_eq!(v.pop(), None);
-
-        assert_eq!(v.iter().count(), 0);
-        v.push(());
-        assert_eq!(v.iter().count(), 1);
-        v.push(());
-        assert_eq!(v.iter().count(), 2);
-
-        for &() in &v {}
-
-        assert_eq!(v.iter_mut().count(), 2);
-        v.push(());
-        assert_eq!(v.iter_mut().count(), 3);
-        v.push(());
-        assert_eq!(v.iter_mut().count(), 4);
-
-        for &mut () in &mut v {}
-        unsafe { v.set_len(0); }
-        assert_eq!(v.iter_mut().count(), 0);
-    }
-
-    #[test]
-    fn test_partition() {
-        assert_eq!(vec![].into_iter().partition(|x: &i32| *x < 3), (vec![], vec![]));
-        assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 4), (vec![1, 2, 3], vec![]));
-        assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 2), (vec![1], vec![2, 3]));
-        assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 0), (vec![], vec![1, 2, 3]));
-    }
-
-    #[test]
-    fn test_zip_unzip() {
-        let z1 = vec![(1, 4), (2, 5), (3, 6)];
-
-        let (left, right): (Vec<_>, Vec<_>) = z1.iter().cloned().unzip();
-
-        assert_eq!((1, 4), (left[0], right[0]));
-        assert_eq!((2, 5), (left[1], right[1]));
-        assert_eq!((3, 6), (left[2], right[2]));
-    }
-
-    #[test]
-    fn test_unsafe_ptrs() {
-        unsafe {
-            // Test on-stack copy-from-buf.
-            let a = [1, 2, 3];
-            let ptr = a.as_ptr();
-            let b = Vec::from_raw_buf(ptr, 3);
-            assert_eq!(b, [1, 2, 3]);
-
-            // Test on-heap copy-from-buf.
-            let c = vec![1, 2, 3, 4, 5];
-            let ptr = c.as_ptr();
-            let d = Vec::from_raw_buf(ptr, 5);
-            assert_eq!(d, [1, 2, 3, 4, 5]);
-        }
-    }
-
-    #[test]
-    fn test_vec_truncate_drop() {
-        static mut drops: u32 = 0;
-        struct Elem(i32);
-        impl Drop for Elem {
-            fn drop(&mut self) {
-                unsafe { drops += 1; }
-            }
-        }
-
-        let mut v = vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
-        assert_eq!(unsafe { drops }, 0);
-        v.truncate(3);
-        assert_eq!(unsafe { drops }, 2);
-        v.truncate(0);
-        assert_eq!(unsafe { drops }, 5);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_vec_truncate_fail() {
-        struct BadElem(i32);
-        impl Drop for BadElem {
-            fn drop(&mut self) {
-                let BadElem(ref mut x) = *self;
-                if *x == 0xbadbeef {
-                    panic!("BadElem panic: 0xbadbeef")
-                }
-            }
-        }
-
-        let mut v = vec![BadElem(1), BadElem(2), BadElem(0xbadbeef), BadElem(4)];
-        v.truncate(0);
-    }
-
-    #[test]
-    fn test_index() {
-        let vec = vec![1, 2, 3];
-        assert!(vec[1] == 2);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_index_out_of_bounds() {
-        let vec = vec![1, 2, 3];
-        let _ = vec[3];
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_slice_out_of_bounds_1() {
-        let x = vec![1, 2, 3, 4, 5];
-        &x[-1..];
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_slice_out_of_bounds_2() {
-        let x = vec![1, 2, 3, 4, 5];
-        &x[..6];
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_slice_out_of_bounds_3() {
-        let x = vec![1, 2, 3, 4, 5];
-        &x[-1..4];
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_slice_out_of_bounds_4() {
-        let x = vec![1, 2, 3, 4, 5];
-        &x[1..6];
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_slice_out_of_bounds_5() {
-        let x = vec![1, 2, 3, 4, 5];
-        &x[3..2];
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_swap_remove_empty() {
-        let mut vec= Vec::<i32>::new();
-        vec.swap_remove(0);
-    }
-
-    #[test]
-    fn test_move_iter_unwrap() {
-        let mut vec = Vec::with_capacity(7);
-        vec.push(1);
-        vec.push(2);
-        let ptr = vec.as_ptr();
-        vec = vec.into_iter().into_inner();
-        assert_eq!(vec.as_ptr(), ptr);
-        assert_eq!(vec.capacity(), 7);
-        assert_eq!(vec.len(), 0);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_map_in_place_incompatible_types_fail() {
-        let v = vec![0, 1, 2];
-        v.map_in_place(|_| ());
-    }
-
-    #[test]
-    fn test_map_in_place() {
-        let v = vec![0, 1, 2];
-        assert_eq!(v.map_in_place(|i: u32| i as i32 - 1), [-1, 0, 1]);
-    }
-
-    #[test]
-    fn test_map_in_place_zero_sized() {
-        let v = vec![(), ()];
-        #[derive(PartialEq, Debug)]
-        struct ZeroSized;
-        assert_eq!(v.map_in_place(|_| ZeroSized), [ZeroSized, ZeroSized]);
-    }
-
-    #[test]
-    fn test_map_in_place_zero_drop_count() {
-        use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
-
-        #[derive(Clone, PartialEq, Debug)]
-        struct Nothing;
-        impl Drop for Nothing { fn drop(&mut self) { } }
-
-        #[derive(Clone, PartialEq, Debug)]
-        struct ZeroSized;
-        impl Drop for ZeroSized {
-            fn drop(&mut self) {
-                DROP_COUNTER.fetch_add(1, Ordering::Relaxed);
-            }
-        }
-        const NUM_ELEMENTS: usize = 2;
-        static DROP_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
-
-        let v = repeat(Nothing).take(NUM_ELEMENTS).collect::<Vec<_>>();
-
-        DROP_COUNTER.store(0, Ordering::Relaxed);
-
-        let v = v.map_in_place(|_| ZeroSized);
-        assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
-        drop(v);
-        assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), NUM_ELEMENTS);
-    }
-
-    #[test]
-    fn test_move_items() {
-        let vec = vec![1, 2, 3];
-        let mut vec2 = vec![];
-        for i in vec {
-            vec2.push(i);
-        }
-        assert_eq!(vec2, [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_move_items_reverse() {
-        let vec = vec![1, 2, 3];
-        let mut vec2 = vec![];
-        for i in vec.into_iter().rev() {
-            vec2.push(i);
-        }
-        assert_eq!(vec2, [3, 2, 1]);
-    }
-
-    #[test]
-    fn test_move_items_zero_sized() {
-        let vec = vec![(), (), ()];
-        let mut vec2 = vec![];
-        for i in vec {
-            vec2.push(i);
-        }
-        assert_eq!(vec2, [(), (), ()]);
-    }
-
-    #[test]
-    fn test_drain_items() {
-        let mut vec = vec![1, 2, 3];
-        let mut vec2 = vec![];
-        for i in vec.drain() {
-            vec2.push(i);
-        }
-        assert_eq!(vec, []);
-        assert_eq!(vec2, [ 1, 2, 3 ]);
-    }
-
-    #[test]
-    fn test_drain_items_reverse() {
-        let mut vec = vec![1, 2, 3];
-        let mut vec2 = vec![];
-        for i in vec.drain().rev() {
-            vec2.push(i);
-        }
-        assert_eq!(vec, []);
-        assert_eq!(vec2, [3, 2, 1]);
-    }
-
-    #[test]
-    fn test_drain_items_zero_sized() {
-        let mut vec = vec![(), (), ()];
-        let mut vec2 = vec![];
-        for i in vec.drain() {
-            vec2.push(i);
-        }
-        assert_eq!(vec, []);
-        assert_eq!(vec2, [(), (), ()]);
-    }
-
-    #[test]
-    fn test_into_boxed_slice() {
-        let xs = vec![1, 2, 3];
-        let ys = xs.into_boxed_slice();
-        assert_eq!(&*ys, [1, 2, 3]);
-    }
-
-    #[test]
-    fn test_append() {
-        let mut vec = vec![1, 2, 3];
-        let mut vec2 = vec![4, 5, 6];
-        vec.append(&mut vec2);
-        assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
-        assert_eq!(vec2, []);
-    }
-
-    #[test]
-    fn test_split_off() {
-        let mut vec = vec![1, 2, 3, 4, 5, 6];
-        let vec2 = vec.split_off(4);
-        assert_eq!(vec, [1, 2, 3, 4]);
-        assert_eq!(vec2, [5, 6]);
-    }
-
-    #[bench]
-    fn bench_new(b: &mut Bencher) {
-        b.iter(|| {
-            let v: Vec<u32> = Vec::new();
-            assert_eq!(v.len(), 0);
-            assert_eq!(v.capacity(), 0);
-        })
-    }
-
-    fn do_bench_with_capacity(b: &mut Bencher, src_len: usize) {
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let v: Vec<u32> = Vec::with_capacity(src_len);
-            assert_eq!(v.len(), 0);
-            assert_eq!(v.capacity(), src_len);
-        })
-    }
-
-    #[bench]
-    fn bench_with_capacity_0000(b: &mut Bencher) {
-        do_bench_with_capacity(b, 0)
-    }
-
-    #[bench]
-    fn bench_with_capacity_0010(b: &mut Bencher) {
-        do_bench_with_capacity(b, 10)
-    }
-
-    #[bench]
-    fn bench_with_capacity_0100(b: &mut Bencher) {
-        do_bench_with_capacity(b, 100)
-    }
-
-    #[bench]
-    fn bench_with_capacity_1000(b: &mut Bencher) {
-        do_bench_with_capacity(b, 1000)
-    }
-
-    fn do_bench_from_fn(b: &mut Bencher, src_len: usize) {
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let dst = (0..src_len).collect::<Vec<_>>();
-            assert_eq!(dst.len(), src_len);
-            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
-        })
-    }
-
-    #[bench]
-    fn bench_from_fn_0000(b: &mut Bencher) {
-        do_bench_from_fn(b, 0)
-    }
-
-    #[bench]
-    fn bench_from_fn_0010(b: &mut Bencher) {
-        do_bench_from_fn(b, 10)
-    }
-
-    #[bench]
-    fn bench_from_fn_0100(b: &mut Bencher) {
-        do_bench_from_fn(b, 100)
-    }
-
-    #[bench]
-    fn bench_from_fn_1000(b: &mut Bencher) {
-        do_bench_from_fn(b, 1000)
-    }
-
-    fn do_bench_from_elem(b: &mut Bencher, src_len: usize) {
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let dst: Vec<usize> = repeat(5).take(src_len).collect();
-            assert_eq!(dst.len(), src_len);
-            assert!(dst.iter().all(|x| *x == 5));
-        })
-    }
-
-    #[bench]
-    fn bench_from_elem_0000(b: &mut Bencher) {
-        do_bench_from_elem(b, 0)
-    }
-
-    #[bench]
-    fn bench_from_elem_0010(b: &mut Bencher) {
-        do_bench_from_elem(b, 10)
-    }
-
-    #[bench]
-    fn bench_from_elem_0100(b: &mut Bencher) {
-        do_bench_from_elem(b, 100)
-    }
-
-    #[bench]
-    fn bench_from_elem_1000(b: &mut Bencher) {
-        do_bench_from_elem(b, 1000)
-    }
-
-    fn do_bench_from_slice(b: &mut Bencher, src_len: usize) {
-        let src: Vec<_> = FromIterator::from_iter(0..src_len);
-
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let dst = src.clone()[..].to_vec();
-            assert_eq!(dst.len(), src_len);
-            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
-        });
-    }
-
-    #[bench]
-    fn bench_from_slice_0000(b: &mut Bencher) {
-        do_bench_from_slice(b, 0)
-    }
-
-    #[bench]
-    fn bench_from_slice_0010(b: &mut Bencher) {
-        do_bench_from_slice(b, 10)
-    }
-
-    #[bench]
-    fn bench_from_slice_0100(b: &mut Bencher) {
-        do_bench_from_slice(b, 100)
-    }
-
-    #[bench]
-    fn bench_from_slice_1000(b: &mut Bencher) {
-        do_bench_from_slice(b, 1000)
-    }
-
-    fn do_bench_from_iter(b: &mut Bencher, src_len: usize) {
-        let src: Vec<_> = FromIterator::from_iter(0..src_len);
-
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let dst: Vec<_> = FromIterator::from_iter(src.clone().into_iter());
-            assert_eq!(dst.len(), src_len);
-            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
-        });
-    }
-
-    #[bench]
-    fn bench_from_iter_0000(b: &mut Bencher) {
-        do_bench_from_iter(b, 0)
-    }
-
-    #[bench]
-    fn bench_from_iter_0010(b: &mut Bencher) {
-        do_bench_from_iter(b, 10)
-    }
-
-    #[bench]
-    fn bench_from_iter_0100(b: &mut Bencher) {
-        do_bench_from_iter(b, 100)
-    }
-
-    #[bench]
-    fn bench_from_iter_1000(b: &mut Bencher) {
-        do_bench_from_iter(b, 1000)
-    }
-
-    fn do_bench_extend(b: &mut Bencher, dst_len: usize, src_len: usize) {
-        let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
-        let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
-
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let mut dst = dst.clone();
-            dst.extend(src.clone().into_iter());
-            assert_eq!(dst.len(), dst_len + src_len);
-            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
-        });
-    }
-
-    #[bench]
-    fn bench_extend_0000_0000(b: &mut Bencher) {
-        do_bench_extend(b, 0, 0)
-    }
-
-    #[bench]
-    fn bench_extend_0000_0010(b: &mut Bencher) {
-        do_bench_extend(b, 0, 10)
-    }
-
-    #[bench]
-    fn bench_extend_0000_0100(b: &mut Bencher) {
-        do_bench_extend(b, 0, 100)
-    }
-
-    #[bench]
-    fn bench_extend_0000_1000(b: &mut Bencher) {
-        do_bench_extend(b, 0, 1000)
-    }
-
-    #[bench]
-    fn bench_extend_0010_0010(b: &mut Bencher) {
-        do_bench_extend(b, 10, 10)
-    }
-
-    #[bench]
-    fn bench_extend_0100_0100(b: &mut Bencher) {
-        do_bench_extend(b, 100, 100)
-    }
-
-    #[bench]
-    fn bench_extend_1000_1000(b: &mut Bencher) {
-        do_bench_extend(b, 1000, 1000)
-    }
-
-    fn do_bench_push_all(b: &mut Bencher, dst_len: usize, src_len: usize) {
-        let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
-        let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
-
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let mut dst = dst.clone();
-            dst.push_all(&src);
-            assert_eq!(dst.len(), dst_len + src_len);
-            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
-        });
-    }
-
-    #[bench]
-    fn bench_push_all_0000_0000(b: &mut Bencher) {
-        do_bench_push_all(b, 0, 0)
-    }
-
-    #[bench]
-    fn bench_push_all_0000_0010(b: &mut Bencher) {
-        do_bench_push_all(b, 0, 10)
-    }
-
-    #[bench]
-    fn bench_push_all_0000_0100(b: &mut Bencher) {
-        do_bench_push_all(b, 0, 100)
-    }
-
-    #[bench]
-    fn bench_push_all_0000_1000(b: &mut Bencher) {
-        do_bench_push_all(b, 0, 1000)
-    }
-
-    #[bench]
-    fn bench_push_all_0010_0010(b: &mut Bencher) {
-        do_bench_push_all(b, 10, 10)
-    }
-
-    #[bench]
-    fn bench_push_all_0100_0100(b: &mut Bencher) {
-        do_bench_push_all(b, 100, 100)
-    }
-
-    #[bench]
-    fn bench_push_all_1000_1000(b: &mut Bencher) {
-        do_bench_push_all(b, 1000, 1000)
-    }
-
-    fn do_bench_push_all_move(b: &mut Bencher, dst_len: usize, src_len: usize) {
-        let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
-        let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
-
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let mut dst = dst.clone();
-            dst.extend(src.clone().into_iter());
-            assert_eq!(dst.len(), dst_len + src_len);
-            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
-        });
-    }
-
-    #[bench]
-    fn bench_push_all_move_0000_0000(b: &mut Bencher) {
-        do_bench_push_all_move(b, 0, 0)
-    }
-
-    #[bench]
-    fn bench_push_all_move_0000_0010(b: &mut Bencher) {
-        do_bench_push_all_move(b, 0, 10)
-    }
-
-    #[bench]
-    fn bench_push_all_move_0000_0100(b: &mut Bencher) {
-        do_bench_push_all_move(b, 0, 100)
-    }
-
-    #[bench]
-    fn bench_push_all_move_0000_1000(b: &mut Bencher) {
-        do_bench_push_all_move(b, 0, 1000)
-    }
-
-    #[bench]
-    fn bench_push_all_move_0010_0010(b: &mut Bencher) {
-        do_bench_push_all_move(b, 10, 10)
-    }
-
-    #[bench]
-    fn bench_push_all_move_0100_0100(b: &mut Bencher) {
-        do_bench_push_all_move(b, 100, 100)
-    }
-
-    #[bench]
-    fn bench_push_all_move_1000_1000(b: &mut Bencher) {
-        do_bench_push_all_move(b, 1000, 1000)
-    }
-
-    fn do_bench_clone(b: &mut Bencher, src_len: usize) {
-        let src: Vec<usize> = FromIterator::from_iter(0..src_len);
-
-        b.bytes = src_len as u64;
-
-        b.iter(|| {
-            let dst = src.clone();
-            assert_eq!(dst.len(), src_len);
-            assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
-        });
-    }
-
-    #[bench]
-    fn bench_clone_0000(b: &mut Bencher) {
-        do_bench_clone(b, 0)
-    }
-
-    #[bench]
-    fn bench_clone_0010(b: &mut Bencher) {
-        do_bench_clone(b, 10)
-    }
-
-    #[bench]
-    fn bench_clone_0100(b: &mut Bencher) {
-        do_bench_clone(b, 100)
-    }
-
-    #[bench]
-    fn bench_clone_1000(b: &mut Bencher) {
-        do_bench_clone(b, 1000)
-    }
-
-    fn do_bench_clone_from(b: &mut Bencher, times: usize, dst_len: usize, src_len: usize) {
-        let dst: Vec<_> = FromIterator::from_iter(0..src_len);
-        let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
-
-        b.bytes = (times * src_len) as u64;
-
-        b.iter(|| {
-            let mut dst = dst.clone();
-
-            for _ in 0..times {
-                dst.clone_from(&src);
-
-                assert_eq!(dst.len(), src_len);
-                assert!(dst.iter().enumerate().all(|(i, x)| dst_len + i == *x));
-            }
-        });
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0000_0000(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 0, 0)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0000_0010(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 0, 10)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0000_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 0, 100)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0000_1000(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 0, 1000)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0010_0010(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 10, 10)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0100_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 100, 100)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_1000_1000(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 1000, 1000)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0010_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 10, 100)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0100_1000(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 100, 1000)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0010_0000(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 10, 0)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_0100_0010(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 100, 10)
-    }
-
-    #[bench]
-    fn bench_clone_from_01_1000_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 1, 1000, 100)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0000_0000(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 0, 0)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0000_0010(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 0, 10)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0000_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 0, 100)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0000_1000(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 0, 1000)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0010_0010(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 10, 10)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0100_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 100, 100)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_1000_1000(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 1000, 1000)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0010_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 10, 100)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0100_1000(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 100, 1000)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0010_0000(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 10, 0)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_0100_0010(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 100, 10)
-    }
-
-    #[bench]
-    fn bench_clone_from_10_1000_0100(b: &mut Bencher) {
-        do_bench_clone_from(b, 10, 1000, 100)
-    }
-}
diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs
index 3e364584597..aefcad49a58 100644
--- a/src/libcollections/vec_deque.rs
+++ b/src/libcollections/vec_deque.rs
@@ -25,11 +25,12 @@ use core::default::Default;
 use core::fmt;
 use core::iter::{self, repeat, FromIterator, IntoIterator, RandomAccessIterator};
 use core::mem;
+#[cfg(stage0)]
 use core::num::{Int, UnsignedInt};
 use core::num::wrapping::WrappingOps;
 use core::ops::{Index, IndexMut};
 use core::ptr::{self, Unique};
-use core::raw::Slice as RawSlice;
+use core::slice;
 
 use core::hash::{Hash, Hasher};
 use core::cmp;
@@ -91,13 +92,13 @@ impl<T> VecDeque<T> {
     /// Turn ptr into a slice
     #[inline]
     unsafe fn buffer_as_slice(&self) -> &[T] {
-        mem::transmute(RawSlice { data: *self.ptr as *const T, len: self.cap })
+        slice::from_raw_parts(*self.ptr, self.cap)
     }
 
     /// Turn ptr into a mut slice
     #[inline]
     unsafe fn buffer_as_mut_slice(&mut self) -> &mut [T] {
-        mem::transmute(RawSlice { data: *self.ptr as *const T, len: self.cap })
+        slice::from_raw_parts_mut(*self.ptr, self.cap)
     }
 
     /// Moves an element out of the buffer
@@ -1769,138 +1770,14 @@ impl<T: fmt::Debug> fmt::Debug for VecDeque<T> {
 }
 
 #[cfg(test)]
-mod tests {
-    use self::Taggy::*;
-    use self::Taggypar::*;
-    use prelude::*;
-    use core::iter;
-    use std::fmt::Debug;
-    use std::hash::{self, SipHasher};
-    use test::Bencher;
+mod test {
+    use core::iter::{IteratorExt, self};
+    use core::option::Option::Some;
+
     use test;
 
     use super::VecDeque;
 
-    #[test]
-    #[allow(deprecated)]
-    fn test_simple() {
-        let mut d = VecDeque::new();
-        assert_eq!(d.len(), 0);
-        d.push_front(17);
-        d.push_front(42);
-        d.push_back(137);
-        assert_eq!(d.len(), 3);
-        d.push_back(137);
-        assert_eq!(d.len(), 4);
-        assert_eq!(*d.front().unwrap(), 42);
-        assert_eq!(*d.back().unwrap(), 137);
-        let mut i = d.pop_front();
-        assert_eq!(i, Some(42));
-        i = d.pop_back();
-        assert_eq!(i, Some(137));
-        i = d.pop_back();
-        assert_eq!(i, Some(137));
-        i = d.pop_back();
-        assert_eq!(i, Some(17));
-        assert_eq!(d.len(), 0);
-        d.push_back(3);
-        assert_eq!(d.len(), 1);
-        d.push_front(2);
-        assert_eq!(d.len(), 2);
-        d.push_back(4);
-        assert_eq!(d.len(), 3);
-        d.push_front(1);
-        assert_eq!(d.len(), 4);
-        debug!("{}", d[0]);
-        debug!("{}", d[1]);
-        debug!("{}", d[2]);
-        debug!("{}", d[3]);
-        assert_eq!(d[0], 1);
-        assert_eq!(d[1], 2);
-        assert_eq!(d[2], 3);
-        assert_eq!(d[3], 4);
-    }
-
-    #[cfg(test)]
-    fn test_parameterized<T:Clone + PartialEq + Debug>(a: T, b: T, c: T, d: T) {
-        let mut deq = VecDeque::new();
-        assert_eq!(deq.len(), 0);
-        deq.push_front(a.clone());
-        deq.push_front(b.clone());
-        deq.push_back(c.clone());
-        assert_eq!(deq.len(), 3);
-        deq.push_back(d.clone());
-        assert_eq!(deq.len(), 4);
-        assert_eq!((*deq.front().unwrap()).clone(), b.clone());
-        assert_eq!((*deq.back().unwrap()).clone(), d.clone());
-        assert_eq!(deq.pop_front().unwrap(), b.clone());
-        assert_eq!(deq.pop_back().unwrap(), d.clone());
-        assert_eq!(deq.pop_back().unwrap(), c.clone());
-        assert_eq!(deq.pop_back().unwrap(), a.clone());
-        assert_eq!(deq.len(), 0);
-        deq.push_back(c.clone());
-        assert_eq!(deq.len(), 1);
-        deq.push_front(b.clone());
-        assert_eq!(deq.len(), 2);
-        deq.push_back(d.clone());
-        assert_eq!(deq.len(), 3);
-        deq.push_front(a.clone());
-        assert_eq!(deq.len(), 4);
-        assert_eq!(deq[0].clone(), a.clone());
-        assert_eq!(deq[1].clone(), b.clone());
-        assert_eq!(deq[2].clone(), c.clone());
-        assert_eq!(deq[3].clone(), d.clone());
-    }
-
-    #[test]
-    fn test_push_front_grow() {
-        let mut deq = VecDeque::new();
-        for i in 0..66 {
-            deq.push_front(i);
-        }
-        assert_eq!(deq.len(), 66);
-
-        for i in 0..66 {
-            assert_eq!(deq[i], 65 - i);
-        }
-
-        let mut deq = VecDeque::new();
-        for i in 0..66 {
-            deq.push_back(i);
-        }
-
-        for i in 0..66 {
-            assert_eq!(deq[i], i);
-        }
-    }
-
-    #[test]
-    fn test_index() {
-        let mut deq = VecDeque::new();
-        for i in 1..4 {
-            deq.push_front(i);
-        }
-        assert_eq!(deq[1], 2);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_index_out_of_bounds() {
-        let mut deq = VecDeque::new();
-        for i in 1..4 {
-            deq.push_front(i);
-        }
-        deq[3];
-    }
-
-    #[bench]
-    fn bench_new(b: &mut test::Bencher) {
-        b.iter(|| {
-            let ring: VecDeque<i32> = VecDeque::new();
-            test::black_box(ring);
-        })
-    }
-
     #[bench]
     fn bench_push_back_100(b: &mut test::Bencher) {
         let mut deq = VecDeque::with_capacity(101);
@@ -1951,666 +1828,6 @@ mod tests {
         })
     }
 
-    #[bench]
-    fn bench_grow_1025(b: &mut test::Bencher) {
-        b.iter(|| {
-            let mut deq = VecDeque::new();
-            for i in 0..1025 {
-                deq.push_front(i);
-            }
-            test::black_box(deq);
-        })
-    }
-
-    #[bench]
-    fn bench_iter_1000(b: &mut test::Bencher) {
-        let ring: VecDeque<_> = (0..1000).collect();
-
-        b.iter(|| {
-            let mut sum = 0;
-            for &i in &ring {
-                sum += i;
-            }
-            test::black_box(sum);
-        })
-    }
-
-    #[bench]
-    fn bench_mut_iter_1000(b: &mut test::Bencher) {
-        let mut ring: VecDeque<_> = (0..1000).collect();
-
-        b.iter(|| {
-            let mut sum = 0;
-            for i in &mut ring {
-                sum += *i;
-            }
-            test::black_box(sum);
-        })
-    }
-
-    #[derive(Clone, PartialEq, Debug)]
-    enum Taggy {
-        One(i32),
-        Two(i32, i32),
-        Three(i32, i32, i32),
-    }
-
-    #[derive(Clone, PartialEq, Debug)]
-    enum Taggypar<T> {
-        Onepar(T),
-        Twopar(T, T),
-        Threepar(T, T, T),
-    }
-
-    #[derive(Clone, PartialEq, Debug)]
-    struct RecCy {
-        x: i32,
-        y: i32,
-        t: Taggy
-    }
-
-    #[test]
-    fn test_param_int() {
-        test_parameterized::<i32>(5, 72, 64, 175);
-    }
-
-    #[test]
-    fn test_param_taggy() {
-        test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42));
-    }
-
-    #[test]
-    fn test_param_taggypar() {
-        test_parameterized::<Taggypar<i32>>(Onepar::<i32>(1),
-                                            Twopar::<i32>(1, 2),
-                                            Threepar::<i32>(1, 2, 3),
-                                            Twopar::<i32>(17, 42));
-    }
-
-    #[test]
-    fn test_param_reccy() {
-        let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
-        let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
-        let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
-        let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
-        test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
-    }
-
-    #[test]
-    fn test_with_capacity() {
-        let mut d = VecDeque::with_capacity(0);
-        d.push_back(1);
-        assert_eq!(d.len(), 1);
-        let mut d = VecDeque::with_capacity(50);
-        d.push_back(1);
-        assert_eq!(d.len(), 1);
-    }
-
-    #[test]
-    fn test_with_capacity_non_power_two() {
-        let mut d3 = VecDeque::with_capacity(3);
-        d3.push_back(1);
-
-        // X = None, | = lo
-        // [|1, X, X]
-        assert_eq!(d3.pop_front(), Some(1));
-        // [X, |X, X]
-        assert_eq!(d3.front(), None);
-
-        // [X, |3, X]
-        d3.push_back(3);
-        // [X, |3, 6]
-        d3.push_back(6);
-        // [X, X, |6]
-        assert_eq!(d3.pop_front(), Some(3));
-
-        // Pushing the lo past half way point to trigger
-        // the 'B' scenario for growth
-        // [9, X, |6]
-        d3.push_back(9);
-        // [9, 12, |6]
-        d3.push_back(12);
-
-        d3.push_back(15);
-        // There used to be a bug here about how the
-        // VecDeque made growth assumptions about the
-        // underlying Vec which didn't hold and lead
-        // to corruption.
-        // (Vec grows to next power of two)
-        //good- [9, 12, 15, X, X, X, X, |6]
-        //bug-  [15, 12, X, X, X, |6, X, X]
-        assert_eq!(d3.pop_front(), Some(6));
-
-        // Which leads us to the following state which
-        // would be a failure case.
-        //bug-  [15, 12, X, X, X, X, |X, X]
-        assert_eq!(d3.front(), Some(&9));
-    }
-
-    #[test]
-    fn test_reserve_exact() {
-        let mut d = VecDeque::new();
-        d.push_back(0);
-        d.reserve_exact(50);
-        assert!(d.capacity() >= 51);
-    }
-
-    #[test]
-    fn test_reserve() {
-        let mut d = VecDeque::new();
-        d.push_back(0);
-        d.reserve(50);
-        assert!(d.capacity() >= 51);
-    }
-
-    #[test]
-    fn test_swap() {
-        let mut d: VecDeque<_> = (0..5).collect();
-        d.pop_front();
-        d.swap(0, 3);
-        assert_eq!(d.iter().cloned().collect::<Vec<_>>(), [4, 2, 3, 1]);
-    }
-
-    #[test]
-    fn test_iter() {
-        let mut d = VecDeque::new();
-        assert_eq!(d.iter().next(), None);
-        assert_eq!(d.iter().size_hint(), (0, Some(0)));
-
-        for i in 0..5 {
-            d.push_back(i);
-        }
-        {
-            let b: &[_] = &[&0,&1,&2,&3,&4];
-            assert_eq!(d.iter().collect::<Vec<_>>(), b);
-        }
-
-        for i in 6..9 {
-            d.push_front(i);
-        }
-        {
-            let b: &[_] = &[&8,&7,&6,&0,&1,&2,&3,&4];
-            assert_eq!(d.iter().collect::<Vec<_>>(), b);
-        }
-
-        let mut it = d.iter();
-        let mut len = d.len();
-        loop {
-            match it.next() {
-                None => break,
-                _ => { len -= 1; assert_eq!(it.size_hint(), (len, Some(len))) }
-            }
-        }
-    }
-
-    #[test]
-    fn test_rev_iter() {
-        let mut d = VecDeque::new();
-        assert_eq!(d.iter().rev().next(), None);
-
-        for i in 0..5 {
-            d.push_back(i);
-        }
-        {
-            let b: &[_] = &[&4,&3,&2,&1,&0];
-            assert_eq!(d.iter().rev().collect::<Vec<_>>(), b);
-        }
-
-        for i in 6..9 {
-            d.push_front(i);
-        }
-        let b: &[_] = &[&4,&3,&2,&1,&0,&6,&7,&8];
-        assert_eq!(d.iter().rev().collect::<Vec<_>>(), b);
-    }
-
-    #[test]
-    fn test_mut_rev_iter_wrap() {
-        let mut d = VecDeque::with_capacity(3);
-        assert!(d.iter_mut().rev().next().is_none());
-
-        d.push_back(1);
-        d.push_back(2);
-        d.push_back(3);
-        assert_eq!(d.pop_front(), Some(1));
-        d.push_back(4);
-
-        assert_eq!(d.iter_mut().rev().cloned().collect::<Vec<_>>(),
-                   vec![4, 3, 2]);
-    }
-
-    #[test]
-    fn test_mut_iter() {
-        let mut d = VecDeque::new();
-        assert!(d.iter_mut().next().is_none());
-
-        for i in 0..3 {
-            d.push_front(i);
-        }
-
-        for (i, elt) in d.iter_mut().enumerate() {
-            assert_eq!(*elt, 2 - i);
-            *elt = i;
-        }
-
-        {
-            let mut it = d.iter_mut();
-            assert_eq!(*it.next().unwrap(), 0);
-            assert_eq!(*it.next().unwrap(), 1);
-            assert_eq!(*it.next().unwrap(), 2);
-            assert!(it.next().is_none());
-        }
-    }
-
-    #[test]
-    fn test_mut_rev_iter() {
-        let mut d = VecDeque::new();
-        assert!(d.iter_mut().rev().next().is_none());
-
-        for i in 0..3 {
-            d.push_front(i);
-        }
-
-        for (i, elt) in d.iter_mut().rev().enumerate() {
-            assert_eq!(*elt, i);
-            *elt = i;
-        }
-
-        {
-            let mut it = d.iter_mut().rev();
-            assert_eq!(*it.next().unwrap(), 0);
-            assert_eq!(*it.next().unwrap(), 1);
-            assert_eq!(*it.next().unwrap(), 2);
-            assert!(it.next().is_none());
-        }
-    }
-
-    #[test]
-    fn test_into_iter() {
-
-        // Empty iter
-        {
-            let d: VecDeque<i32> = VecDeque::new();
-            let mut iter = d.into_iter();
-
-            assert_eq!(iter.size_hint(), (0, Some(0)));
-            assert_eq!(iter.next(), None);
-            assert_eq!(iter.size_hint(), (0, Some(0)));
-        }
-
-        // simple iter
-        {
-            let mut d = VecDeque::new();
-            for i in 0..5 {
-                d.push_back(i);
-            }
-
-            let b = vec![0,1,2,3,4];
-            assert_eq!(d.into_iter().collect::<Vec<_>>(), b);
-        }
-
-        // wrapped iter
-        {
-            let mut d = VecDeque::new();
-            for i in 0..5 {
-                d.push_back(i);
-            }
-            for i in 6..9 {
-                d.push_front(i);
-            }
-
-            let b = vec![8,7,6,0,1,2,3,4];
-            assert_eq!(d.into_iter().collect::<Vec<_>>(), b);
-        }
-
-        // partially used
-        {
-            let mut d = VecDeque::new();
-            for i in 0..5 {
-                d.push_back(i);
-            }
-            for i in 6..9 {
-                d.push_front(i);
-            }
-
-            let mut it = d.into_iter();
-            assert_eq!(it.size_hint(), (8, Some(8)));
-            assert_eq!(it.next(), Some(8));
-            assert_eq!(it.size_hint(), (7, Some(7)));
-            assert_eq!(it.next_back(), Some(4));
-            assert_eq!(it.size_hint(), (6, Some(6)));
-            assert_eq!(it.next(), Some(7));
-            assert_eq!(it.size_hint(), (5, Some(5)));
-        }
-    }
-
-    #[test]
-    fn test_drain() {
-
-        // Empty iter
-        {
-            let mut d: VecDeque<i32> = VecDeque::new();
-
-            {
-                let mut iter = d.drain();
-
-                assert_eq!(iter.size_hint(), (0, Some(0)));
-                assert_eq!(iter.next(), None);
-                assert_eq!(iter.size_hint(), (0, Some(0)));
-            }
-
-            assert!(d.is_empty());
-        }
-
-        // simple iter
-        {
-            let mut d = VecDeque::new();
-            for i in 0..5 {
-                d.push_back(i);
-            }
-
-            assert_eq!(d.drain().collect::<Vec<_>>(), [0, 1, 2, 3, 4]);
-            assert!(d.is_empty());
-        }
-
-        // wrapped iter
-        {
-            let mut d = VecDeque::new();
-            for i in 0..5 {
-                d.push_back(i);
-            }
-            for i in 6..9 {
-                d.push_front(i);
-            }
-
-            assert_eq!(d.drain().collect::<Vec<_>>(), [8,7,6,0,1,2,3,4]);
-            assert!(d.is_empty());
-        }
-
-        // partially used
-        {
-            let mut d: VecDeque<_> = VecDeque::new();
-            for i in 0..5 {
-                d.push_back(i);
-            }
-            for i in 6..9 {
-                d.push_front(i);
-            }
-
-            {
-                let mut it = d.drain();
-                assert_eq!(it.size_hint(), (8, Some(8)));
-                assert_eq!(it.next(), Some(8));
-                assert_eq!(it.size_hint(), (7, Some(7)));
-                assert_eq!(it.next_back(), Some(4));
-                assert_eq!(it.size_hint(), (6, Some(6)));
-                assert_eq!(it.next(), Some(7));
-                assert_eq!(it.size_hint(), (5, Some(5)));
-            }
-            assert!(d.is_empty());
-        }
-    }
-
-    #[test]
-    fn test_from_iter() {
-        use core::iter;
-        let v = vec!(1,2,3,4,5,6,7);
-        let deq: VecDeque<_> = v.iter().cloned().collect();
-        let u: Vec<_> = deq.iter().cloned().collect();
-        assert_eq!(u, v);
-
-        let seq = iter::count(0, 2).take(256);
-        let deq: VecDeque<_> = seq.collect();
-        for (i, &x) in deq.iter().enumerate() {
-            assert_eq!(2*i, x);
-        }
-        assert_eq!(deq.len(), 256);
-    }
-
-    #[test]
-    fn test_clone() {
-        let mut d = VecDeque::new();
-        d.push_front(17);
-        d.push_front(42);
-        d.push_back(137);
-        d.push_back(137);
-        assert_eq!(d.len(), 4);
-        let mut e = d.clone();
-        assert_eq!(e.len(), 4);
-        while !d.is_empty() {
-            assert_eq!(d.pop_back(), e.pop_back());
-        }
-        assert_eq!(d.len(), 0);
-        assert_eq!(e.len(), 0);
-    }
-
-    #[test]
-    fn test_eq() {
-        let mut d = VecDeque::new();
-        assert!(d == VecDeque::with_capacity(0));
-        d.push_front(137);
-        d.push_front(17);
-        d.push_front(42);
-        d.push_back(137);
-        let mut e = VecDeque::with_capacity(0);
-        e.push_back(42);
-        e.push_back(17);
-        e.push_back(137);
-        e.push_back(137);
-        assert!(&e == &d);
-        e.pop_back();
-        e.push_back(0);
-        assert!(e != d);
-        e.clear();
-        assert!(e == VecDeque::new());
-    }
-
-    #[test]
-    fn test_hash() {
-      let mut x = VecDeque::new();
-      let mut y = VecDeque::new();
-
-      x.push_back(1);
-      x.push_back(2);
-      x.push_back(3);
-
-      y.push_back(0);
-      y.push_back(1);
-      y.pop_front();
-      y.push_back(2);
-      y.push_back(3);
-
-      assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
-    }
-
-    #[test]
-    fn test_ord() {
-        let x = VecDeque::new();
-        let mut y = VecDeque::new();
-        y.push_back(1);
-        y.push_back(2);
-        y.push_back(3);
-        assert!(x < y);
-        assert!(y > x);
-        assert!(x <= x);
-        assert!(x >= x);
-    }
-
-    #[test]
-    fn test_show() {
-        let ringbuf: VecDeque<_> = (0..10).collect();
-        assert_eq!(format!("{:?}", ringbuf), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
-
-        let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"].iter()
-                                                                        .cloned()
-                                                                        .collect();
-        assert_eq!(format!("{:?}", ringbuf), "[\"just\", \"one\", \"test\", \"more\"]");
-    }
-
-    #[test]
-    fn test_drop() {
-        static mut drops: i32 = 0;
-        struct Elem;
-        impl Drop for Elem {
-            fn drop(&mut self) {
-                unsafe { drops += 1; }
-            }
-        }
-
-        let mut ring = VecDeque::new();
-        ring.push_back(Elem);
-        ring.push_front(Elem);
-        ring.push_back(Elem);
-        ring.push_front(Elem);
-        drop(ring);
-
-        assert_eq!(unsafe {drops}, 4);
-    }
-
-    #[test]
-    fn test_drop_with_pop() {
-        static mut drops: i32 = 0;
-        struct Elem;
-        impl Drop for Elem {
-            fn drop(&mut self) {
-                unsafe { drops += 1; }
-            }
-        }
-
-        let mut ring = VecDeque::new();
-        ring.push_back(Elem);
-        ring.push_front(Elem);
-        ring.push_back(Elem);
-        ring.push_front(Elem);
-
-        drop(ring.pop_back());
-        drop(ring.pop_front());
-        assert_eq!(unsafe {drops}, 2);
-
-        drop(ring);
-        assert_eq!(unsafe {drops}, 4);
-    }
-
-    #[test]
-    fn test_drop_clear() {
-        static mut drops: i32 = 0;
-        struct Elem;
-        impl Drop for Elem {
-            fn drop(&mut self) {
-                unsafe { drops += 1; }
-            }
-        }
-
-        let mut ring = VecDeque::new();
-        ring.push_back(Elem);
-        ring.push_front(Elem);
-        ring.push_back(Elem);
-        ring.push_front(Elem);
-        ring.clear();
-        assert_eq!(unsafe {drops}, 4);
-
-        drop(ring);
-        assert_eq!(unsafe {drops}, 4);
-    }
-
-    #[test]
-    fn test_reserve_grow() {
-        // test growth path A
-        // [T o o H] -> [T o o H . . . . ]
-        let mut ring = VecDeque::with_capacity(4);
-        for i in 0..3 {
-            ring.push_back(i);
-        }
-        ring.reserve(7);
-        for i in 0..3 {
-            assert_eq!(ring.pop_front(), Some(i));
-        }
-
-        // test growth path B
-        // [H T o o] -> [. T o o H . . . ]
-        let mut ring = VecDeque::with_capacity(4);
-        for i in 0..1 {
-            ring.push_back(i);
-            assert_eq!(ring.pop_front(), Some(i));
-        }
-        for i in 0..3 {
-            ring.push_back(i);
-        }
-        ring.reserve(7);
-        for i in 0..3 {
-            assert_eq!(ring.pop_front(), Some(i));
-        }
-
-        // test growth path C
-        // [o o H T] -> [o o H . . . . T ]
-        let mut ring = VecDeque::with_capacity(4);
-        for i in 0..3 {
-            ring.push_back(i);
-            assert_eq!(ring.pop_front(), Some(i));
-        }
-        for i in 0..3 {
-            ring.push_back(i);
-        }
-        ring.reserve(7);
-        for i in 0..3 {
-            assert_eq!(ring.pop_front(), Some(i));
-        }
-    }
-
-    #[test]
-    fn test_get() {
-        let mut ring = VecDeque::new();
-        ring.push_back(0);
-        assert_eq!(ring.get(0), Some(&0));
-        assert_eq!(ring.get(1), None);
-
-        ring.push_back(1);
-        assert_eq!(ring.get(0), Some(&0));
-        assert_eq!(ring.get(1), Some(&1));
-        assert_eq!(ring.get(2), None);
-
-        ring.push_back(2);
-        assert_eq!(ring.get(0), Some(&0));
-        assert_eq!(ring.get(1), Some(&1));
-        assert_eq!(ring.get(2), Some(&2));
-        assert_eq!(ring.get(3), None);
-
-        assert_eq!(ring.pop_front(), Some(0));
-        assert_eq!(ring.get(0), Some(&1));
-        assert_eq!(ring.get(1), Some(&2));
-        assert_eq!(ring.get(2), None);
-
-        assert_eq!(ring.pop_front(), Some(1));
-        assert_eq!(ring.get(0), Some(&2));
-        assert_eq!(ring.get(1), None);
-
-        assert_eq!(ring.pop_front(), Some(2));
-        assert_eq!(ring.get(0), None);
-        assert_eq!(ring.get(1), None);
-    }
-
-    #[test]
-    fn test_get_mut() {
-        let mut ring = VecDeque::new();
-        for i in 0..3 {
-            ring.push_back(i);
-        }
-
-        match ring.get_mut(1) {
-            Some(x) => *x = -1,
-            None => ()
-        };
-
-        assert_eq!(ring.get_mut(0), Some(&mut 0));
-        assert_eq!(ring.get_mut(1), Some(&mut -1));
-        assert_eq!(ring.get_mut(2), Some(&mut 2));
-        assert_eq!(ring.get_mut(3), None);
-
-        assert_eq!(ring.pop_front(), Some(0));
-        assert_eq!(ring.get_mut(0), Some(&mut -1));
-        assert_eq!(ring.get_mut(1), Some(&mut 2));
-        assert_eq!(ring.get_mut(2), None);
-    }
-
     #[test]
     fn test_swap_front_back_remove() {
         fn test(back: bool) {
@@ -2759,74 +1976,6 @@ mod tests {
     }
 
     #[test]
-    fn test_front() {
-        let mut ring = VecDeque::new();
-        ring.push_back(10);
-        ring.push_back(20);
-        assert_eq!(ring.front(), Some(&10));
-        ring.pop_front();
-        assert_eq!(ring.front(), Some(&20));
-        ring.pop_front();
-        assert_eq!(ring.front(), None);
-    }
-
-    #[test]
-    fn test_as_slices() {
-        let mut ring: VecDeque<i32> = VecDeque::with_capacity(127);
-        let cap = ring.capacity() as i32;
-        let first = cap/2;
-        let last  = cap - first;
-        for i in 0..first {
-            ring.push_back(i);
-
-            let (left, right) = ring.as_slices();
-            let expected: Vec<_> = (0..i+1).collect();
-            assert_eq!(left, expected);
-            assert_eq!(right, []);
-        }
-
-        for j in -last..0 {
-            ring.push_front(j);
-            let (left, right) = ring.as_slices();
-            let expected_left: Vec<_> = (-last..j+1).rev().collect();
-            let expected_right: Vec<_> = (0..first).collect();
-            assert_eq!(left, expected_left);
-            assert_eq!(right, expected_right);
-        }
-
-        assert_eq!(ring.len() as i32, cap);
-        assert_eq!(ring.capacity() as i32, cap);
-    }
-
-    #[test]
-    fn test_as_mut_slices() {
-        let mut ring: VecDeque<i32> = VecDeque::with_capacity(127);
-        let cap = ring.capacity() as i32;
-        let first = cap/2;
-        let last  = cap - first;
-        for i in 0..first {
-            ring.push_back(i);
-
-            let (left, right) = ring.as_mut_slices();
-            let expected: Vec<_> = (0..i+1).collect();
-            assert_eq!(left, expected);
-            assert_eq!(right, []);
-        }
-
-        for j in -last..0 {
-            ring.push_front(j);
-            let (left, right) = ring.as_mut_slices();
-            let expected_left: Vec<_> = (-last..j+1).rev().collect();
-            let expected_right: Vec<_> = (0..first).collect();
-            assert_eq!(left, expected_left);
-            assert_eq!(right, expected_right);
-        }
-
-        assert_eq!(ring.len() as i32, cap);
-        assert_eq!(ring.capacity() as i32, cap);
-    }
-
-    #[test]
     fn test_split_off() {
         // This test checks that every single combination of tail position, length, and
         // split position is tested. Capacity 15 should be large enough to cover every case.
@@ -2863,25 +2012,4 @@ mod tests {
             }
         }
     }
-
-    #[test]
-    fn test_append() {
-        let mut a: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
-        let mut b: VecDeque<_> = vec![4, 5, 6].into_iter().collect();
-
-        // normal append
-        a.append(&mut b);
-        assert_eq!(a.iter().cloned().collect::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
-        assert_eq!(b.iter().cloned().collect::<Vec<_>>(), []);
-
-        // append nothing to something
-        a.append(&mut b);
-        assert_eq!(a.iter().cloned().collect::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
-        assert_eq!(b.iter().cloned().collect::<Vec<_>>(), []);
-
-        // append something to nothing
-        b.append(&mut a);
-        assert_eq!(b.iter().cloned().collect::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
-        assert_eq!(a.iter().cloned().collect::<Vec<_>>(), []);
-    }
 }
diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs
index 431c8d5df8c..6e67d876327 100644
--- a/src/libcollections/vec_map.rs
+++ b/src/libcollections/vec_map.rs
@@ -1004,510 +1004,3 @@ impl<V> Iterator for IntoIter<V> {
 impl<V> DoubleEndedIterator for IntoIter<V> {
     fn next_back(&mut self) -> Option<(usize, V)> { self.iter.next_back() }
 }
-
-#[cfg(test)]
-mod test_map {
-    use prelude::*;
-    use core::hash::{hash, SipHasher};
-
-    use super::VecMap;
-    use super::Entry::{Occupied, Vacant};
-
-    #[test]
-    fn test_get_mut() {
-        let mut m = VecMap::new();
-        assert!(m.insert(1, 12).is_none());
-        assert!(m.insert(2, 8).is_none());
-        assert!(m.insert(5, 14).is_none());
-        let new = 100;
-        match m.get_mut(&5) {
-            None => panic!(), Some(x) => *x = new
-        }
-        assert_eq!(m.get(&5), Some(&new));
-    }
-
-    #[test]
-    fn test_len() {
-        let mut map = VecMap::new();
-        assert_eq!(map.len(), 0);
-        assert!(map.is_empty());
-        assert!(map.insert(5, 20).is_none());
-        assert_eq!(map.len(), 1);
-        assert!(!map.is_empty());
-        assert!(map.insert(11, 12).is_none());
-        assert_eq!(map.len(), 2);
-        assert!(!map.is_empty());
-        assert!(map.insert(14, 22).is_none());
-        assert_eq!(map.len(), 3);
-        assert!(!map.is_empty());
-    }
-
-    #[test]
-    fn test_clear() {
-        let mut map = VecMap::new();
-        assert!(map.insert(5, 20).is_none());
-        assert!(map.insert(11, 12).is_none());
-        assert!(map.insert(14, 22).is_none());
-        map.clear();
-        assert!(map.is_empty());
-        assert!(map.get(&5).is_none());
-        assert!(map.get(&11).is_none());
-        assert!(map.get(&14).is_none());
-    }
-
-    #[test]
-    fn test_insert() {
-        let mut m = VecMap::new();
-        assert_eq!(m.insert(1, 2), None);
-        assert_eq!(m.insert(1, 3), Some(2));
-        assert_eq!(m.insert(1, 4), Some(3));
-    }
-
-    #[test]
-    fn test_remove() {
-        let mut m = VecMap::new();
-        m.insert(1, 2);
-        assert_eq!(m.remove(&1), Some(2));
-        assert_eq!(m.remove(&1), None);
-    }
-
-    #[test]
-    fn test_keys() {
-        let mut map = VecMap::new();
-        map.insert(1, 'a');
-        map.insert(2, 'b');
-        map.insert(3, 'c');
-        let keys: Vec<_> = map.keys().collect();
-        assert_eq!(keys.len(), 3);
-        assert!(keys.contains(&1));
-        assert!(keys.contains(&2));
-        assert!(keys.contains(&3));
-    }
-
-    #[test]
-    fn test_values() {
-        let mut map = VecMap::new();
-        map.insert(1, 'a');
-        map.insert(2, 'b');
-        map.insert(3, 'c');
-        let values: Vec<_> = map.values().cloned().collect();
-        assert_eq!(values.len(), 3);
-        assert!(values.contains(&'a'));
-        assert!(values.contains(&'b'));
-        assert!(values.contains(&'c'));
-    }
-
-    #[test]
-    fn test_iterator() {
-        let mut m = VecMap::new();
-
-        assert!(m.insert(0, 1).is_none());
-        assert!(m.insert(1, 2).is_none());
-        assert!(m.insert(3, 5).is_none());
-        assert!(m.insert(6, 10).is_none());
-        assert!(m.insert(10, 11).is_none());
-
-        let mut it = m.iter();
-        assert_eq!(it.size_hint(), (0, Some(11)));
-        assert_eq!(it.next().unwrap(), (0, &1));
-        assert_eq!(it.size_hint(), (0, Some(10)));
-        assert_eq!(it.next().unwrap(), (1, &2));
-        assert_eq!(it.size_hint(), (0, Some(9)));
-        assert_eq!(it.next().unwrap(), (3, &5));
-        assert_eq!(it.size_hint(), (0, Some(7)));
-        assert_eq!(it.next().unwrap(), (6, &10));
-        assert_eq!(it.size_hint(), (0, Some(4)));
-        assert_eq!(it.next().unwrap(), (10, &11));
-        assert_eq!(it.size_hint(), (0, Some(0)));
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_iterator_size_hints() {
-        let mut m = VecMap::new();
-
-        assert!(m.insert(0, 1).is_none());
-        assert!(m.insert(1, 2).is_none());
-        assert!(m.insert(3, 5).is_none());
-        assert!(m.insert(6, 10).is_none());
-        assert!(m.insert(10, 11).is_none());
-
-        assert_eq!(m.iter().size_hint(), (0, Some(11)));
-        assert_eq!(m.iter().rev().size_hint(), (0, Some(11)));
-        assert_eq!(m.iter_mut().size_hint(), (0, Some(11)));
-        assert_eq!(m.iter_mut().rev().size_hint(), (0, Some(11)));
-    }
-
-    #[test]
-    fn test_mut_iterator() {
-        let mut m = VecMap::new();
-
-        assert!(m.insert(0, 1).is_none());
-        assert!(m.insert(1, 2).is_none());
-        assert!(m.insert(3, 5).is_none());
-        assert!(m.insert(6, 10).is_none());
-        assert!(m.insert(10, 11).is_none());
-
-        for (k, v) in &mut m {
-            *v += k as isize;
-        }
-
-        let mut it = m.iter();
-        assert_eq!(it.next().unwrap(), (0, &1));
-        assert_eq!(it.next().unwrap(), (1, &3));
-        assert_eq!(it.next().unwrap(), (3, &8));
-        assert_eq!(it.next().unwrap(), (6, &16));
-        assert_eq!(it.next().unwrap(), (10, &21));
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_rev_iterator() {
-        let mut m = VecMap::new();
-
-        assert!(m.insert(0, 1).is_none());
-        assert!(m.insert(1, 2).is_none());
-        assert!(m.insert(3, 5).is_none());
-        assert!(m.insert(6, 10).is_none());
-        assert!(m.insert(10, 11).is_none());
-
-        let mut it = m.iter().rev();
-        assert_eq!(it.next().unwrap(), (10, &11));
-        assert_eq!(it.next().unwrap(), (6, &10));
-        assert_eq!(it.next().unwrap(), (3, &5));
-        assert_eq!(it.next().unwrap(), (1, &2));
-        assert_eq!(it.next().unwrap(), (0, &1));
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_mut_rev_iterator() {
-        let mut m = VecMap::new();
-
-        assert!(m.insert(0, 1).is_none());
-        assert!(m.insert(1, 2).is_none());
-        assert!(m.insert(3, 5).is_none());
-        assert!(m.insert(6, 10).is_none());
-        assert!(m.insert(10, 11).is_none());
-
-        for (k, v) in m.iter_mut().rev() {
-            *v += k as isize;
-        }
-
-        let mut it = m.iter();
-        assert_eq!(it.next().unwrap(), (0, &1));
-        assert_eq!(it.next().unwrap(), (1, &3));
-        assert_eq!(it.next().unwrap(), (3, &8));
-        assert_eq!(it.next().unwrap(), (6, &16));
-        assert_eq!(it.next().unwrap(), (10, &21));
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_move_iter() {
-        let mut m: VecMap<Box<_>> = VecMap::new();
-        m.insert(1, box 2);
-        let mut called = false;
-        for (k, v) in m {
-            assert!(!called);
-            called = true;
-            assert_eq!(k, 1);
-            assert_eq!(v, box 2);
-        }
-        assert!(called);
-    }
-
-    #[test]
-    fn test_drain_iterator() {
-        let mut map = VecMap::new();
-        map.insert(1, "a");
-        map.insert(3, "c");
-        map.insert(2, "b");
-
-        let vec: Vec<_> = map.drain().collect();
-
-        assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]);
-        assert_eq!(map.len(), 0);
-    }
-
-    #[test]
-    fn test_append() {
-        let mut a = VecMap::new();
-        a.insert(1, "a");
-        a.insert(2, "b");
-        a.insert(3, "c");
-
-        let mut b = VecMap::new();
-        b.insert(3, "d");  // Overwrite element from a
-        b.insert(4, "e");
-        b.insert(5, "f");
-
-        a.append(&mut b);
-
-        assert_eq!(a.len(), 5);
-        assert_eq!(b.len(), 0);
-        // Capacity shouldn't change for possible reuse
-        assert!(b.capacity() >= 4);
-
-        assert_eq!(a[1], "a");
-        assert_eq!(a[2], "b");
-        assert_eq!(a[3], "d");
-        assert_eq!(a[4], "e");
-        assert_eq!(a[5], "f");
-    }
-
-    #[test]
-    fn test_split_off() {
-        // Split within the key range
-        let mut a = VecMap::new();
-        a.insert(1, "a");
-        a.insert(2, "b");
-        a.insert(3, "c");
-        a.insert(4, "d");
-
-        let b = a.split_off(3);
-
-        assert_eq!(a.len(), 2);
-        assert_eq!(b.len(), 2);
-
-        assert_eq!(a[1], "a");
-        assert_eq!(a[2], "b");
-
-        assert_eq!(b[3], "c");
-        assert_eq!(b[4], "d");
-
-        // Split at 0
-        a.clear();
-        a.insert(1, "a");
-        a.insert(2, "b");
-        a.insert(3, "c");
-        a.insert(4, "d");
-
-        let b = a.split_off(0);
-
-        assert_eq!(a.len(), 0);
-        assert_eq!(b.len(), 4);
-        assert_eq!(b[1], "a");
-        assert_eq!(b[2], "b");
-        assert_eq!(b[3], "c");
-        assert_eq!(b[4], "d");
-
-        // Split behind max_key
-        a.clear();
-        a.insert(1, "a");
-        a.insert(2, "b");
-        a.insert(3, "c");
-        a.insert(4, "d");
-
-        let b = a.split_off(5);
-
-        assert_eq!(a.len(), 4);
-        assert_eq!(b.len(), 0);
-        assert_eq!(a[1], "a");
-        assert_eq!(a[2], "b");
-        assert_eq!(a[3], "c");
-        assert_eq!(a[4], "d");
-    }
-
-    #[test]
-    fn test_show() {
-        let mut map = VecMap::new();
-        let empty = VecMap::<i32>::new();
-
-        map.insert(1, 2);
-        map.insert(3, 4);
-
-        let map_str = format!("{:?}", map);
-        assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
-        assert_eq!(format!("{:?}", empty), "{}");
-    }
-
-    #[test]
-    fn test_clone() {
-        let mut a = VecMap::new();
-
-        a.insert(1, 'x');
-        a.insert(4, 'y');
-        a.insert(6, 'z');
-
-        assert!(a.clone() == a);
-    }
-
-    #[test]
-    fn test_eq() {
-        let mut a = VecMap::new();
-        let mut b = VecMap::new();
-
-        assert!(a == b);
-        assert!(a.insert(0, 5).is_none());
-        assert!(a != b);
-        assert!(b.insert(0, 4).is_none());
-        assert!(a != b);
-        assert!(a.insert(5, 19).is_none());
-        assert!(a != b);
-        assert!(!b.insert(0, 5).is_none());
-        assert!(a != b);
-        assert!(b.insert(5, 19).is_none());
-        assert!(a == b);
-
-        a = VecMap::new();
-        b = VecMap::with_capacity(1);
-        assert!(a == b);
-    }
-
-    #[test]
-    fn test_lt() {
-        let mut a = VecMap::new();
-        let mut b = VecMap::new();
-
-        assert!(!(a < b) && !(b < a));
-        assert!(b.insert(2, 5).is_none());
-        assert!(a < b);
-        assert!(a.insert(2, 7).is_none());
-        assert!(!(a < b) && b < a);
-        assert!(b.insert(1, 0).is_none());
-        assert!(b < a);
-        assert!(a.insert(0, 6).is_none());
-        assert!(a < b);
-        assert!(a.insert(6, 2).is_none());
-        assert!(a < b && !(b < a));
-    }
-
-    #[test]
-    fn test_ord() {
-        let mut a = VecMap::new();
-        let mut b = VecMap::new();
-
-        assert!(a <= b && a >= b);
-        assert!(a.insert(1, 1).is_none());
-        assert!(a > b && a >= b);
-        assert!(b < a && b <= a);
-        assert!(b.insert(2, 2).is_none());
-        assert!(b > a && b >= a);
-        assert!(a < b && a <= b);
-    }
-
-    #[test]
-    fn test_hash() {
-        let mut x = VecMap::new();
-        let mut y = VecMap::new();
-
-        assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
-        x.insert(1, 'a');
-        x.insert(2, 'b');
-        x.insert(3, 'c');
-
-        y.insert(3, 'c');
-        y.insert(2, 'b');
-        y.insert(1, 'a');
-
-        assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
-
-        x.insert(1000, 'd');
-        x.remove(&1000);
-
-        assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
-    }
-
-    #[test]
-    fn test_from_iter() {
-        let xs = vec![(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')];
-
-        let map: VecMap<_> = xs.iter().cloned().collect();
-
-        for &(k, v) in &xs {
-            assert_eq!(map.get(&k), Some(&v));
-        }
-    }
-
-    #[test]
-    fn test_index() {
-        let mut map = VecMap::new();
-
-        map.insert(1, 2);
-        map.insert(2, 1);
-        map.insert(3, 4);
-
-        assert_eq!(map[3], 4);
-    }
-
-    #[test]
-    #[should_panic]
-    fn test_index_nonexistent() {
-        let mut map = VecMap::new();
-
-        map.insert(1, 2);
-        map.insert(2, 1);
-        map.insert(3, 4);
-
-        map[4];
-    }
-
-    #[test]
-    fn test_entry(){
-        let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
-
-        let mut map: VecMap<_> = xs.iter().cloned().collect();
-
-        // Existing key (insert)
-        match map.entry(1) {
-            Vacant(_) => unreachable!(),
-            Occupied(mut view) => {
-                assert_eq!(view.get(), &10);
-                assert_eq!(view.insert(100), 10);
-            }
-        }
-        assert_eq!(map.get(&1).unwrap(), &100);
-        assert_eq!(map.len(), 6);
-
-
-        // Existing key (update)
-        match map.entry(2) {
-            Vacant(_) => unreachable!(),
-            Occupied(mut view) => {
-                let v = view.get_mut();
-                *v *= 10;
-            }
-        }
-        assert_eq!(map.get(&2).unwrap(), &200);
-        assert_eq!(map.len(), 6);
-
-        // Existing key (take)
-        match map.entry(3) {
-            Vacant(_) => unreachable!(),
-            Occupied(view) => {
-                assert_eq!(view.remove(), 30);
-            }
-        }
-        assert_eq!(map.get(&3), None);
-        assert_eq!(map.len(), 5);
-
-
-        // Inexistent key (insert)
-        match map.entry(10) {
-            Occupied(_) => unreachable!(),
-            Vacant(view) => {
-                assert_eq!(*view.insert(1000), 1000);
-            }
-        }
-        assert_eq!(map.get(&10).unwrap(), &1000);
-        assert_eq!(map.len(), 6);
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    use super::VecMap;
-
-    map_insert_rand_bench!{insert_rand_100,    100,    VecMap}
-    map_insert_rand_bench!{insert_rand_10_000, 10_000, VecMap}
-
-    map_insert_seq_bench!{insert_seq_100,    100,    VecMap}
-    map_insert_seq_bench!{insert_seq_10_000, 10_000, VecMap}
-
-    map_find_rand_bench!{find_rand_100,    100,    VecMap}
-    map_find_rand_bench!{find_rand_10_000, 10_000, VecMap}
-
-    map_find_seq_bench!{find_seq_100,    100,    VecMap}
-    map_find_seq_bench!{find_seq_10_000, 10_000, VecMap}
-}
diff --git a/src/libcollections/bench.rs b/src/libcollectionstest/bench.rs
index 107f6031c11..2396a577589 100644
--- a/src/libcollections/bench.rs
+++ b/src/libcollectionstest/bench.rs
@@ -66,11 +66,11 @@ macro_rules! map_find_rand_bench {
     ($name: ident, $n: expr, $map: ident) => (
         #[bench]
         pub fn $name(b: &mut ::test::Bencher) {
-            use std::rand;
             use std::iter::IteratorExt;
             use std::rand::Rng;
+            use std::rand;
+            use std::vec::Vec;
             use test::black_box;
-            use vec::Vec;
 
             let mut map = $map::new();
             let n: usize = $n;
diff --git a/src/libcollectionstest/binary_heap.rs b/src/libcollectionstest/binary_heap.rs
new file mode 100644
index 00000000000..47a366bb1e2
--- /dev/null
+++ b/src/libcollectionstest/binary_heap.rs
@@ -0,0 +1,219 @@
+// Copyright 2013-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.
+
+use std::collections::BinaryHeap;
+
+#[test]
+fn test_iterator() {
+    let data = vec![5, 9, 3];
+    let iterout = [9, 5, 3];
+    let heap = BinaryHeap::from_vec(data);
+    let mut i = 0;
+    for el in &heap {
+        assert_eq!(*el, iterout[i]);
+        i += 1;
+    }
+}
+
+#[test]
+fn test_iterator_reverse() {
+    let data = vec![5, 9, 3];
+    let iterout = vec![3, 5, 9];
+    let pq = BinaryHeap::from_vec(data);
+
+    let v: Vec<_> = pq.iter().rev().cloned().collect();
+    assert_eq!(v, iterout);
+}
+
+#[test]
+fn test_move_iter() {
+    let data = vec![5, 9, 3];
+    let iterout = vec![9, 5, 3];
+    let pq = BinaryHeap::from_vec(data);
+
+    let v: Vec<_> = pq.into_iter().collect();
+    assert_eq!(v, iterout);
+}
+
+#[test]
+fn test_move_iter_size_hint() {
+    let data = vec![5, 9];
+    let pq = BinaryHeap::from_vec(data);
+
+    let mut it = pq.into_iter();
+
+    assert_eq!(it.size_hint(), (2, Some(2)));
+    assert_eq!(it.next(), Some(9));
+
+    assert_eq!(it.size_hint(), (1, Some(1)));
+    assert_eq!(it.next(), Some(5));
+
+    assert_eq!(it.size_hint(), (0, Some(0)));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_move_iter_reverse() {
+    let data = vec![5, 9, 3];
+    let iterout = vec![3, 5, 9];
+    let pq = BinaryHeap::from_vec(data);
+
+    let v: Vec<_> = pq.into_iter().rev().collect();
+    assert_eq!(v, iterout);
+}
+
+#[test]
+fn test_peek_and_pop() {
+    let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
+    let mut sorted = data.clone();
+    sorted.sort();
+    let mut heap = BinaryHeap::from_vec(data);
+    while !heap.is_empty() {
+        assert_eq!(heap.peek().unwrap(), sorted.last().unwrap());
+        assert_eq!(heap.pop().unwrap(), sorted.pop().unwrap());
+    }
+}
+
+#[test]
+fn test_push() {
+    let mut heap = BinaryHeap::from_vec(vec![2, 4, 9]);
+    assert_eq!(heap.len(), 3);
+    assert!(*heap.peek().unwrap() == 9);
+    heap.push(11);
+    assert_eq!(heap.len(), 4);
+    assert!(*heap.peek().unwrap() == 11);
+    heap.push(5);
+    assert_eq!(heap.len(), 5);
+    assert!(*heap.peek().unwrap() == 11);
+    heap.push(27);
+    assert_eq!(heap.len(), 6);
+    assert!(*heap.peek().unwrap() == 27);
+    heap.push(3);
+    assert_eq!(heap.len(), 7);
+    assert!(*heap.peek().unwrap() == 27);
+    heap.push(103);
+    assert_eq!(heap.len(), 8);
+    assert!(*heap.peek().unwrap() == 103);
+}
+
+#[test]
+fn test_push_unique() {
+    let mut heap = BinaryHeap::<Box<_>>::from_vec(vec![box 2, box 4, box 9]);
+    assert_eq!(heap.len(), 3);
+    assert!(*heap.peek().unwrap() == box 9);
+    heap.push(box 11);
+    assert_eq!(heap.len(), 4);
+    assert!(*heap.peek().unwrap() == box 11);
+    heap.push(box 5);
+    assert_eq!(heap.len(), 5);
+    assert!(*heap.peek().unwrap() == box 11);
+    heap.push(box 27);
+    assert_eq!(heap.len(), 6);
+    assert!(*heap.peek().unwrap() == box 27);
+    heap.push(box 3);
+    assert_eq!(heap.len(), 7);
+    assert!(*heap.peek().unwrap() == box 27);
+    heap.push(box 103);
+    assert_eq!(heap.len(), 8);
+    assert!(*heap.peek().unwrap() == box 103);
+}
+
+#[test]
+fn test_push_pop() {
+    let mut heap = BinaryHeap::from_vec(vec![5, 5, 2, 1, 3]);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.push_pop(6), 6);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.push_pop(0), 5);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.push_pop(4), 5);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.push_pop(1), 4);
+    assert_eq!(heap.len(), 5);
+}
+
+#[test]
+fn test_replace() {
+    let mut heap = BinaryHeap::from_vec(vec![5, 5, 2, 1, 3]);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.replace(6).unwrap(), 5);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.replace(0).unwrap(), 6);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.replace(4).unwrap(), 5);
+    assert_eq!(heap.len(), 5);
+    assert_eq!(heap.replace(1).unwrap(), 4);
+    assert_eq!(heap.len(), 5);
+}
+
+fn check_to_vec(mut data: Vec<i32>) {
+    let heap = BinaryHeap::from_vec(data.clone());
+    let mut v = heap.clone().into_vec();
+    v.sort();
+    data.sort();
+
+    assert_eq!(v, data);
+    assert_eq!(heap.into_sorted_vec(), data);
+}
+
+#[test]
+fn test_to_vec() {
+    check_to_vec(vec![]);
+    check_to_vec(vec![5]);
+    check_to_vec(vec![3, 2]);
+    check_to_vec(vec![2, 3]);
+    check_to_vec(vec![5, 1, 2]);
+    check_to_vec(vec![1, 100, 2, 3]);
+    check_to_vec(vec![1, 3, 5, 7, 9, 2, 4, 6, 8, 0]);
+    check_to_vec(vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1]);
+    check_to_vec(vec![9, 11, 9, 9, 9, 9, 11, 2, 3, 4, 11, 9, 0, 0, 0, 0]);
+    check_to_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+    check_to_vec(vec![10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]);
+    check_to_vec(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 1, 2]);
+    check_to_vec(vec![5, 4, 3, 2, 1, 5, 4, 3, 2, 1, 5, 4, 3, 2, 1]);
+}
+
+#[test]
+fn test_empty_pop() {
+    let mut heap = BinaryHeap::<i32>::new();
+    assert!(heap.pop().is_none());
+}
+
+#[test]
+fn test_empty_peek() {
+    let empty = BinaryHeap::<i32>::new();
+    assert!(empty.peek().is_none());
+}
+
+#[test]
+fn test_empty_replace() {
+    let mut heap = BinaryHeap::new();
+    assert!(heap.replace(5).is_none());
+}
+
+#[test]
+fn test_from_iter() {
+    let xs = vec![9, 8, 7, 6, 5, 4, 3, 2, 1];
+
+    let mut q: BinaryHeap<_> = xs.iter().rev().cloned().collect();
+
+    for &x in &xs {
+        assert_eq!(q.pop().unwrap(), x);
+    }
+}
+
+#[test]
+fn test_drain() {
+    let mut q: BinaryHeap<_> = [9, 8, 7, 6, 5, 4, 3, 2, 1].iter().cloned().collect();
+
+    assert_eq!(q.drain().take(5).count(), 5);
+
+    assert!(q.is_empty());
+}
diff --git a/src/libcollectionstest/bit/mod.rs b/src/libcollectionstest/bit/mod.rs
new file mode 100644
index 00000000000..8e06524f2e5
--- /dev/null
+++ b/src/libcollectionstest/bit/mod.rs
@@ -0,0 +1,12 @@
+// 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.
+
+mod set;
+mod vec;
diff --git a/src/libcollectionstest/bit/set.rs b/src/libcollectionstest/bit/set.rs
new file mode 100644
index 00000000000..4b4995d5fa7
--- /dev/null
+++ b/src/libcollectionstest/bit/set.rs
@@ -0,0 +1,441 @@
+// 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.
+
+use std::cmp::Ordering::{Equal, Greater, Less};
+use std::collections::{BitSet, BitVec};
+use std::iter::range_step;
+
+#[test]
+fn test_bit_set_show() {
+    let mut s = BitSet::new();
+    s.insert(1);
+    s.insert(10);
+    s.insert(50);
+    s.insert(2);
+    assert_eq!("{1, 2, 10, 50}", format!("{:?}", s));
+}
+
+#[test]
+fn test_bit_set_from_usizes() {
+    let usizes = vec![0, 2, 2, 3];
+    let a: BitSet = usizes.into_iter().collect();
+    let mut b = BitSet::new();
+    b.insert(0);
+    b.insert(2);
+    b.insert(3);
+    assert_eq!(a, b);
+}
+
+#[test]
+fn test_bit_set_iterator() {
+    let usizes = vec![0, 2, 2, 3];
+    let bit_vec: BitSet = usizes.into_iter().collect();
+
+    let idxs: Vec<_> = bit_vec.iter().collect();
+    assert_eq!(idxs, [0, 2, 3]);
+
+    let long: BitSet = (0..10000).filter(|&n| n % 2 == 0).collect();
+    let real: Vec<_> = range_step(0, 10000, 2).collect();
+
+    let idxs: Vec<_> = long.iter().collect();
+    assert_eq!(idxs, real);
+}
+
+#[test]
+fn test_bit_set_frombit_vec_init() {
+    let bools = [true, false];
+    let lengths = [10, 64, 100];
+    for &b in &bools {
+        for &l in &lengths {
+            let bitset = BitSet::from_bit_vec(BitVec::from_elem(l, b));
+            assert_eq!(bitset.contains(&1), b);
+            assert_eq!(bitset.contains(&(l-1)), b);
+            assert!(!bitset.contains(&l));
+        }
+    }
+}
+
+#[test]
+fn test_bit_vec_masking() {
+    let b = BitVec::from_elem(140, true);
+    let mut bs = BitSet::from_bit_vec(b);
+    assert!(bs.contains(&139));
+    assert!(!bs.contains(&140));
+    assert!(bs.insert(150));
+    assert!(!bs.contains(&140));
+    assert!(!bs.contains(&149));
+    assert!(bs.contains(&150));
+    assert!(!bs.contains(&151));
+}
+
+#[test]
+fn test_bit_set_basic() {
+    let mut b = BitSet::new();
+    assert!(b.insert(3));
+    assert!(!b.insert(3));
+    assert!(b.contains(&3));
+    assert!(b.insert(4));
+    assert!(!b.insert(4));
+    assert!(b.contains(&3));
+    assert!(b.insert(400));
+    assert!(!b.insert(400));
+    assert!(b.contains(&400));
+    assert_eq!(b.len(), 3);
+}
+
+#[test]
+fn test_bit_set_intersection() {
+    let mut a = BitSet::new();
+    let mut b = BitSet::new();
+
+    assert!(a.insert(11));
+    assert!(a.insert(1));
+    assert!(a.insert(3));
+    assert!(a.insert(77));
+    assert!(a.insert(103));
+    assert!(a.insert(5));
+
+    assert!(b.insert(2));
+    assert!(b.insert(11));
+    assert!(b.insert(77));
+    assert!(b.insert(5));
+    assert!(b.insert(3));
+
+    let expected = [3, 5, 11, 77];
+    let actual: Vec<_> = a.intersection(&b).collect();
+    assert_eq!(actual, expected);
+}
+
+#[test]
+fn test_bit_set_difference() {
+    let mut a = BitSet::new();
+    let mut b = BitSet::new();
+
+    assert!(a.insert(1));
+    assert!(a.insert(3));
+    assert!(a.insert(5));
+    assert!(a.insert(200));
+    assert!(a.insert(500));
+
+    assert!(b.insert(3));
+    assert!(b.insert(200));
+
+    let expected = [1, 5, 500];
+    let actual: Vec<_> = a.difference(&b).collect();
+    assert_eq!(actual, expected);
+}
+
+#[test]
+fn test_bit_set_symmetric_difference() {
+    let mut a = BitSet::new();
+    let mut b = BitSet::new();
+
+    assert!(a.insert(1));
+    assert!(a.insert(3));
+    assert!(a.insert(5));
+    assert!(a.insert(9));
+    assert!(a.insert(11));
+
+    assert!(b.insert(3));
+    assert!(b.insert(9));
+    assert!(b.insert(14));
+    assert!(b.insert(220));
+
+    let expected = [1, 5, 11, 14, 220];
+    let actual: Vec<_> = a.symmetric_difference(&b).collect();
+    assert_eq!(actual, expected);
+}
+
+#[test]
+fn test_bit_set_union() {
+    let mut a = BitSet::new();
+    let mut b = BitSet::new();
+    assert!(a.insert(1));
+    assert!(a.insert(3));
+    assert!(a.insert(5));
+    assert!(a.insert(9));
+    assert!(a.insert(11));
+    assert!(a.insert(160));
+    assert!(a.insert(19));
+    assert!(a.insert(24));
+    assert!(a.insert(200));
+
+    assert!(b.insert(1));
+    assert!(b.insert(5));
+    assert!(b.insert(9));
+    assert!(b.insert(13));
+    assert!(b.insert(19));
+
+    let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160, 200];
+    let actual: Vec<_> = a.union(&b).collect();
+    assert_eq!(actual, expected);
+}
+
+#[test]
+fn test_bit_set_subset() {
+    let mut set1 = BitSet::new();
+    let mut set2 = BitSet::new();
+
+    assert!(set1.is_subset(&set2)); //  {}  {}
+    set2.insert(100);
+    assert!(set1.is_subset(&set2)); //  {}  { 1 }
+    set2.insert(200);
+    assert!(set1.is_subset(&set2)); //  {}  { 1, 2 }
+    set1.insert(200);
+    assert!(set1.is_subset(&set2)); //  { 2 }  { 1, 2 }
+    set1.insert(300);
+    assert!(!set1.is_subset(&set2)); // { 2, 3 }  { 1, 2 }
+    set2.insert(300);
+    assert!(set1.is_subset(&set2)); // { 2, 3 }  { 1, 2, 3 }
+    set2.insert(400);
+    assert!(set1.is_subset(&set2)); // { 2, 3 }  { 1, 2, 3, 4 }
+    set2.remove(&100);
+    assert!(set1.is_subset(&set2)); // { 2, 3 }  { 2, 3, 4 }
+    set2.remove(&300);
+    assert!(!set1.is_subset(&set2)); // { 2, 3 }  { 2, 4 }
+    set1.remove(&300);
+    assert!(set1.is_subset(&set2)); // { 2 }  { 2, 4 }
+}
+
+#[test]
+fn test_bit_set_is_disjoint() {
+    let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01000000]));
+    let c = BitSet::new();
+    let d = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00110000]));
+
+    assert!(!a.is_disjoint(&d));
+    assert!(!d.is_disjoint(&a));
+
+    assert!(a.is_disjoint(&b));
+    assert!(a.is_disjoint(&c));
+    assert!(b.is_disjoint(&a));
+    assert!(b.is_disjoint(&c));
+    assert!(c.is_disjoint(&a));
+    assert!(c.is_disjoint(&b));
+}
+
+#[test]
+fn test_bit_set_union_with() {
+    //a should grow to include larger elements
+    let mut a = BitSet::new();
+    a.insert(0);
+    let mut b = BitSet::new();
+    b.insert(5);
+    let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100]));
+    a.union_with(&b);
+    assert_eq!(a, expected);
+
+    // Standard
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
+    let c = a.clone();
+    a.union_with(&b);
+    b.union_with(&c);
+    assert_eq!(a.len(), 4);
+    assert_eq!(b.len(), 4);
+}
+
+#[test]
+fn test_bit_set_intersect_with() {
+    // Explicitly 0'ed bits
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
+    let c = a.clone();
+    a.intersect_with(&b);
+    b.intersect_with(&c);
+    assert!(a.is_empty());
+    assert!(b.is_empty());
+
+    // Uninitialized bits should behave like 0's
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let mut b = BitSet::new();
+    let c = a.clone();
+    a.intersect_with(&b);
+    b.intersect_with(&c);
+    assert!(a.is_empty());
+    assert!(b.is_empty());
+
+    // Standard
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
+    let c = a.clone();
+    a.intersect_with(&b);
+    b.intersect_with(&c);
+    assert_eq!(a.len(), 2);
+    assert_eq!(b.len(), 2);
+}
+
+#[test]
+fn test_bit_set_difference_with() {
+    // Explicitly 0'ed bits
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
+    let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    a.difference_with(&b);
+    assert!(a.is_empty());
+
+    // Uninitialized bits should behave like 0's
+    let mut a = BitSet::new();
+    let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11111111]));
+    a.difference_with(&b);
+    assert!(a.is_empty());
+
+    // Standard
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01100010]));
+    let c = a.clone();
+    a.difference_with(&b);
+    b.difference_with(&c);
+    assert_eq!(a.len(), 1);
+    assert_eq!(b.len(), 1);
+}
+
+#[test]
+fn test_bit_set_symmetric_difference_with() {
+    //a should grow to include larger elements
+    let mut a = BitSet::new();
+    a.insert(0);
+    a.insert(1);
+    let mut b = BitSet::new();
+    b.insert(1);
+    b.insert(5);
+    let expected = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10000100]));
+    a.symmetric_difference_with(&b);
+    assert_eq!(a, expected);
+
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let b = BitSet::new();
+    let c = a.clone();
+    a.symmetric_difference_with(&b);
+    assert_eq!(a, c);
+
+    // Standard
+    let mut a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b11100010]));
+    let mut b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101010]));
+    let c = a.clone();
+    a.symmetric_difference_with(&b);
+    b.symmetric_difference_with(&c);
+    assert_eq!(a.len(), 2);
+    assert_eq!(b.len(), 2);
+}
+
+#[test]
+fn test_bit_set_eq() {
+    let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
+    let c = BitSet::new();
+
+    assert!(a == a);
+    assert!(a != b);
+    assert!(a != c);
+    assert!(b == b);
+    assert!(b == c);
+    assert!(c == c);
+}
+
+#[test]
+fn test_bit_set_cmp() {
+    let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b10100010]));
+    let b = BitSet::from_bit_vec(BitVec::from_bytes(&[0b00000000]));
+    let c = BitSet::new();
+
+    assert_eq!(a.cmp(&b), Greater);
+    assert_eq!(a.cmp(&c), Greater);
+    assert_eq!(b.cmp(&a), Less);
+    assert_eq!(b.cmp(&c), Equal);
+    assert_eq!(c.cmp(&a), Less);
+    assert_eq!(c.cmp(&b), Equal);
+}
+
+#[test]
+fn test_bit_vec_remove() {
+    let mut a = BitSet::new();
+
+    assert!(a.insert(1));
+    assert!(a.remove(&1));
+
+    assert!(a.insert(100));
+    assert!(a.remove(&100));
+
+    assert!(a.insert(1000));
+    assert!(a.remove(&1000));
+    a.shrink_to_fit();
+}
+
+#[test]
+fn test_bit_vec_clone() {
+    let mut a = BitSet::new();
+
+    assert!(a.insert(1));
+    assert!(a.insert(100));
+    assert!(a.insert(1000));
+
+    let mut b = a.clone();
+
+    assert!(a == b);
+
+    assert!(b.remove(&1));
+    assert!(a.contains(&1));
+
+    assert!(a.remove(&1000));
+    assert!(b.contains(&1000));
+}
+
+mod bench {
+    use std::collections::{BitSet, BitVec};
+    use std::rand::{Rng, self};
+    use std::u32;
+
+    use test::{Bencher, black_box};
+
+    const BENCH_BITS : usize = 1 << 14;
+
+    fn rng() -> rand::IsaacRng {
+        let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
+        rand::SeedableRng::from_seed(seed)
+    }
+
+    #[bench]
+    fn bench_bit_vecset_small(b: &mut Bencher) {
+        let mut r = rng();
+        let mut bit_vec = BitSet::new();
+        b.iter(|| {
+            for _ in 0..100 {
+                bit_vec.insert((r.next_u32() as usize) % u32::BITS as usize);
+            }
+            black_box(&bit_vec);
+        });
+    }
+
+    #[bench]
+    fn bench_bit_vecset_big(b: &mut Bencher) {
+        let mut r = rng();
+        let mut bit_vec = BitSet::new();
+        b.iter(|| {
+            for _ in 0..100 {
+                bit_vec.insert((r.next_u32() as usize) % BENCH_BITS);
+            }
+            black_box(&bit_vec);
+        });
+    }
+
+    #[bench]
+    fn bench_bit_vecset_iter(b: &mut Bencher) {
+        let bit_vec = BitSet::from_bit_vec(BitVec::from_fn(BENCH_BITS,
+                                              |idx| {idx % 3 == 0}));
+        b.iter(|| {
+            let mut sum = 0;
+            for idx in &bit_vec {
+                sum += idx as usize;
+            }
+            sum
+        })
+    }
+}
diff --git a/src/libcollectionstest/bit/vec.rs b/src/libcollectionstest/bit/vec.rs
new file mode 100644
index 00000000000..3826974d1ad
--- /dev/null
+++ b/src/libcollectionstest/bit/vec.rs
@@ -0,0 +1,729 @@
+// 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.
+
+use std::collections::BitVec;
+use std::u32;
+
+#[test]
+fn test_to_str() {
+    let zerolen = BitVec::new();
+    assert_eq!(format!("{:?}", zerolen), "");
+
+    let eightbits = BitVec::from_elem(8, false);
+    assert_eq!(format!("{:?}", eightbits), "00000000")
+}
+
+#[test]
+fn test_0_elements() {
+    let act = BitVec::new();
+    let exp = Vec::new();
+    assert!(act.eq_vec(&exp));
+    assert!(act.none() && act.all());
+}
+
+#[test]
+fn test_1_element() {
+    let mut act = BitVec::from_elem(1, false);
+    assert!(act.eq_vec(&[false]));
+    assert!(act.none() && !act.all());
+    act = BitVec::from_elem(1, true);
+    assert!(act.eq_vec(&[true]));
+    assert!(!act.none() && act.all());
+}
+
+#[test]
+fn test_2_elements() {
+    let mut b = BitVec::from_elem(2, false);
+    b.set(0, true);
+    b.set(1, false);
+    assert_eq!(format!("{:?}", b), "10");
+    assert!(!b.none() && !b.all());
+}
+
+#[test]
+fn test_10_elements() {
+    let mut act;
+    // all 0
+
+    act = BitVec::from_elem(10, false);
+    assert!((act.eq_vec(
+                &[false, false, false, false, false, false, false, false, false, false])));
+    assert!(act.none() && !act.all());
+    // all 1
+
+    act = BitVec::from_elem(10, true);
+    assert!((act.eq_vec(&[true, true, true, true, true, true, true, true, true, true])));
+    assert!(!act.none() && act.all());
+    // mixed
+
+    act = BitVec::from_elem(10, false);
+    act.set(0, true);
+    act.set(1, true);
+    act.set(2, true);
+    act.set(3, true);
+    act.set(4, true);
+    assert!((act.eq_vec(&[true, true, true, true, true, false, false, false, false, false])));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(10, false);
+    act.set(5, true);
+    act.set(6, true);
+    act.set(7, true);
+    act.set(8, true);
+    act.set(9, true);
+    assert!((act.eq_vec(&[false, false, false, false, false, true, true, true, true, true])));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(10, false);
+    act.set(0, true);
+    act.set(3, true);
+    act.set(6, true);
+    act.set(9, true);
+    assert!((act.eq_vec(&[true, false, false, true, false, false, true, false, false, true])));
+    assert!(!act.none() && !act.all());
+}
+
+#[test]
+fn test_31_elements() {
+    let mut act;
+    // all 0
+
+    act = BitVec::from_elem(31, false);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false]));
+    assert!(act.none() && !act.all());
+    // all 1
+
+    act = BitVec::from_elem(31, true);
+    assert!(act.eq_vec(
+            &[true, true, true, true, true, true, true, true, true, true, true, true, true,
+              true, true, true, true, true, true, true, true, true, true, true, true, true,
+              true, true, true, true, true]));
+    assert!(!act.none() && act.all());
+    // mixed
+
+    act = BitVec::from_elem(31, false);
+    act.set(0, true);
+    act.set(1, true);
+    act.set(2, true);
+    act.set(3, true);
+    act.set(4, true);
+    act.set(5, true);
+    act.set(6, true);
+    act.set(7, true);
+    assert!(act.eq_vec(
+            &[true, true, true, true, true, true, true, true, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(31, false);
+    act.set(16, true);
+    act.set(17, true);
+    act.set(18, true);
+    act.set(19, true);
+    act.set(20, true);
+    act.set(21, true);
+    act.set(22, true);
+    act.set(23, true);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, true, true, true, true, true, true, true, true,
+              false, false, false, false, false, false, false]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(31, false);
+    act.set(24, true);
+    act.set(25, true);
+    act.set(26, true);
+    act.set(27, true);
+    act.set(28, true);
+    act.set(29, true);
+    act.set(30, true);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, true, true, true, true, true, true, true]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(31, false);
+    act.set(3, true);
+    act.set(17, true);
+    act.set(30, true);
+    assert!(act.eq_vec(
+            &[false, false, false, true, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, true, false, false, false, false, false, false,
+              false, false, false, false, false, false, true]));
+    assert!(!act.none() && !act.all());
+}
+
+#[test]
+fn test_32_elements() {
+    let mut act;
+    // all 0
+
+    act = BitVec::from_elem(32, false);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false]));
+    assert!(act.none() && !act.all());
+    // all 1
+
+    act = BitVec::from_elem(32, true);
+    assert!(act.eq_vec(
+            &[true, true, true, true, true, true, true, true, true, true, true, true, true,
+              true, true, true, true, true, true, true, true, true, true, true, true, true,
+              true, true, true, true, true, true]));
+    assert!(!act.none() && act.all());
+    // mixed
+
+    act = BitVec::from_elem(32, false);
+    act.set(0, true);
+    act.set(1, true);
+    act.set(2, true);
+    act.set(3, true);
+    act.set(4, true);
+    act.set(5, true);
+    act.set(6, true);
+    act.set(7, true);
+    assert!(act.eq_vec(
+            &[true, true, true, true, true, true, true, true, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(32, false);
+    act.set(16, true);
+    act.set(17, true);
+    act.set(18, true);
+    act.set(19, true);
+    act.set(20, true);
+    act.set(21, true);
+    act.set(22, true);
+    act.set(23, true);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, true, true, true, true, true, true, true, true,
+              false, false, false, false, false, false, false, false]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(32, false);
+    act.set(24, true);
+    act.set(25, true);
+    act.set(26, true);
+    act.set(27, true);
+    act.set(28, true);
+    act.set(29, true);
+    act.set(30, true);
+    act.set(31, true);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, true, true, true, true, true, true, true, true]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(32, false);
+    act.set(3, true);
+    act.set(17, true);
+    act.set(30, true);
+    act.set(31, true);
+    assert!(act.eq_vec(
+            &[false, false, false, true, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, true, false, false, false, false, false, false,
+              false, false, false, false, false, false, true, true]));
+    assert!(!act.none() && !act.all());
+}
+
+#[test]
+fn test_33_elements() {
+    let mut act;
+    // all 0
+
+    act = BitVec::from_elem(33, false);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false]));
+    assert!(act.none() && !act.all());
+    // all 1
+
+    act = BitVec::from_elem(33, true);
+    assert!(act.eq_vec(
+            &[true, true, true, true, true, true, true, true, true, true, true, true, true,
+              true, true, true, true, true, true, true, true, true, true, true, true, true,
+              true, true, true, true, true, true, true]));
+    assert!(!act.none() && act.all());
+    // mixed
+
+    act = BitVec::from_elem(33, false);
+    act.set(0, true);
+    act.set(1, true);
+    act.set(2, true);
+    act.set(3, true);
+    act.set(4, true);
+    act.set(5, true);
+    act.set(6, true);
+    act.set(7, true);
+    assert!(act.eq_vec(
+            &[true, true, true, true, true, true, true, true, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(33, false);
+    act.set(16, true);
+    act.set(17, true);
+    act.set(18, true);
+    act.set(19, true);
+    act.set(20, true);
+    act.set(21, true);
+    act.set(22, true);
+    act.set(23, true);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, true, true, true, true, true, true, true, true,
+              false, false, false, false, false, false, false, false, false]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(33, false);
+    act.set(24, true);
+    act.set(25, true);
+    act.set(26, true);
+    act.set(27, true);
+    act.set(28, true);
+    act.set(29, true);
+    act.set(30, true);
+    act.set(31, true);
+    assert!(act.eq_vec(
+            &[false, false, false, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, false, false, false, false, false, false,
+              false, false, true, true, true, true, true, true, true, true, false]));
+    assert!(!act.none() && !act.all());
+    // mixed
+
+    act = BitVec::from_elem(33, false);
+    act.set(3, true);
+    act.set(17, true);
+    act.set(30, true);
+    act.set(31, true);
+    act.set(32, true);
+    assert!(act.eq_vec(
+            &[false, false, false, true, false, false, false, false, false, false, false, false,
+              false, false, false, false, false, true, false, false, false, false, false, false,
+              false, false, false, false, false, false, true, true, true]));
+    assert!(!act.none() && !act.all());
+}
+
+#[test]
+fn test_equal_differing_sizes() {
+    let v0 = BitVec::from_elem(10, false);
+    let v1 = BitVec::from_elem(11, false);
+    assert!(v0 != v1);
+}
+
+#[test]
+fn test_equal_greatly_differing_sizes() {
+    let v0 = BitVec::from_elem(10, false);
+    let v1 = BitVec::from_elem(110, false);
+    assert!(v0 != v1);
+}
+
+#[test]
+fn test_equal_sneaky_small() {
+    let mut a = BitVec::from_elem(1, false);
+    a.set(0, true);
+
+    let mut b = BitVec::from_elem(1, true);
+    b.set(0, true);
+
+    assert_eq!(a, b);
+}
+
+#[test]
+fn test_equal_sneaky_big() {
+    let mut a = BitVec::from_elem(100, false);
+    for i in 0..100 {
+        a.set(i, true);
+    }
+
+    let mut b = BitVec::from_elem(100, true);
+    for i in 0..100 {
+        b.set(i, true);
+    }
+
+    assert_eq!(a, b);
+}
+
+#[test]
+fn test_from_bytes() {
+    let bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
+    let str = concat!("10110110", "00000000", "11111111");
+    assert_eq!(format!("{:?}", bit_vec), str);
+}
+
+#[test]
+fn test_to_bytes() {
+    let mut bv = BitVec::from_elem(3, true);
+    bv.set(1, false);
+    assert_eq!(bv.to_bytes(), [0b10100000]);
+
+    let mut bv = BitVec::from_elem(9, false);
+    bv.set(2, true);
+    bv.set(8, true);
+    assert_eq!(bv.to_bytes(), [0b00100000, 0b10000000]);
+}
+
+#[test]
+fn test_from_bools() {
+    let bools = vec![true, false, true, true];
+    let bit_vec: BitVec = bools.iter().map(|n| *n).collect();
+    assert_eq!(format!("{:?}", bit_vec), "1011");
+}
+
+#[test]
+fn test_to_bools() {
+    let bools = vec![false, false, true, false, false, true, true, false];
+    assert_eq!(BitVec::from_bytes(&[0b00100110]).iter().collect::<Vec<bool>>(), bools);
+}
+
+#[test]
+fn test_bit_vec_iterator() {
+    let bools = vec![true, false, true, true];
+    let bit_vec: BitVec = bools.iter().map(|n| *n).collect();
+
+    assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), bools);
+
+    let long: Vec<_> = (0..10000).map(|i| i % 2 == 0).collect();
+    let bit_vec: BitVec = long.iter().map(|n| *n).collect();
+    assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), long)
+}
+
+#[test]
+fn test_small_difference() {
+    let mut b1 = BitVec::from_elem(3, false);
+    let mut b2 = BitVec::from_elem(3, false);
+    b1.set(0, true);
+    b1.set(1, true);
+    b2.set(1, true);
+    b2.set(2, true);
+    assert!(b1.difference(&b2));
+    assert!(b1[0]);
+    assert!(!b1[1]);
+    assert!(!b1[2]);
+}
+
+#[test]
+fn test_big_difference() {
+    let mut b1 = BitVec::from_elem(100, false);
+    let mut b2 = BitVec::from_elem(100, false);
+    b1.set(0, true);
+    b1.set(40, true);
+    b2.set(40, true);
+    b2.set(80, true);
+    assert!(b1.difference(&b2));
+    assert!(b1[0]);
+    assert!(!b1[40]);
+    assert!(!b1[80]);
+}
+
+#[test]
+fn test_small_clear() {
+    let mut b = BitVec::from_elem(14, true);
+    assert!(!b.none() && b.all());
+    b.clear();
+    assert!(b.none() && !b.all());
+}
+
+#[test]
+fn test_big_clear() {
+    let mut b = BitVec::from_elem(140, true);
+    assert!(!b.none() && b.all());
+    b.clear();
+    assert!(b.none() && !b.all());
+}
+
+#[test]
+fn test_bit_vec_lt() {
+    let mut a = BitVec::from_elem(5, false);
+    let mut b = BitVec::from_elem(5, false);
+
+    assert!(!(a < b) && !(b < a));
+    b.set(2, true);
+    assert!(a < b);
+    a.set(3, true);
+    assert!(a < b);
+    a.set(2, true);
+    assert!(!(a < b) && b < a);
+    b.set(0, true);
+    assert!(a < b);
+}
+
+#[test]
+fn test_ord() {
+    let mut a = BitVec::from_elem(5, false);
+    let mut b = BitVec::from_elem(5, false);
+
+    assert!(a <= b && a >= b);
+    a.set(1, true);
+    assert!(a > b && a >= b);
+    assert!(b < a && b <= a);
+    b.set(1, true);
+    b.set(2, true);
+    assert!(b > a && b >= a);
+    assert!(a < b && a <= b);
+}
+
+
+#[test]
+fn test_small_bit_vec_tests() {
+    let v = BitVec::from_bytes(&[0]);
+    assert!(!v.all());
+    assert!(!v.any());
+    assert!(v.none());
+
+    let v = BitVec::from_bytes(&[0b00010100]);
+    assert!(!v.all());
+    assert!(v.any());
+    assert!(!v.none());
+
+    let v = BitVec::from_bytes(&[0xFF]);
+    assert!(v.all());
+    assert!(v.any());
+    assert!(!v.none());
+}
+
+#[test]
+fn test_big_bit_vec_tests() {
+    let v = BitVec::from_bytes(&[ // 88 bits
+        0, 0, 0, 0,
+        0, 0, 0, 0,
+        0, 0, 0]);
+    assert!(!v.all());
+    assert!(!v.any());
+    assert!(v.none());
+
+    let v = BitVec::from_bytes(&[ // 88 bits
+        0, 0, 0b00010100, 0,
+        0, 0, 0, 0b00110100,
+        0, 0, 0]);
+    assert!(!v.all());
+    assert!(v.any());
+    assert!(!v.none());
+
+    let v = BitVec::from_bytes(&[ // 88 bits
+        0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF, 0xFF,
+        0xFF, 0xFF, 0xFF]);
+    assert!(v.all());
+    assert!(v.any());
+    assert!(!v.none());
+}
+
+#[test]
+fn test_bit_vec_push_pop() {
+    let mut s = BitVec::from_elem(5 * u32::BITS as usize - 2, false);
+    assert_eq!(s.len(), 5 * u32::BITS as usize - 2);
+    assert_eq!(s[5 * u32::BITS as usize - 3], false);
+    s.push(true);
+    s.push(true);
+    assert_eq!(s[5 * u32::BITS as usize - 2], true);
+    assert_eq!(s[5 * u32::BITS as usize - 1], true);
+    // Here the internal vector will need to be extended
+    s.push(false);
+    assert_eq!(s[5 * u32::BITS as usize], false);
+    s.push(false);
+    assert_eq!(s[5 * u32::BITS as usize + 1], false);
+    assert_eq!(s.len(), 5 * u32::BITS as usize + 2);
+    // Pop it all off
+    assert_eq!(s.pop(), Some(false));
+    assert_eq!(s.pop(), Some(false));
+    assert_eq!(s.pop(), Some(true));
+    assert_eq!(s.pop(), Some(true));
+    assert_eq!(s.len(), 5 * u32::BITS as usize - 2);
+}
+
+#[test]
+fn test_bit_vec_truncate() {
+    let mut s = BitVec::from_elem(5 * u32::BITS as usize, true);
+
+    assert_eq!(s, BitVec::from_elem(5 * u32::BITS as usize, true));
+    assert_eq!(s.len(), 5 * u32::BITS as usize);
+    s.truncate(4 * u32::BITS as usize);
+    assert_eq!(s, BitVec::from_elem(4 * u32::BITS as usize, true));
+    assert_eq!(s.len(), 4 * u32::BITS as usize);
+    // Truncating to a size > s.len() should be a noop
+    s.truncate(5 * u32::BITS as usize);
+    assert_eq!(s, BitVec::from_elem(4 * u32::BITS as usize, true));
+    assert_eq!(s.len(), 4 * u32::BITS as usize);
+    s.truncate(3 * u32::BITS as usize - 10);
+    assert_eq!(s, BitVec::from_elem(3 * u32::BITS as usize - 10, true));
+    assert_eq!(s.len(), 3 * u32::BITS as usize - 10);
+    s.truncate(0);
+    assert_eq!(s, BitVec::from_elem(0, true));
+    assert_eq!(s.len(), 0);
+}
+
+#[test]
+fn test_bit_vec_reserve() {
+    let mut s = BitVec::from_elem(5 * u32::BITS as usize, true);
+    // Check capacity
+    assert!(s.capacity() >= 5 * u32::BITS as usize);
+    s.reserve(2 * u32::BITS as usize);
+    assert!(s.capacity() >= 7 * u32::BITS as usize);
+    s.reserve(7 * u32::BITS as usize);
+    assert!(s.capacity() >= 12 * u32::BITS as usize);
+    s.reserve_exact(7 * u32::BITS as usize);
+    assert!(s.capacity() >= 12 * u32::BITS as usize);
+    s.reserve(7 * u32::BITS as usize + 1);
+    assert!(s.capacity() >= 12 * u32::BITS as usize + 1);
+    // Check that length hasn't changed
+    assert_eq!(s.len(), 5 * u32::BITS as usize);
+    s.push(true);
+    s.push(false);
+    s.push(true);
+    assert_eq!(s[5 * u32::BITS as usize - 1], true);
+    assert_eq!(s[5 * u32::BITS as usize - 0], true);
+    assert_eq!(s[5 * u32::BITS as usize + 1], false);
+    assert_eq!(s[5 * u32::BITS as usize + 2], true);
+}
+
+#[test]
+fn test_bit_vec_grow() {
+    let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010]);
+    bit_vec.grow(32, true);
+    assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
+                                 0xFF, 0xFF, 0xFF, 0xFF]));
+    bit_vec.grow(64, false);
+    assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
+                                 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0]));
+    bit_vec.grow(16, true);
+    assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b10101010,
+                                 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF]));
+}
+
+#[test]
+fn test_bit_vec_extend() {
+    let mut bit_vec = BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111]);
+    let ext = BitVec::from_bytes(&[0b01001001, 0b10010010, 0b10111101]);
+    bit_vec.extend(ext.iter());
+    assert_eq!(bit_vec, BitVec::from_bytes(&[0b10110110, 0b00000000, 0b11111111,
+                                 0b01001001, 0b10010010, 0b10111101]));
+}
+
+mod bench {
+    use std::collections::BitVec;
+    use std::u32;
+    use std::rand::{Rng, self};
+
+    use test::{Bencher, black_box};
+
+    const BENCH_BITS : usize = 1 << 14;
+
+    fn rng() -> rand::IsaacRng {
+        let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
+        rand::SeedableRng::from_seed(seed)
+    }
+
+    #[bench]
+    fn bench_usize_small(b: &mut Bencher) {
+        let mut r = rng();
+        let mut bit_vec = 0 as usize;
+        b.iter(|| {
+            for _ in 0..100 {
+                bit_vec |= 1 << ((r.next_u32() as usize) % u32::BITS as usize);
+            }
+            black_box(&bit_vec);
+        });
+    }
+
+    #[bench]
+    fn bench_bit_set_big_fixed(b: &mut Bencher) {
+        let mut r = rng();
+        let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
+        b.iter(|| {
+            for _ in 0..100 {
+                bit_vec.set((r.next_u32() as usize) % BENCH_BITS, true);
+            }
+            black_box(&bit_vec);
+        });
+    }
+
+    #[bench]
+    fn bench_bit_set_big_variable(b: &mut Bencher) {
+        let mut r = rng();
+        let mut bit_vec = BitVec::from_elem(BENCH_BITS, false);
+        b.iter(|| {
+            for _ in 0..100 {
+                bit_vec.set((r.next_u32() as usize) % BENCH_BITS, r.gen());
+            }
+            black_box(&bit_vec);
+        });
+    }
+
+    #[bench]
+    fn bench_bit_set_small(b: &mut Bencher) {
+        let mut r = rng();
+        let mut bit_vec = BitVec::from_elem(u32::BITS as usize, false);
+        b.iter(|| {
+            for _ in 0..100 {
+                bit_vec.set((r.next_u32() as usize) % u32::BITS as usize, true);
+            }
+            black_box(&bit_vec);
+        });
+    }
+
+    #[bench]
+    fn bench_bit_vec_big_union(b: &mut Bencher) {
+        let mut b1 = BitVec::from_elem(BENCH_BITS, false);
+        let b2 = BitVec::from_elem(BENCH_BITS, false);
+        b.iter(|| {
+            b1.union(&b2)
+        })
+    }
+
+    #[bench]
+    fn bench_bit_vec_small_iter(b: &mut Bencher) {
+        let bit_vec = BitVec::from_elem(u32::BITS as usize, false);
+        b.iter(|| {
+            let mut sum = 0;
+            for _ in 0..10 {
+                for pres in &bit_vec {
+                    sum += pres as usize;
+                }
+            }
+            sum
+        })
+    }
+
+    #[bench]
+    fn bench_bit_vec_big_iter(b: &mut Bencher) {
+        let bit_vec = BitVec::from_elem(BENCH_BITS, false);
+        b.iter(|| {
+            let mut sum = 0;
+            for pres in &bit_vec {
+                sum += pres as usize;
+            }
+            sum
+        })
+    }
+}
diff --git a/src/libcollectionstest/btree/map.rs b/src/libcollectionstest/btree/map.rs
new file mode 100644
index 00000000000..10d69c9f5ec
--- /dev/null
+++ b/src/libcollectionstest/btree/map.rs
@@ -0,0 +1,299 @@
+// 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.
+
+use std::collections::BTreeMap;
+use std::collections::Bound::{Excluded, Included, Unbounded, self};
+use std::collections::btree_map::Entry::{Occupied, Vacant};
+use std::iter::range_inclusive;
+
+#[test]
+fn test_basic_large() {
+    let mut map = BTreeMap::new();
+    let size = 10000;
+    assert_eq!(map.len(), 0);
+
+    for i in 0..size {
+        assert_eq!(map.insert(i, 10*i), None);
+        assert_eq!(map.len(), i + 1);
+    }
+
+    for i in 0..size {
+        assert_eq!(map.get(&i).unwrap(), &(i*10));
+    }
+
+    for i in size..size*2 {
+        assert_eq!(map.get(&i), None);
+    }
+
+    for i in 0..size {
+        assert_eq!(map.insert(i, 100*i), Some(10*i));
+        assert_eq!(map.len(), size);
+    }
+
+    for i in 0..size {
+        assert_eq!(map.get(&i).unwrap(), &(i*100));
+    }
+
+    for i in 0..size/2 {
+        assert_eq!(map.remove(&(i*2)), Some(i*200));
+        assert_eq!(map.len(), size - i - 1);
+    }
+
+    for i in 0..size/2 {
+        assert_eq!(map.get(&(2*i)), None);
+        assert_eq!(map.get(&(2*i+1)).unwrap(), &(i*200 + 100));
+    }
+
+    for i in 0..size/2 {
+        assert_eq!(map.remove(&(2*i)), None);
+        assert_eq!(map.remove(&(2*i+1)), Some(i*200 + 100));
+        assert_eq!(map.len(), size/2 - i - 1);
+    }
+}
+
+#[test]
+fn test_basic_small() {
+    let mut map = BTreeMap::new();
+    assert_eq!(map.remove(&1), None);
+    assert_eq!(map.get(&1), None);
+    assert_eq!(map.insert(1, 1), None);
+    assert_eq!(map.get(&1), Some(&1));
+    assert_eq!(map.insert(1, 2), Some(1));
+    assert_eq!(map.get(&1), Some(&2));
+    assert_eq!(map.insert(2, 4), None);
+    assert_eq!(map.get(&2), Some(&4));
+    assert_eq!(map.remove(&1), Some(2));
+    assert_eq!(map.remove(&2), Some(4));
+    assert_eq!(map.remove(&1), None);
+}
+
+#[test]
+fn test_iter() {
+    let size = 10000;
+
+    // Forwards
+    let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
+
+    fn test<T>(size: usize, mut iter: T) where T: Iterator<Item=(usize, usize)> {
+        for i in 0..size {
+            assert_eq!(iter.size_hint(), (size - i, Some(size - i)));
+            assert_eq!(iter.next().unwrap(), (i, i));
+        }
+        assert_eq!(iter.size_hint(), (0, Some(0)));
+        assert_eq!(iter.next(), None);
+    }
+    test(size, map.iter().map(|(&k, &v)| (k, v)));
+    test(size, map.iter_mut().map(|(&k, &mut v)| (k, v)));
+    test(size, map.into_iter());
+}
+
+#[test]
+fn test_iter_rev() {
+    let size = 10000;
+
+    // Forwards
+    let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
+
+    fn test<T>(size: usize, mut iter: T) where T: Iterator<Item=(usize, usize)> {
+        for i in 0..size {
+            assert_eq!(iter.size_hint(), (size - i, Some(size - i)));
+            assert_eq!(iter.next().unwrap(), (size - i - 1, size - i - 1));
+        }
+        assert_eq!(iter.size_hint(), (0, Some(0)));
+        assert_eq!(iter.next(), None);
+    }
+    test(size, map.iter().rev().map(|(&k, &v)| (k, v)));
+    test(size, map.iter_mut().rev().map(|(&k, &mut v)| (k, v)));
+    test(size, map.into_iter().rev());
+}
+
+#[test]
+fn test_iter_mixed() {
+    let size = 10000;
+
+    // Forwards
+    let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
+
+    fn test<T>(size: usize, mut iter: T)
+            where T: Iterator<Item=(usize, usize)> + DoubleEndedIterator {
+        for i in 0..size / 4 {
+            assert_eq!(iter.size_hint(), (size - i * 2, Some(size - i * 2)));
+            assert_eq!(iter.next().unwrap(), (i, i));
+            assert_eq!(iter.next_back().unwrap(), (size - i - 1, size - i - 1));
+        }
+        for i in size / 4..size * 3 / 4 {
+            assert_eq!(iter.size_hint(), (size * 3 / 4 - i, Some(size * 3 / 4 - i)));
+            assert_eq!(iter.next().unwrap(), (i, i));
+        }
+        assert_eq!(iter.size_hint(), (0, Some(0)));
+        assert_eq!(iter.next(), None);
+    }
+    test(size, map.iter().map(|(&k, &v)| (k, v)));
+    test(size, map.iter_mut().map(|(&k, &mut v)| (k, v)));
+    test(size, map.into_iter());
+}
+
+#[test]
+fn test_range_small() {
+    let size = 5;
+
+    // Forwards
+    let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
+
+    let mut j = 0;
+    for ((&k, &v), i) in map.range(Included(&2), Unbounded).zip(2..size) {
+        assert_eq!(k, i);
+        assert_eq!(v, i);
+        j += 1;
+    }
+    assert_eq!(j, size - 2);
+}
+
+#[test]
+fn test_range_1000() {
+    let size = 1000;
+    let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
+
+    fn test(map: &BTreeMap<u32, u32>, size: u32, min: Bound<&u32>, max: Bound<&u32>) {
+        let mut kvs = map.range(min, max).map(|(&k, &v)| (k, v));
+        let mut pairs = (0..size).map(|i| (i, i));
+
+        for (kv, pair) in kvs.by_ref().zip(pairs.by_ref()) {
+            assert_eq!(kv, pair);
+        }
+        assert_eq!(kvs.next(), None);
+        assert_eq!(pairs.next(), None);
+    }
+    test(&map, size, Included(&0), Excluded(&size));
+    test(&map, size, Unbounded, Excluded(&size));
+    test(&map, size, Included(&0), Included(&(size - 1)));
+    test(&map, size, Unbounded, Included(&(size - 1)));
+    test(&map, size, Included(&0), Unbounded);
+    test(&map, size, Unbounded, Unbounded);
+}
+
+#[test]
+fn test_range() {
+    let size = 200;
+    let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
+
+    for i in 0..size {
+        for j in i..size {
+            let mut kvs = map.range(Included(&i), Included(&j)).map(|(&k, &v)| (k, v));
+            let mut pairs = range_inclusive(i, j).map(|i| (i, i));
+
+            for (kv, pair) in kvs.by_ref().zip(pairs.by_ref()) {
+                assert_eq!(kv, pair);
+            }
+            assert_eq!(kvs.next(), None);
+            assert_eq!(pairs.next(), None);
+        }
+    }
+}
+
+#[test]
+fn test_entry(){
+    let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
+
+    let mut map: BTreeMap<_, _> = xs.iter().cloned().collect();
+
+    // Existing key (insert)
+    match map.entry(1) {
+        Vacant(_) => unreachable!(),
+        Occupied(mut view) => {
+            assert_eq!(view.get(), &10);
+            assert_eq!(view.insert(100), 10);
+        }
+    }
+    assert_eq!(map.get(&1).unwrap(), &100);
+    assert_eq!(map.len(), 6);
+
+
+    // Existing key (update)
+    match map.entry(2) {
+        Vacant(_) => unreachable!(),
+        Occupied(mut view) => {
+            let v = view.get_mut();
+            *v *= 10;
+        }
+    }
+    assert_eq!(map.get(&2).unwrap(), &200);
+    assert_eq!(map.len(), 6);
+
+    // Existing key (take)
+    match map.entry(3) {
+        Vacant(_) => unreachable!(),
+        Occupied(view) => {
+            assert_eq!(view.remove(), 30);
+        }
+    }
+    assert_eq!(map.get(&3), None);
+    assert_eq!(map.len(), 5);
+
+
+    // Inexistent key (insert)
+    match map.entry(10) {
+        Occupied(_) => unreachable!(),
+        Vacant(view) => {
+            assert_eq!(*view.insert(1000), 1000);
+        }
+    }
+    assert_eq!(map.get(&10).unwrap(), &1000);
+    assert_eq!(map.len(), 6);
+}
+
+mod bench {
+    use std::collections::BTreeMap;
+    use std::rand::{Rng, weak_rng};
+
+    use test::{Bencher, black_box};
+
+    map_insert_rand_bench!{insert_rand_100,    100,    BTreeMap}
+    map_insert_rand_bench!{insert_rand_10_000, 10_000, BTreeMap}
+
+    map_insert_seq_bench!{insert_seq_100,    100,    BTreeMap}
+    map_insert_seq_bench!{insert_seq_10_000, 10_000, BTreeMap}
+
+    map_find_rand_bench!{find_rand_100,    100,    BTreeMap}
+    map_find_rand_bench!{find_rand_10_000, 10_000, BTreeMap}
+
+    map_find_seq_bench!{find_seq_100,    100,    BTreeMap}
+    map_find_seq_bench!{find_seq_10_000, 10_000, BTreeMap}
+
+    fn bench_iter(b: &mut Bencher, size: i32) {
+        let mut map = BTreeMap::<i32, i32>::new();
+        let mut rng = weak_rng();
+
+        for _ in 0..size {
+            map.insert(rng.gen(), rng.gen());
+        }
+
+        b.iter(|| {
+            for entry in &map {
+                black_box(entry);
+            }
+        });
+    }
+
+    #[bench]
+    pub fn iter_20(b: &mut Bencher) {
+        bench_iter(b, 20);
+    }
+
+    #[bench]
+    pub fn iter_1000(b: &mut Bencher) {
+        bench_iter(b, 1000);
+    }
+
+    #[bench]
+    pub fn iter_100000(b: &mut Bencher) {
+        bench_iter(b, 100000);
+    }
+}
diff --git a/src/libcollectionstest/btree/mod.rs b/src/libcollectionstest/btree/mod.rs
new file mode 100644
index 00000000000..0db48f3ce9e
--- /dev/null
+++ b/src/libcollectionstest/btree/mod.rs
@@ -0,0 +1,12 @@
+// 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.
+
+mod map;
+mod set;
diff --git a/src/libcollectionstest/btree/set.rs b/src/libcollectionstest/btree/set.rs
new file mode 100644
index 00000000000..488f0d756d3
--- /dev/null
+++ b/src/libcollectionstest/btree/set.rs
@@ -0,0 +1,180 @@
+// 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.
+
+use std::collections::BTreeSet;
+use std::hash::{SipHasher, self};
+
+#[test]
+fn test_clone_eq() {
+  let mut m = BTreeSet::new();
+
+  m.insert(1);
+  m.insert(2);
+
+  assert!(m.clone() == m);
+}
+
+#[test]
+fn test_hash() {
+  let mut x = BTreeSet::new();
+  let mut y = BTreeSet::new();
+
+  x.insert(1);
+  x.insert(2);
+  x.insert(3);
+
+  y.insert(3);
+  y.insert(2);
+  y.insert(1);
+
+  assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
+}
+
+struct Counter<'a, 'b> {
+    i: &'a mut usize,
+    expected: &'b [i32],
+}
+
+impl<'a, 'b, 'c> FnMut<(&'c i32,)> for Counter<'a, 'b> {
+    type Output = bool;
+
+    extern "rust-call" fn call_mut(&mut self, (&x,): (&'c i32,)) -> bool {
+        assert_eq!(x, self.expected[*self.i]);
+        *self.i += 1;
+        true
+    }
+}
+
+fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F) where
+    // FIXME Replace Counter with `Box<FnMut(_) -> _>`
+    F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, Counter) -> bool,
+{
+    let mut set_a = BTreeSet::new();
+    let mut set_b = BTreeSet::new();
+
+    for x in a { assert!(set_a.insert(*x)) }
+    for y in b { assert!(set_b.insert(*y)) }
+
+    let mut i = 0;
+    f(&set_a, &set_b, Counter { i: &mut i, expected: expected });
+    assert_eq!(i, expected.len());
+}
+
+#[test]
+fn test_intersection() {
+    fn check_intersection(a: &[i32], b: &[i32], expected: &[i32]) {
+        check(a, b, expected, |x, y, f| x.intersection(y).all(f))
+    }
+
+    check_intersection(&[], &[], &[]);
+    check_intersection(&[1, 2, 3], &[], &[]);
+    check_intersection(&[], &[1, 2, 3], &[]);
+    check_intersection(&[2], &[1, 2, 3], &[2]);
+    check_intersection(&[1, 2, 3], &[2], &[2]);
+    check_intersection(&[11, 1, 3, 77, 103, 5, -5],
+                       &[2, 11, 77, -9, -42, 5, 3],
+                       &[3, 5, 11, 77]);
+}
+
+#[test]
+fn test_difference() {
+    fn check_difference(a: &[i32], b: &[i32], expected: &[i32]) {
+        check(a, b, expected, |x, y, f| x.difference(y).all(f))
+    }
+
+    check_difference(&[], &[], &[]);
+    check_difference(&[1, 12], &[], &[1, 12]);
+    check_difference(&[], &[1, 2, 3, 9], &[]);
+    check_difference(&[1, 3, 5, 9, 11],
+                     &[3, 9],
+                     &[1, 5, 11]);
+    check_difference(&[-5, 11, 22, 33, 40, 42],
+                     &[-12, -5, 14, 23, 34, 38, 39, 50],
+                     &[11, 22, 33, 40, 42]);
+}
+
+#[test]
+fn test_symmetric_difference() {
+    fn check_symmetric_difference(a: &[i32], b: &[i32], expected: &[i32]) {
+        check(a, b, expected, |x, y, f| x.symmetric_difference(y).all(f))
+    }
+
+    check_symmetric_difference(&[], &[], &[]);
+    check_symmetric_difference(&[1, 2, 3], &[2], &[1, 3]);
+    check_symmetric_difference(&[2], &[1, 2, 3], &[1, 3]);
+    check_symmetric_difference(&[1, 3, 5, 9, 11],
+                               &[-2, 3, 9, 14, 22],
+                               &[-2, 1, 5, 11, 14, 22]);
+}
+
+#[test]
+fn test_union() {
+    fn check_union(a: &[i32], b: &[i32], expected: &[i32]) {
+        check(a, b, expected, |x, y, f| x.union(y).all(f))
+    }
+
+    check_union(&[], &[], &[]);
+    check_union(&[1, 2, 3], &[2], &[1, 2, 3]);
+    check_union(&[2], &[1, 2, 3], &[1, 2, 3]);
+    check_union(&[1, 3, 5, 9, 11, 16, 19, 24],
+                &[-2, 1, 5, 9, 13, 19],
+                &[-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]);
+}
+
+#[test]
+fn test_zip() {
+    let mut x = BTreeSet::new();
+    x.insert(5);
+    x.insert(12);
+    x.insert(11);
+
+    let mut y = BTreeSet::new();
+    y.insert("foo");
+    y.insert("bar");
+
+    let x = x;
+    let y = y;
+    let mut z = x.iter().zip(y.iter());
+
+    // FIXME: #5801: this needs a type hint to compile...
+    let result: Option<(&usize, & &'static str)> = z.next();
+    assert_eq!(result.unwrap(), (&5, &("bar")));
+
+    let result: Option<(&usize, & &'static str)> = z.next();
+    assert_eq!(result.unwrap(), (&11, &("foo")));
+
+    let result: Option<(&usize, & &'static str)> = z.next();
+    assert!(result.is_none());
+}
+
+#[test]
+fn test_from_iter() {
+    let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9];
+
+    let set: BTreeSet<_> = xs.iter().cloned().collect();
+
+    for x in &xs {
+        assert!(set.contains(x));
+    }
+}
+
+#[test]
+fn test_show() {
+    let mut set = BTreeSet::new();
+    let empty = BTreeSet::<i32>::new();
+
+    set.insert(1);
+    set.insert(2);
+
+    let set_str = format!("{:?}", set);
+
+    assert_eq!(set_str, "{1, 2}");
+    assert_eq!(format!("{:?}", empty), "{}");
+}
diff --git a/src/libcollectionstest/enum_set.rs b/src/libcollectionstest/enum_set.rs
new file mode 100644
index 00000000000..f04367147cb
--- /dev/null
+++ b/src/libcollectionstest/enum_set.rs
@@ -0,0 +1,244 @@
+// Copyright 2012 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.
+
+use std::mem;
+
+use collections::enum_set::{CLike, EnumSet};
+
+use self::Foo::*;
+
+#[derive(Copy, PartialEq, Debug)]
+#[repr(usize)]
+enum Foo {
+    A, B, C
+}
+
+impl CLike for Foo {
+    fn to_usize(&self) -> usize {
+        *self as usize
+    }
+
+    fn from_usize(v: usize) -> Foo {
+        unsafe { mem::transmute(v) }
+    }
+}
+
+#[test]
+fn test_new() {
+    let e: EnumSet<Foo> = EnumSet::new();
+    assert!(e.is_empty());
+}
+
+#[test]
+fn test_show() {
+    let mut e = EnumSet::new();
+    assert!(format!("{:?}", e) == "{}");
+    e.insert(A);
+    assert!(format!("{:?}", e) == "{A}");
+    e.insert(C);
+    assert!(format!("{:?}", e) == "{A, C}");
+}
+
+#[test]
+fn test_len() {
+    let mut e = EnumSet::new();
+    assert_eq!(e.len(), 0);
+    e.insert(A);
+    e.insert(B);
+    e.insert(C);
+    assert_eq!(e.len(), 3);
+    e.remove(&A);
+    assert_eq!(e.len(), 2);
+    e.clear();
+    assert_eq!(e.len(), 0);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// intersect
+
+#[test]
+fn test_two_empties_do_not_intersect() {
+    let e1: EnumSet<Foo> = EnumSet::new();
+    let e2: EnumSet<Foo> = EnumSet::new();
+    assert!(e1.is_disjoint(&e2));
+}
+
+#[test]
+fn test_empty_does_not_intersect_with_full() {
+    let e1: EnumSet<Foo> = EnumSet::new();
+
+    let mut e2: EnumSet<Foo> = EnumSet::new();
+    e2.insert(A);
+    e2.insert(B);
+    e2.insert(C);
+
+    assert!(e1.is_disjoint(&e2));
+}
+
+#[test]
+fn test_disjoint_intersects() {
+    let mut e1: EnumSet<Foo> = EnumSet::new();
+    e1.insert(A);
+
+    let mut e2: EnumSet<Foo> = EnumSet::new();
+    e2.insert(B);
+
+    assert!(e1.is_disjoint(&e2));
+}
+
+#[test]
+fn test_overlapping_intersects() {
+    let mut e1: EnumSet<Foo> = EnumSet::new();
+    e1.insert(A);
+
+    let mut e2: EnumSet<Foo> = EnumSet::new();
+    e2.insert(A);
+    e2.insert(B);
+
+    assert!(!e1.is_disjoint(&e2));
+}
+
+///////////////////////////////////////////////////////////////////////////
+// contains and contains_elem
+
+#[test]
+fn test_superset() {
+    let mut e1: EnumSet<Foo> = EnumSet::new();
+    e1.insert(A);
+
+    let mut e2: EnumSet<Foo> = EnumSet::new();
+    e2.insert(A);
+    e2.insert(B);
+
+    let mut e3: EnumSet<Foo> = EnumSet::new();
+    e3.insert(C);
+
+    assert!(e1.is_subset(&e2));
+    assert!(e2.is_superset(&e1));
+    assert!(!e3.is_superset(&e2));
+    assert!(!e2.is_superset(&e3))
+}
+
+#[test]
+fn test_contains() {
+    let mut e1: EnumSet<Foo> = EnumSet::new();
+    e1.insert(A);
+    assert!(e1.contains(&A));
+    assert!(!e1.contains(&B));
+    assert!(!e1.contains(&C));
+
+    e1.insert(A);
+    e1.insert(B);
+    assert!(e1.contains(&A));
+    assert!(e1.contains(&B));
+    assert!(!e1.contains(&C));
+}
+
+///////////////////////////////////////////////////////////////////////////
+// iter
+
+#[test]
+fn test_iterator() {
+    let mut e1: EnumSet<Foo> = EnumSet::new();
+
+    let elems: Vec<Foo> = e1.iter().collect();
+    assert!(elems.is_empty());
+
+    e1.insert(A);
+    let elems: Vec<_> = e1.iter().collect();
+    assert_eq!([A], elems);
+
+    e1.insert(C);
+    let elems: Vec<_> = e1.iter().collect();
+    assert_eq!([A,C], elems);
+
+    e1.insert(C);
+    let elems: Vec<_> = e1.iter().collect();
+    assert_eq!([A,C], elems);
+
+    e1.insert(B);
+    let elems: Vec<_> = e1.iter().collect();
+    assert_eq!([A,B,C], elems);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// operators
+
+#[test]
+fn test_operators() {
+    let mut e1: EnumSet<Foo> = EnumSet::new();
+    e1.insert(A);
+    e1.insert(C);
+
+    let mut e2: EnumSet<Foo> = EnumSet::new();
+    e2.insert(B);
+    e2.insert(C);
+
+    let e_union = e1 | e2;
+    let elems: Vec<_> = e_union.iter().collect();
+    assert_eq!([A,B,C], elems);
+
+    let e_intersection = e1 & e2;
+    let elems: Vec<_> = e_intersection.iter().collect();
+    assert_eq!([C], elems);
+
+    // Another way to express intersection
+    let e_intersection = e1 - (e1 - e2);
+    let elems: Vec<_> = e_intersection.iter().collect();
+    assert_eq!([C], elems);
+
+    let e_subtract = e1 - e2;
+    let elems: Vec<_> = e_subtract.iter().collect();
+    assert_eq!([A], elems);
+
+    // Bitwise XOR of two sets, aka symmetric difference
+    let e_symmetric_diff = e1 ^ e2;
+    let elems: Vec<_> = e_symmetric_diff.iter().collect();
+    assert_eq!([A,B], elems);
+
+    // Another way to express symmetric difference
+    let e_symmetric_diff = (e1 - e2) | (e2 - e1);
+    let elems: Vec<_> = e_symmetric_diff.iter().collect();
+    assert_eq!([A,B], elems);
+
+    // Yet another way to express symmetric difference
+    let e_symmetric_diff = (e1 | e2) - (e1 & e2);
+    let elems: Vec<_> = e_symmetric_diff.iter().collect();
+    assert_eq!([A,B], elems);
+}
+
+#[test]
+#[should_panic]
+fn test_overflow() {
+    #[allow(dead_code)]
+    #[derive(Copy)]
+    #[repr(usize)]
+    enum Bar {
+        V00, V01, V02, V03, V04, V05, V06, V07, V08, V09,
+        V10, V11, V12, V13, V14, V15, V16, V17, V18, V19,
+        V20, V21, V22, V23, V24, V25, V26, V27, V28, V29,
+        V30, V31, V32, V33, V34, V35, V36, V37, V38, V39,
+        V40, V41, V42, V43, V44, V45, V46, V47, V48, V49,
+        V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
+        V60, V61, V62, V63, V64, V65, V66, V67, V68, V69,
+    }
+
+    impl CLike for Bar {
+        fn to_usize(&self) -> usize {
+            *self as usize
+        }
+
+        fn from_usize(v: usize) -> Bar {
+            unsafe { mem::transmute(v) }
+        }
+    }
+    let mut set = EnumSet::new();
+    set.insert(Bar::V64);
+}
diff --git a/src/libcollectionstest/fmt.rs b/src/libcollectionstest/fmt.rs
new file mode 100644
index 00000000000..9a9aa71b58b
--- /dev/null
+++ b/src/libcollectionstest/fmt.rs
@@ -0,0 +1,17 @@
+// Copyright 2013-2015 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.
+
+use std::fmt;
+
+#[test]
+fn test_format() {
+    let s = fmt::format(format_args!("Hello, {}!", "world"));
+    assert_eq!(s.as_slice(), "Hello, world!");
+}
diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs
new file mode 100644
index 00000000000..7f029340d25
--- /dev/null
+++ b/src/libcollectionstest/lib.rs
@@ -0,0 +1,43 @@
+// Copyright 2015 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.
+
+#![allow(deprecated)]
+#![feature(box_syntax)]
+#![feature(collections)]
+#![feature(core)]
+#![feature(hash)]
+#![feature(rand)]
+#![feature(rustc_private)]
+#![feature(str_words)]
+#![feature(test)]
+#![feature(unboxed_closures)]
+#![feature(unicode)]
+#![feature(unsafe_destructor)]
+
+#[macro_use] extern crate log;
+
+extern crate collections;
+extern crate test;
+extern crate unicode;
+
+#[cfg(test)] #[macro_use] mod bench;
+
+mod binary_heap;
+mod bit;
+mod btree;
+mod enum_set;
+mod fmt;
+mod linked_list;
+mod slice;
+mod str;
+mod string;
+mod vec_deque;
+mod vec_map;
+mod vec;
diff --git a/src/libcollectionstest/linked_list.rs b/src/libcollectionstest/linked_list.rs
new file mode 100644
index 00000000000..fd73938095f
--- /dev/null
+++ b/src/libcollectionstest/linked_list.rs
@@ -0,0 +1,397 @@
+// Copyright 2012-2015 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.
+
+use std::collections::LinkedList;
+use std::hash::{SipHasher, self};
+
+use test;
+
+#[test]
+fn test_basic() {
+    let mut m = LinkedList::<Box<_>>::new();
+    assert_eq!(m.pop_front(), None);
+    assert_eq!(m.pop_back(), None);
+    assert_eq!(m.pop_front(), None);
+    m.push_front(box 1);
+    assert_eq!(m.pop_front(), Some(box 1));
+    m.push_back(box 2);
+    m.push_back(box 3);
+    assert_eq!(m.len(), 2);
+    assert_eq!(m.pop_front(), Some(box 2));
+    assert_eq!(m.pop_front(), Some(box 3));
+    assert_eq!(m.len(), 0);
+    assert_eq!(m.pop_front(), None);
+    m.push_back(box 1);
+    m.push_back(box 3);
+    m.push_back(box 5);
+    m.push_back(box 7);
+    assert_eq!(m.pop_front(), Some(box 1));
+
+    let mut n = LinkedList::new();
+    n.push_front(2);
+    n.push_front(3);
+    {
+        assert_eq!(n.front().unwrap(), &3);
+        let x = n.front_mut().unwrap();
+        assert_eq!(*x, 3);
+        *x = 0;
+    }
+    {
+        assert_eq!(n.back().unwrap(), &2);
+        let y = n.back_mut().unwrap();
+        assert_eq!(*y, 2);
+        *y = 1;
+    }
+    assert_eq!(n.pop_front(), Some(0));
+    assert_eq!(n.pop_front(), Some(1));
+}
+
+#[cfg(test)]
+fn generate_test() -> LinkedList<i32> {
+    list_from(&[0,1,2,3,4,5,6])
+}
+
+#[cfg(test)]
+fn list_from<T: Clone>(v: &[T]) -> LinkedList<T> {
+    v.iter().cloned().collect()
+}
+
+#[test]
+fn test_split_off() {
+    // singleton
+    {
+        let mut m = LinkedList::new();
+        m.push_back(1);
+
+        let p = m.split_off(0);
+        assert_eq!(m.len(), 0);
+        assert_eq!(p.len(), 1);
+        assert_eq!(p.back(), Some(&1));
+        assert_eq!(p.front(), Some(&1));
+    }
+
+    // not singleton, forwards
+    {
+        let u = vec![1,2,3,4,5];
+        let mut m = list_from(&u);
+        let mut n = m.split_off(2);
+        assert_eq!(m.len(), 2);
+        assert_eq!(n.len(), 3);
+        for elt in 1..3 {
+            assert_eq!(m.pop_front(), Some(elt));
+        }
+        for elt in 3..6 {
+            assert_eq!(n.pop_front(), Some(elt));
+        }
+    }
+    // not singleton, backwards
+    {
+        let u = vec![1,2,3,4,5];
+        let mut m = list_from(&u);
+        let mut n = m.split_off(4);
+        assert_eq!(m.len(), 4);
+        assert_eq!(n.len(), 1);
+        for elt in 1..5 {
+            assert_eq!(m.pop_front(), Some(elt));
+        }
+        for elt in 5..6 {
+            assert_eq!(n.pop_front(), Some(elt));
+        }
+    }
+
+    // no-op on the last index
+    {
+        let mut m = LinkedList::new();
+        m.push_back(1);
+
+        let p = m.split_off(1);
+        assert_eq!(m.len(), 1);
+        assert_eq!(p.len(), 0);
+        assert_eq!(m.back(), Some(&1));
+        assert_eq!(m.front(), Some(&1));
+    }
+
+}
+
+#[test]
+fn test_iterator() {
+    let m = generate_test();
+    for (i, elt) in m.iter().enumerate() {
+        assert_eq!(i as i32, *elt);
+    }
+    let mut n = LinkedList::new();
+    assert_eq!(n.iter().next(), None);
+    n.push_front(4);
+    let mut it = n.iter();
+    assert_eq!(it.size_hint(), (1, Some(1)));
+    assert_eq!(it.next().unwrap(), &4);
+    assert_eq!(it.size_hint(), (0, Some(0)));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_iterator_clone() {
+    let mut n = LinkedList::new();
+    n.push_back(2);
+    n.push_back(3);
+    n.push_back(4);
+    let mut it = n.iter();
+    it.next();
+    let mut jt = it.clone();
+    assert_eq!(it.next(), jt.next());
+    assert_eq!(it.next_back(), jt.next_back());
+    assert_eq!(it.next(), jt.next());
+}
+
+#[test]
+fn test_iterator_double_end() {
+    let mut n = LinkedList::new();
+    assert_eq!(n.iter().next(), None);
+    n.push_front(4);
+    n.push_front(5);
+    n.push_front(6);
+    let mut it = n.iter();
+    assert_eq!(it.size_hint(), (3, Some(3)));
+    assert_eq!(it.next().unwrap(), &6);
+    assert_eq!(it.size_hint(), (2, Some(2)));
+    assert_eq!(it.next_back().unwrap(), &4);
+    assert_eq!(it.size_hint(), (1, Some(1)));
+    assert_eq!(it.next_back().unwrap(), &5);
+    assert_eq!(it.next_back(), None);
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_rev_iter() {
+    let m = generate_test();
+    for (i, elt) in m.iter().rev().enumerate() {
+        assert_eq!((6 - i) as i32, *elt);
+    }
+    let mut n = LinkedList::new();
+    assert_eq!(n.iter().rev().next(), None);
+    n.push_front(4);
+    let mut it = n.iter().rev();
+    assert_eq!(it.size_hint(), (1, Some(1)));
+    assert_eq!(it.next().unwrap(), &4);
+    assert_eq!(it.size_hint(), (0, Some(0)));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_mut_iter() {
+    let mut m = generate_test();
+    let mut len = m.len();
+    for (i, elt) in m.iter_mut().enumerate() {
+        assert_eq!(i as i32, *elt);
+        len -= 1;
+    }
+    assert_eq!(len, 0);
+    let mut n = LinkedList::new();
+    assert!(n.iter_mut().next().is_none());
+    n.push_front(4);
+    n.push_back(5);
+    let mut it = n.iter_mut();
+    assert_eq!(it.size_hint(), (2, Some(2)));
+    assert!(it.next().is_some());
+    assert!(it.next().is_some());
+    assert_eq!(it.size_hint(), (0, Some(0)));
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_iterator_mut_double_end() {
+    let mut n = LinkedList::new();
+    assert!(n.iter_mut().next_back().is_none());
+    n.push_front(4);
+    n.push_front(5);
+    n.push_front(6);
+    let mut it = n.iter_mut();
+    assert_eq!(it.size_hint(), (3, Some(3)));
+    assert_eq!(*it.next().unwrap(), 6);
+    assert_eq!(it.size_hint(), (2, Some(2)));
+    assert_eq!(*it.next_back().unwrap(), 4);
+    assert_eq!(it.size_hint(), (1, Some(1)));
+    assert_eq!(*it.next_back().unwrap(), 5);
+    assert!(it.next_back().is_none());
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_mut_rev_iter() {
+    let mut m = generate_test();
+    for (i, elt) in m.iter_mut().rev().enumerate() {
+        assert_eq!((6 - i) as i32, *elt);
+    }
+    let mut n = LinkedList::new();
+    assert!(n.iter_mut().rev().next().is_none());
+    n.push_front(4);
+    let mut it = n.iter_mut().rev();
+    assert!(it.next().is_some());
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_eq() {
+    let mut n = list_from(&[]);
+    let mut m = list_from(&[]);
+    assert!(n == m);
+    n.push_front(1);
+    assert!(n != m);
+    m.push_back(1);
+    assert!(n == m);
+
+    let n = list_from(&[2,3,4]);
+    let m = list_from(&[1,2,3]);
+    assert!(n != m);
+}
+
+#[test]
+fn test_hash() {
+  let mut x = LinkedList::new();
+  let mut y = LinkedList::new();
+
+  assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
+
+  x.push_back(1);
+  x.push_back(2);
+  x.push_back(3);
+
+  y.push_front(3);
+  y.push_front(2);
+  y.push_front(1);
+
+  assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
+}
+
+#[test]
+fn test_ord() {
+    let n = list_from(&[]);
+    let m = list_from(&[1,2,3]);
+    assert!(n < m);
+    assert!(m > n);
+    assert!(n <= n);
+    assert!(n >= n);
+}
+
+#[test]
+fn test_ord_nan() {
+    let nan = 0.0f64/0.0;
+    let n = list_from(&[nan]);
+    let m = list_from(&[nan]);
+    assert!(!(n < m));
+    assert!(!(n > m));
+    assert!(!(n <= m));
+    assert!(!(n >= m));
+
+    let n = list_from(&[nan]);
+    let one = list_from(&[1.0f64]);
+    assert!(!(n < one));
+    assert!(!(n > one));
+    assert!(!(n <= one));
+    assert!(!(n >= one));
+
+    let u = list_from(&[1.0f64,2.0,nan]);
+    let v = list_from(&[1.0f64,2.0,3.0]);
+    assert!(!(u < v));
+    assert!(!(u > v));
+    assert!(!(u <= v));
+    assert!(!(u >= v));
+
+    let s = list_from(&[1.0f64,2.0,4.0,2.0]);
+    let t = list_from(&[1.0f64,2.0,3.0,2.0]);
+    assert!(!(s < t));
+    assert!(s > one);
+    assert!(!(s <= one));
+    assert!(s >= one);
+}
+
+#[test]
+fn test_show() {
+    let list: LinkedList<_> = (0..10).collect();
+    assert_eq!(format!("{:?}", list), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
+
+    let list: LinkedList<_> = vec!["just", "one", "test", "more"].iter().cloned().collect();
+    assert_eq!(format!("{:?}", list), "[\"just\", \"one\", \"test\", \"more\"]");
+}
+
+#[bench]
+fn bench_collect_into(b: &mut test::Bencher) {
+    let v = &[0; 64];
+    b.iter(|| {
+        let _: LinkedList<_> = v.iter().cloned().collect();
+    })
+}
+
+#[bench]
+fn bench_push_front(b: &mut test::Bencher) {
+    let mut m: LinkedList<_> = LinkedList::new();
+    b.iter(|| {
+        m.push_front(0);
+    })
+}
+
+#[bench]
+fn bench_push_back(b: &mut test::Bencher) {
+    let mut m: LinkedList<_> = LinkedList::new();
+    b.iter(|| {
+        m.push_back(0);
+    })
+}
+
+#[bench]
+fn bench_push_back_pop_back(b: &mut test::Bencher) {
+    let mut m: LinkedList<_> = LinkedList::new();
+    b.iter(|| {
+        m.push_back(0);
+        m.pop_back();
+    })
+}
+
+#[bench]
+fn bench_push_front_pop_front(b: &mut test::Bencher) {
+    let mut m: LinkedList<_> = LinkedList::new();
+    b.iter(|| {
+        m.push_front(0);
+        m.pop_front();
+    })
+}
+
+#[bench]
+fn bench_iter(b: &mut test::Bencher) {
+    let v = &[0; 128];
+    let m: LinkedList<_> = v.iter().cloned().collect();
+    b.iter(|| {
+        assert!(m.iter().count() == 128);
+    })
+}
+#[bench]
+fn bench_iter_mut(b: &mut test::Bencher) {
+    let v = &[0; 128];
+    let mut m: LinkedList<_> = v.iter().cloned().collect();
+    b.iter(|| {
+        assert!(m.iter_mut().count() == 128);
+    })
+}
+#[bench]
+fn bench_iter_rev(b: &mut test::Bencher) {
+    let v = &[0; 128];
+    let m: LinkedList<_> = v.iter().cloned().collect();
+    b.iter(|| {
+        assert!(m.iter().rev().count() == 128);
+    })
+}
+#[bench]
+fn bench_iter_mut_rev(b: &mut test::Bencher) {
+    let v = &[0; 128];
+    let mut m: LinkedList<_> = v.iter().cloned().collect();
+    b.iter(|| {
+        assert!(m.iter_mut().rev().count() == 128);
+    })
+}
diff --git a/src/libcollectionstest/slice.rs b/src/libcollectionstest/slice.rs
new file mode 100644
index 00000000000..0c3c82eea78
--- /dev/null
+++ b/src/libcollectionstest/slice.rs
@@ -0,0 +1,1571 @@
+// Copyright 2012-2015 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.
+
+use std::cmp::Ordering::{Equal, Greater, Less};
+use std::default::Default;
+use std::iter::RandomAccessIterator;
+use std::mem;
+use std::rand::{Rng, thread_rng};
+use std::rc::Rc;
+use std::slice::ElementSwaps;
+
+fn square(n: usize) -> usize { n * n }
+
+fn is_odd(n: &usize) -> bool { *n % 2 == 1 }
+
+#[test]
+fn test_from_fn() {
+    // Test on-stack from_fn.
+    let mut v: Vec<_> = (0..3).map(square).collect();
+    {
+        let v = v;
+        assert_eq!(v.len(), 3);
+        assert_eq!(v[0], 0);
+        assert_eq!(v[1], 1);
+        assert_eq!(v[2], 4);
+    }
+
+    // Test on-heap from_fn.
+    v = (0..5).map(square).collect();
+    {
+        let v = v;
+        assert_eq!(v.len(), 5);
+        assert_eq!(v[0], 0);
+        assert_eq!(v[1], 1);
+        assert_eq!(v[2], 4);
+        assert_eq!(v[3], 9);
+        assert_eq!(v[4], 16);
+    }
+}
+
+#[test]
+fn test_from_elem() {
+    // Test on-stack from_elem.
+    let mut v = vec![10, 10];
+    {
+        let v = v;
+        assert_eq!(v.len(), 2);
+        assert_eq!(v[0], 10);
+        assert_eq!(v[1], 10);
+    }
+
+    // Test on-heap from_elem.
+    v = vec![20; 6];
+    {
+        let v = v.as_slice();
+        assert_eq!(v[0], 20);
+        assert_eq!(v[1], 20);
+        assert_eq!(v[2], 20);
+        assert_eq!(v[3], 20);
+        assert_eq!(v[4], 20);
+        assert_eq!(v[5], 20);
+    }
+}
+
+#[test]
+fn test_is_empty() {
+    let xs: [i32; 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 = vec![11];
+    assert_eq!(a.get(1), None);
+    a = vec![11, 12];
+    assert_eq!(a.get(1).unwrap(), &12);
+    a = vec![11, 12, 13];
+    assert_eq!(a.get(1).unwrap(), &12);
+}
+
+#[test]
+fn test_first() {
+    let mut a = vec![];
+    assert_eq!(a.first(), None);
+    a = vec![11];
+    assert_eq!(a.first().unwrap(), &11);
+    a = vec![11, 12];
+    assert_eq!(a.first().unwrap(), &11);
+}
+
+#[test]
+fn test_first_mut() {
+    let mut a = vec![];
+    assert_eq!(a.first_mut(), None);
+    a = vec![11];
+    assert_eq!(*a.first_mut().unwrap(), 11);
+    a = vec![11, 12];
+    assert_eq!(*a.first_mut().unwrap(), 11);
+}
+
+#[test]
+fn test_tail() {
+    let mut a = vec![11];
+    let b: &[i32] = &[];
+    assert_eq!(a.tail(), b);
+    a = vec![11, 12];
+    let b: &[i32] = &[12];
+    assert_eq!(a.tail(), b);
+}
+
+#[test]
+fn test_tail_mut() {
+    let mut a = vec![11];
+    let b: &mut [i32] = &mut [];
+    assert!(a.tail_mut() == b);
+    a = vec![11, 12];
+    let b: &mut [_] = &mut [12];
+    assert!(a.tail_mut() == b);
+}
+
+#[test]
+#[should_panic]
+fn test_tail_empty() {
+    let a = Vec::<i32>::new();
+    a.tail();
+}
+
+#[test]
+#[should_panic]
+fn test_tail_mut_empty() {
+    let mut a = Vec::<i32>::new();
+    a.tail_mut();
+}
+
+#[test]
+fn test_init() {
+    let mut a = vec![11];
+    let b: &[i32] = &[];
+    assert_eq!(a.init(), b);
+    a = vec![11, 12];
+    let b: &[_] = &[11];
+    assert_eq!(a.init(), b);
+}
+
+#[test]
+fn test_init_mut() {
+    let mut a = vec![11];
+    let b: &mut [i32] = &mut [];
+    assert!(a.init_mut() == b);
+    a = vec![11, 12];
+    let b: &mut [_] = &mut [11];
+    assert!(a.init_mut() == b);
+}
+
+#[test]
+#[should_panic]
+fn test_init_empty() {
+    let a = Vec::<i32>::new();
+    a.init();
+}
+
+#[test]
+#[should_panic]
+fn test_init_mut_empty() {
+    let mut a = Vec::<i32>::new();
+    a.init_mut();
+}
+
+#[test]
+fn test_last() {
+    let mut a = vec![];
+    assert_eq!(a.last(), None);
+    a = vec![11];
+    assert_eq!(a.last().unwrap(), &11);
+    a = vec![11, 12];
+    assert_eq!(a.last().unwrap(), &12);
+}
+
+#[test]
+fn test_last_mut() {
+    let mut a = vec![];
+    assert_eq!(a.last_mut(), None);
+    a = vec![11];
+    assert_eq!(*a.last_mut().unwrap(), 11);
+    a = vec![11, 12];
+    assert_eq!(*a.last_mut().unwrap(), 12);
+}
+
+#[test]
+fn test_slice() {
+    // Test fixed length vector.
+    let vec_fixed = [1, 2, 3, 4];
+    let v_a = vec_fixed[1..vec_fixed.len()].to_vec();
+    assert_eq!(v_a.len(), 3);
+
+    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[1..3].to_vec();
+    assert_eq!(v_b.len(), 2);
+
+    assert_eq!(v_b[0], 2);
+    assert_eq!(v_b[1], 3);
+
+    // Test `Box<[T]>`
+    let vec_unique = vec![1, 2, 3, 4, 5, 6];
+    let v_d = vec_unique[1..6].to_vec();
+    assert_eq!(v_d.len(), 5);
+
+    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[..], vec);
+    let b: &[_] = &[3, 4];
+    assert_eq!(&vec[2..], b);
+    let b: &[_] = &[];
+    assert_eq!(&vec[4..], b);
+}
+
+#[test]
+fn test_slice_to() {
+    let vec: &[_] = &[1, 2, 3, 4];
+    assert_eq!(&vec[..4], vec);
+    let b: &[_] = &[1, 2];
+    assert_eq!(&vec[..2], b);
+    let b: &[_] = &[];
+    assert_eq!(&vec[..0], b);
+}
+
+
+#[test]
+fn test_pop() {
+    let mut v = vec![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 = vec![1, 2, 3, 4, 5];
+    let mut e = v.swap_remove(0);
+    assert_eq!(e, 1);
+    assert_eq!(v, [5, 2, 3, 4]);
+    e = v.swap_remove(3);
+    assert_eq!(e, 4);
+    assert_eq!(v, [5, 2, 3]);
+}
+
+#[test]
+#[should_panic]
+fn test_swap_remove_fail() {
+    let mut v = vec![1];
+    let _ = v.swap_remove(0);
+    let _ = v.swap_remove(0);
+}
+
+#[test]
+fn test_swap_remove_noncopyable() {
+    // Tests that we don't accidentally run destructors twice.
+    let mut v: Vec<Box<_>> = Vec::new();
+    v.push(box 0u8);
+    v.push(box 0u8);
+    v.push(box 0u8);
+    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 = vec![];
+    v.push(1);
+    assert_eq!(v.len(), 1);
+    assert_eq!(v[0], 1);
+
+    // Test on-heap push().
+    v.push(2);
+    assert_eq!(v.len(), 2);
+    assert_eq!(v[0], 1);
+    assert_eq!(v[1], 2);
+}
+
+#[test]
+fn test_truncate() {
+    let mut v: Vec<Box<_>> = vec![box 6,box 5,box 4];
+    v.truncate(1);
+    let v = v;
+    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: Vec<Box<_>> = vec![box 6,box 5,box 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: Vec<i32>, b: Vec<i32>) {
+        let mut v = a;
+        v.dedup();
+        assert_eq!(v, b);
+    }
+    case(vec![], vec![]);
+    case(vec![1], vec![1]);
+    case(vec![1,1], vec![1]);
+    case(vec![1,2,3], vec![1,2,3]);
+    case(vec![1,1,2,3], vec![1,2,3]);
+    case(vec![1,2,2,3], vec![1,2,3]);
+    case(vec![1,2,3,3], vec![1,2,3]);
+    case(vec![1,1,2,2,2,3,3], vec![1,2,3]);
+}
+
+#[test]
+fn test_dedup_unique() {
+    let mut v0: Vec<Box<_>> = vec![box 1, box 1, box 2, box 3];
+    v0.dedup();
+    let mut v1: Vec<Box<_>> = vec![box 1, box 2, box 2, box 3];
+    v1.dedup();
+    let mut v2: Vec<Box<_>> = vec![box 1, box 2, box 3, box 3];
+    v2.dedup();
+    /*
+     * If the boxed pointers were leaked or otherwise misused, valgrind
+     * and/or rt should raise errors.
+     */
+}
+
+#[test]
+fn test_dedup_shared() {
+    let mut v0: Vec<Box<_>> = vec![box 1, box 1, box 2, box 3];
+    v0.dedup();
+    let mut v1: Vec<Box<_>> = vec![box 1, box 2, box 2, box 3];
+    v1.dedup();
+    let mut v2: Vec<Box<_>> = vec![box 1, box 2, box 3, box 3];
+    v2.dedup();
+    /*
+     * If the pointers were leaked or otherwise misused, valgrind and/or
+     * rt should raise errors.
+     */
+}
+
+#[test]
+fn test_retain() {
+    let mut v = vec![1, 2, 3, 4, 5];
+    v.retain(is_odd);
+    assert_eq!(v, [1, 3, 5]);
+}
+
+#[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]),
+            _ => panic!(),
+        }
+    }
+}
+
+#[test]
+fn test_lexicographic_permutations() {
+    let v : &mut[_] = &mut[1, 2, 3, 4, 5];
+    assert!(v.prev_permutation() == false);
+    assert!(v.next_permutation());
+    let b: &mut[_] = &mut[1, 2, 3, 5, 4];
+    assert!(v == b);
+    assert!(v.prev_permutation());
+    let b: &mut[_] = &mut[1, 2, 3, 4, 5];
+    assert!(v == b);
+    assert!(v.next_permutation());
+    assert!(v.next_permutation());
+    let b: &mut[_] = &mut[1, 2, 4, 3, 5];
+    assert!(v == b);
+    assert!(v.next_permutation());
+    let b: &mut[_] = &mut[1, 2, 4, 5, 3];
+    assert!(v == b);
+
+    let v : &mut[_] = &mut[1, 0, 0, 0];
+    assert!(v.next_permutation() == false);
+    assert!(v.prev_permutation());
+    let b: &mut[_] = &mut[0, 1, 0, 0];
+    assert!(v == b);
+    assert!(v.prev_permutation());
+    let b: &mut[_] = &mut[0, 0, 1, 0];
+    assert!(v == b);
+    assert!(v.prev_permutation());
+    let b: &mut[_] = &mut[0, 0, 0, 1];
+    assert!(v == b);
+    assert!(v.prev_permutation() == false);
+}
+
+#[test]
+fn test_lexicographic_permutations_empty_and_short() {
+    let empty : &mut[i32] = &mut[];
+    assert!(empty.next_permutation() == false);
+    let b: &mut[i32] = &mut[];
+    assert!(empty == b);
+    assert!(empty.prev_permutation() == false);
+    assert!(empty == b);
+
+    let one_elem : &mut[_] = &mut[4];
+    assert!(one_elem.prev_permutation() == false);
+    let b: &mut[_] = &mut[4];
+    assert!(one_elem == b);
+    assert!(one_elem.next_permutation() == false);
+    assert!(one_elem == b);
+
+    let two_elem : &mut[_] = &mut[1, 2];
+    assert!(two_elem.prev_permutation() == false);
+    let b : &mut[_] = &mut[1, 2];
+    let c : &mut[_] = &mut[2, 1];
+    assert!(two_elem == b);
+    assert!(two_elem.next_permutation());
+    assert!(two_elem == c);
+    assert!(two_elem.next_permutation() == false);
+    assert!(two_elem == c);
+    assert!(two_elem.prev_permutation());
+    assert!(two_elem == b);
+    assert!(two_elem.prev_permutation() == false);
+    assert!(two_elem == b);
+}
+
+#[test]
+fn test_position_elem() {
+    assert!([].position_elem(&1).is_none());
+
+    let v1 = vec![1, 2, 3, 3, 2, 5];
+    assert_eq!(v1.position_elem(&1), Some(0));
+    assert_eq!(v1.position_elem(&2), Some(1));
+    assert_eq!(v1.position_elem(&5), Some(5));
+    assert!(v1.position_elem(&4).is_none());
+}
+
+#[test]
+fn test_binary_search() {
+    assert_eq!([1,2,3,4,5].binary_search(&5).ok(), Some(4));
+    assert_eq!([1,2,3,4,5].binary_search(&4).ok(), Some(3));
+    assert_eq!([1,2,3,4,5].binary_search(&3).ok(), Some(2));
+    assert_eq!([1,2,3,4,5].binary_search(&2).ok(), Some(1));
+    assert_eq!([1,2,3,4,5].binary_search(&1).ok(), Some(0));
+
+    assert_eq!([2,4,6,8,10].binary_search(&1).ok(), None);
+    assert_eq!([2,4,6,8,10].binary_search(&5).ok(), None);
+    assert_eq!([2,4,6,8,10].binary_search(&4).ok(), Some(1));
+    assert_eq!([2,4,6,8,10].binary_search(&10).ok(), Some(4));
+
+    assert_eq!([2,4,6,8].binary_search(&1).ok(), None);
+    assert_eq!([2,4,6,8].binary_search(&5).ok(), None);
+    assert_eq!([2,4,6,8].binary_search(&4).ok(), Some(1));
+    assert_eq!([2,4,6,8].binary_search(&8).ok(), Some(3));
+
+    assert_eq!([2,4,6].binary_search(&1).ok(), None);
+    assert_eq!([2,4,6].binary_search(&5).ok(), None);
+    assert_eq!([2,4,6].binary_search(&4).ok(), Some(1));
+    assert_eq!([2,4,6].binary_search(&6).ok(), Some(2));
+
+    assert_eq!([2,4].binary_search(&1).ok(), None);
+    assert_eq!([2,4].binary_search(&5).ok(), None);
+    assert_eq!([2,4].binary_search(&2).ok(), Some(0));
+    assert_eq!([2,4].binary_search(&4).ok(), Some(1));
+
+    assert_eq!([2].binary_search(&1).ok(), None);
+    assert_eq!([2].binary_search(&5).ok(), None);
+    assert_eq!([2].binary_search(&2).ok(), Some(0));
+
+    assert_eq!([].binary_search(&1).ok(), None);
+    assert_eq!([].binary_search(&5).ok(), None);
+
+    assert!([1,1,1,1,1].binary_search(&1).ok() != None);
+    assert!([1,1,1,1,2].binary_search(&1).ok() != None);
+    assert!([1,1,1,2,2].binary_search(&1).ok() != None);
+    assert!([1,1,2,2,2].binary_search(&1).ok() != None);
+    assert_eq!([1,2,2,2,2].binary_search(&1).ok(), Some(0));
+
+    assert_eq!([1,2,3,4,5].binary_search(&6).ok(), None);
+    assert_eq!([1,2,3,4,5].binary_search(&0).ok(), None);
+}
+
+#[test]
+fn test_reverse() {
+    let mut v = vec![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 = Vec::<i32>::new();
+    v3.reverse();
+    assert!(v3.is_empty());
+}
+
+#[test]
+fn test_sort() {
+    for len in 4..25 {
+        for _ in 0..100 {
+            let mut v: Vec<_> = thread_rng().gen_iter::<i32>().take(len).collect();
+            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 panic
+    let mut v: [i32; 0] = [];
+    v.sort();
+
+    let mut v = [0xDEADBEEFu64];
+    v.sort();
+    assert!(v == [0xDEADBEEF]);
+}
+
+#[test]
+fn test_sort_stability() {
+    for len in 4..25 {
+        for _ in 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: Vec<_> = (0..len).map(|_| {
+                    let n = thread_rng().gen::<usize>() % 10;
+                    counts[n] += 1;
+                    (n, counts[n])
+                }).collect();
+
+            // 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_concat() {
+    let v: [Vec<i32>; 0] = [];
+    let c = v.concat();
+    assert_eq!(c, []);
+    let d = [vec![1], vec![2, 3]].concat();
+    assert_eq!(d, [1, 2, 3]);
+
+    let v: &[&[_]] = &[&[1], &[2, 3]];
+    assert_eq!(v.connect(&0), [1, 0, 2, 3]);
+    let v: &[&[_]] = &[&[1], &[2], &[3]];
+    assert_eq!(v.connect(&0), [1, 0, 2, 0, 3]);
+}
+
+#[test]
+fn test_connect() {
+    let v: [Vec<i32>; 0] = [];
+    assert_eq!(v.connect(&0), []);
+    assert_eq!([vec![1], vec![2, 3]].connect(&0), [1, 0, 2, 3]);
+    assert_eq!([vec![1], vec![2], vec![3]].connect(&0), [1, 0, 2, 0, 3]);
+
+    let v: [&[_]; 2] = [&[1], &[2, 3]];
+    assert_eq!(v.connect(&0), [1, 0, 2, 3]);
+    let v: [&[_]; 3] = [&[1], &[2], &[3]];
+    assert_eq!(v.connect(&0), [1, 0, 2, 0, 3]);
+}
+
+#[test]
+fn test_insert() {
+    let mut a = vec![1, 2, 4];
+    a.insert(2, 3);
+    assert_eq!(a, [1, 2, 3, 4]);
+
+    let mut a = vec![1, 2, 3];
+    a.insert(0, 0);
+    assert_eq!(a, [0, 1, 2, 3]);
+
+    let mut a = vec![1, 2, 3];
+    a.insert(3, 4);
+    assert_eq!(a, [1, 2, 3, 4]);
+
+    let mut a = vec![];
+    a.insert(0, 1);
+    assert_eq!(a, [1]);
+}
+
+#[test]
+#[should_panic]
+fn test_insert_oob() {
+    let mut a = vec![1, 2, 3];
+    a.insert(4, 5);
+}
+
+#[test]
+fn test_remove() {
+    let mut a = vec![1, 2, 3, 4];
+
+    assert_eq!(a.remove(2), 3);
+    assert_eq!(a, [1, 2, 4]);
+
+    assert_eq!(a.remove(2), 4);
+    assert_eq!(a, [1, 2]);
+
+    assert_eq!(a.remove(0), 1);
+    assert_eq!(a, [2]);
+
+    assert_eq!(a.remove(0), 2);
+    assert_eq!(a, []);
+}
+
+#[test]
+#[should_panic]
+fn test_remove_fail() {
+    let mut a = vec![1];
+    let _ = a.remove(0);
+    let _ = a.remove(0);
+}
+
+#[test]
+fn test_capacity() {
+    let mut v = vec![0];
+    v.reserve_exact(10);
+    assert!(v.capacity() >= 11);
+}
+
+#[test]
+fn test_slice_2() {
+    let v = vec![1, 2, 3, 4, 5];
+    let v = v.slice(1, 3);
+    assert_eq!(v.len(), 2);
+    assert_eq!(v[0], 2);
+    assert_eq!(v[1], 3);
+}
+
+#[test]
+#[should_panic]
+fn test_permute_fail() {
+    let v: [(Box<_>, Rc<_>); 4] =
+        [(box 0, Rc::new(0)), (box 0, Rc::new(0)),
+         (box 0, Rc::new(0)), (box 0, Rc::new(0))];
+    let mut i = 0;
+    for _ in v.permutations() {
+        if i == 2 {
+            panic!()
+        }
+        i += 1;
+    }
+}
+
+#[test]
+fn test_total_ord() {
+    let c = &[1, 2, 3];
+    [1, 2, 3, 4][..].cmp(c) == Greater;
+    let c = &[1, 2, 3, 4];
+    [1, 2, 3][..].cmp(c) == Less;
+    let c = &[1, 2, 3, 6];
+    [1, 2, 3, 4][..].cmp(c) == Equal;
+    let c = &[1, 2, 3, 4, 5, 6];
+    [1, 2, 3, 4, 5, 5, 5, 5][..].cmp(c) == Less;
+    let c = &[1, 2, 3, 4];
+    [2, 2][..].cmp(c) == Greater;
+}
+
+#[test]
+fn test_iterator() {
+    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() {
+    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() {
+    let mut xs = [1, 2, 5, 10, 11];
+    assert_eq!(xs.iter().size_hint(), (5, Some(5)));
+    assert_eq!(xs.iter_mut().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() {
+    let mut xs = [1, 2, 3, 4, 5];
+    for x in &mut xs {
+        *x += 1;
+    }
+    assert!(xs == [2, 3, 4, 5, 6])
+}
+
+#[test]
+fn test_rev_iterator() {
+
+    let xs = [1, 2, 5, 10, 11];
+    let ys = [11, 10, 5, 2, 1];
+    let mut i = 0;
+    for &x in xs.iter().rev() {
+        assert_eq!(x, ys[i]);
+        i += 1;
+    }
+    assert_eq!(i, 5);
+}
+
+#[test]
+fn test_mut_rev_iterator() {
+    let mut xs = [1, 2, 3, 4, 5];
+    for (i,x) in xs.iter_mut().rev().enumerate() {
+        *x += i;
+    }
+    assert!(xs == [5, 5, 5, 5, 5])
+}
+
+#[test]
+fn test_move_iterator() {
+    let xs = vec![1,2,3,4,5];
+    assert_eq!(xs.into_iter().fold(0, |a: usize, b: usize| 10*a + b), 12345);
+}
+
+#[test]
+fn test_move_rev_iterator() {
+    let xs = vec![1,2,3,4,5];
+    assert_eq!(xs.into_iter().rev().fold(0, |a: usize, b: usize| 10*a + b), 54321);
+}
+
+#[test]
+fn test_splitator() {
+    let xs = &[1,2,3,4,5];
+
+    let splits: &[&[_]] = &[&[1], &[3], &[5]];
+    assert_eq!(xs.split(|x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[], &[2,3,4,5]];
+    assert_eq!(xs.split(|x| *x == 1).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[1,2,3,4], &[]];
+    assert_eq!(xs.split(|x| *x == 5).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[1,2,3,4,5]];
+    assert_eq!(xs.split(|x| *x == 10).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[], &[], &[], &[], &[], &[]];
+    assert_eq!(xs.split(|_| true).collect::<Vec<&[i32]>>(),
+               splits);
+
+    let xs: &[i32] = &[];
+    let splits: &[&[i32]] = &[&[]];
+    assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[i32]>>(), splits);
+}
+
+#[test]
+fn test_splitnator() {
+    let xs = &[1,2,3,4,5];
+
+    let splits: &[&[_]] = &[&[1,2,3,4,5]];
+    assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[1], &[3,4,5]];
+    assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[], &[], &[], &[4,5]];
+    assert_eq!(xs.splitn(3, |_| true).collect::<Vec<_>>(),
+               splits);
+
+    let xs: &[i32] = &[];
+    let splits: &[&[i32]] = &[&[]];
+    assert_eq!(xs.splitn(1, |x| *x == 5).collect::<Vec<_>>(), splits);
+}
+
+#[test]
+fn test_splitnator_mut() {
+    let xs = &mut [1,2,3,4,5];
+
+    let splits: &[&mut[_]] = &[&mut [1,2,3,4,5]];
+    assert_eq!(xs.splitn_mut(0, |x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&mut[_]] = &[&mut [1], &mut [3,4,5]];
+    assert_eq!(xs.splitn_mut(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&mut[_]] = &[&mut [], &mut [], &mut [], &mut [4,5]];
+    assert_eq!(xs.splitn_mut(3, |_| true).collect::<Vec<_>>(),
+               splits);
+
+    let xs: &mut [i32] = &mut [];
+    let splits: &[&mut[i32]] = &[&mut []];
+    assert_eq!(xs.splitn_mut(1, |x| *x == 5).collect::<Vec<_>>(),
+               splits);
+}
+
+#[test]
+fn test_rsplitator() {
+    let xs = &[1,2,3,4,5];
+
+    let splits: &[&[_]] = &[&[5], &[3], &[1]];
+    assert_eq!(xs.split(|x| *x % 2 == 0).rev().collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[2,3,4,5], &[]];
+    assert_eq!(xs.split(|x| *x == 1).rev().collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[], &[1,2,3,4]];
+    assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[1,2,3,4,5]];
+    assert_eq!(xs.split(|x| *x == 10).rev().collect::<Vec<_>>(),
+               splits);
+
+    let xs: &[i32] = &[];
+    let splits: &[&[i32]] = &[&[]];
+    assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[i32]>>(), splits);
+}
+
+#[test]
+fn test_rsplitnator() {
+    let xs = &[1,2,3,4,5];
+
+    let splits: &[&[_]] = &[&[1,2,3,4,5]];
+    assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[5], &[1,2,3]];
+    assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&[_]] = &[&[], &[], &[], &[1,2]];
+    assert_eq!(xs.rsplitn(3, |_| true).collect::<Vec<_>>(),
+               splits);
+
+    let xs: &[i32]  = &[];
+    let splits: &[&[i32]] = &[&[]];
+    assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<Vec<&[i32]>>(), splits);
+}
+
+#[test]
+fn test_windowsator() {
+    let v = &[1,2,3,4];
+
+    let wins: &[&[_]] = &[&[1,2], &[2,3], &[3,4]];
+    assert_eq!(v.windows(2).collect::<Vec<_>>(), wins);
+
+    let wins: &[&[_]] = &[&[1,2,3], &[2,3,4]];
+    assert_eq!(v.windows(3).collect::<Vec<_>>(), wins);
+    assert!(v.windows(6).next().is_none());
+
+    let wins: &[&[_]] = &[&[3,4], &[2,3], &[1,2]];
+    assert_eq!(v.windows(2).rev().collect::<Vec<&[_]>>(), wins);
+    let mut it = v.windows(2);
+    assert_eq!(it.indexable(), 3);
+    let win: &[_] = &[1,2];
+    assert_eq!(it.idx(0).unwrap(), win);
+    let win: &[_] = &[2,3];
+    assert_eq!(it.idx(1).unwrap(), win);
+    let win: &[_] = &[3,4];
+    assert_eq!(it.idx(2).unwrap(), win);
+    assert_eq!(it.idx(3), None);
+}
+
+#[test]
+#[should_panic]
+fn test_windowsator_0() {
+    let v = &[1,2,3,4];
+    let _it = v.windows(0);
+}
+
+#[test]
+fn test_chunksator() {
+    let v = &[1,2,3,4,5];
+
+    assert_eq!(v.chunks(2).len(), 3);
+
+    let chunks: &[&[_]] = &[&[1,2], &[3,4], &[5]];
+    assert_eq!(v.chunks(2).collect::<Vec<_>>(), chunks);
+    let chunks: &[&[_]] = &[&[1,2,3], &[4,5]];
+    assert_eq!(v.chunks(3).collect::<Vec<_>>(), chunks);
+    let chunks: &[&[_]] = &[&[1,2,3,4,5]];
+    assert_eq!(v.chunks(6).collect::<Vec<_>>(), chunks);
+
+    let chunks: &[&[_]] = &[&[5], &[3,4], &[1,2]];
+    assert_eq!(v.chunks(2).rev().collect::<Vec<_>>(), chunks);
+    let mut it = v.chunks(2);
+    assert_eq!(it.indexable(), 3);
+
+    let chunk: &[_] = &[1,2];
+    assert_eq!(it.idx(0).unwrap(), chunk);
+    let chunk: &[_] = &[3,4];
+    assert_eq!(it.idx(1).unwrap(), chunk);
+    let chunk: &[_] = &[5];
+    assert_eq!(it.idx(2).unwrap(), chunk);
+    assert_eq!(it.idx(3), None);
+}
+
+#[test]
+#[should_panic]
+fn test_chunksator_0() {
+    let v = &[1,2,3,4];
+    let _it = v.chunks(0);
+}
+
+#[test]
+fn test_move_from() {
+    let mut a = [1,2,3,4,5];
+    let b = vec![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 = vec![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 = vec![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 = vec![5,6,7,8,9,0];
+    assert_eq!(a[2..4].move_from(b,1,6), 2);
+    assert!(a == [1,2,6,7,5]);
+}
+
+#[test]
+fn test_reverse_part() {
+    let mut values = [1,2,3,4,5];
+    values[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), x_str);
+        })
+    }
+    let empty = Vec::<i32>::new();
+    test_show_vec!(empty, "[]");
+    test_show_vec!(vec![1], "[1]");
+    test_show_vec!(vec![1, 2, 3], "[1, 2, 3]");
+    test_show_vec!(vec![vec![], vec![1], vec![1, 1]],
+                   "[[], [1], [1, 1]]");
+
+    let empty_mut: &mut [i32] = &mut[];
+    test_show_vec!(empty_mut, "[]");
+    let v = &mut[1];
+    test_show_vec!(v, "[1]");
+    let v = &mut[1, 2, 3];
+    test_show_vec!(v, "[1, 2, 3]");
+    let v: &mut[&mut[_]] = &mut[&mut[], &mut[1], &mut[1, 1]];
+    test_show_vec!(v, "[[], [1], [1, 1]]");
+}
+
+#[test]
+fn test_vec_default() {
+    macro_rules! t {
+        ($ty:ty) => {{
+            let v: $ty = Default::default();
+            assert!(v.is_empty());
+        }}
+    }
+
+    t!(&[i32]);
+    t!(Vec<i32>);
+}
+
+#[test]
+fn test_bytes_set_memory() {
+    use std::slice::bytes::MutableByteVector;
+
+    let mut values = [1,2,3,4,5];
+    values[0..5].set_memory(0xAB);
+    assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
+    values[2..4].set_memory(0xFF);
+    assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
+}
+
+#[test]
+#[should_panic]
+fn test_overflow_does_not_cause_segfault() {
+    let mut v = vec![];
+    v.reserve_exact(-1);
+    v.push(1);
+    v.push(2);
+}
+
+#[test]
+#[should_panic]
+fn test_overflow_does_not_cause_segfault_managed() {
+    let mut v = vec![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.split_at_mut(2);
+        {
+            let left: &[_] = left;
+            assert!(left[..left.len()] == [1, 2]);
+        }
+        for p in left {
+            *p += 1;
+        }
+
+        {
+            let right: &[_] = right;
+            assert!(right[..right.len()] == [3, 4, 5]);
+        }
+        for p in right {
+            *p += 2;
+        }
+    }
+
+    assert!(values == [2, 3, 5, 6, 7]);
+}
+
+#[derive(Clone, PartialEq)]
+struct Foo;
+
+#[test]
+fn test_iter_zero_sized() {
+    let mut v = vec![Foo, Foo, Foo];
+    assert_eq!(v.len(), 3);
+    let mut cnt = 0;
+
+    for f in &v {
+        assert!(*f == Foo);
+        cnt += 1;
+    }
+    assert_eq!(cnt, 3);
+
+    for f in &v[1..3] {
+        assert!(*f == Foo);
+        cnt += 1;
+    }
+    assert_eq!(cnt, 5);
+
+    for f in &mut v {
+        assert!(*f == Foo);
+        cnt += 1;
+    }
+    assert_eq!(cnt, 8);
+
+    for f in v {
+        assert!(f == Foo);
+        cnt += 1;
+    }
+    assert_eq!(cnt, 11);
+
+    let xs: [Foo; 3] = [Foo, Foo, Foo];
+    cnt = 0;
+    for f in &xs {
+        assert!(*f == Foo);
+        cnt += 1;
+    }
+    assert!(cnt == 3);
+}
+
+#[test]
+fn test_shrink_to_fit() {
+    let mut xs = vec![0, 1, 2, 3];
+    for i in 4..100 {
+        xs.push(i)
+    }
+    assert_eq!(xs.capacity(), 128);
+    xs.shrink_to_fit();
+    assert_eq!(xs.capacity(), 100);
+    assert_eq!(xs, (0..100).collect::<Vec<_>>());
+}
+
+#[test]
+fn test_starts_with() {
+    assert!(b"foobar".starts_with(b"foo"));
+    assert!(!b"foobar".starts_with(b"oob"));
+    assert!(!b"foobar".starts_with(b"bar"));
+    assert!(!b"foo".starts_with(b"foobar"));
+    assert!(!b"bar".starts_with(b"foobar"));
+    assert!(b"foobar".starts_with(b"foobar"));
+    let empty: &[u8] = &[];
+    assert!(empty.starts_with(empty));
+    assert!(!empty.starts_with(b"foo"));
+    assert!(b"foobar".starts_with(empty));
+}
+
+#[test]
+fn test_ends_with() {
+    assert!(b"foobar".ends_with(b"bar"));
+    assert!(!b"foobar".ends_with(b"oba"));
+    assert!(!b"foobar".ends_with(b"foo"));
+    assert!(!b"foo".ends_with(b"foobar"));
+    assert!(!b"bar".ends_with(b"foobar"));
+    assert!(b"foobar".ends_with(b"foobar"));
+    let empty: &[u8] = &[];
+    assert!(empty.ends_with(empty));
+    assert!(!empty.ends_with(b"foo"));
+    assert!(b"foobar".ends_with(empty));
+}
+
+#[test]
+fn test_mut_splitator() {
+    let mut xs = [0,1,0,2,3,0,0,4,5,0];
+    assert_eq!(xs.split_mut(|x| *x == 0).count(), 6);
+    for slice in xs.split_mut(|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.split_mut(|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.split_mut(|x| *x == 0).rev().take(4) {
+        slice.reverse();
+    }
+    assert!(xs == [1,2,0,4,3,0,0,6,5,0]);
+}
+
+#[test]
+fn test_get_mut() {
+    let mut v = [0,1,2];
+    assert_eq!(v.get_mut(3), None);
+    v.get_mut(1).map(|e| *e = 7);
+    assert_eq!(v[1], 7);
+    let mut x = 2;
+    assert_eq!(v.get_mut(2), Some(&mut x));
+}
+
+#[test]
+fn test_mut_chunks() {
+    let mut v = [0, 1, 2, 3, 4, 5, 6];
+    assert_eq!(v.chunks_mut(2).len(), 4);
+    for (i, chunk) in v.chunks_mut(3).enumerate() {
+        for x in chunk {
+            *x = i as u8;
+        }
+    }
+    let result = [0, 0, 0, 1, 1, 1, 2];
+    assert!(v == result);
+}
+
+#[test]
+fn test_mut_chunks_rev() {
+    let mut v = [0, 1, 2, 3, 4, 5, 6];
+    for (i, chunk) in v.chunks_mut(3).rev().enumerate() {
+        for x in chunk {
+            *x = i as u8;
+        }
+    }
+    let result = [2, 2, 2, 1, 1, 1, 0];
+    assert!(v == result);
+}
+
+#[test]
+#[should_panic]
+fn test_mut_chunks_0() {
+    let mut v = [1, 2, 3, 4];
+    let _it = v.chunks_mut(0);
+}
+
+#[test]
+fn test_mut_last() {
+    let mut x = [1, 2, 3, 4, 5];
+    let h = x.last_mut();
+    assert_eq!(*h.unwrap(), 5);
+
+    let y: &mut [i32] = &mut [];
+    assert!(y.last_mut().is_none());
+}
+
+#[test]
+fn test_to_vec() {
+    let xs: Box<_> = box [1, 2, 3];
+    let ys = xs.to_vec();
+    assert_eq!(ys, [1, 2, 3]);
+}
+
+mod bench {
+    use std::iter::repeat;
+    use std::{mem, ptr};
+    use std::rand::{Rng, weak_rng};
+
+    use test::{Bencher, black_box};
+
+    #[bench]
+    fn iterator(b: &mut Bencher) {
+        // peculiar numbers to stop LLVM from optimising the summation
+        // out.
+        let v: Vec<_> = (0..100).map(|i| i ^ (i << 1) ^ (i >> 1)).collect();
+
+        b.iter(|| {
+            let mut sum = 0;
+            for x in &v {
+                sum += *x;
+            }
+            // sum == 11806, to stop dead code elimination.
+            if sum == 0 {panic!()}
+        })
+    }
+
+    #[bench]
+    fn mut_iterator(b: &mut Bencher) {
+        let mut v: Vec<_> = repeat(0).take(100).collect();
+
+        b.iter(|| {
+            let mut i = 0;
+            for x in &mut v {
+                *x = i;
+                i += 1;
+            }
+        })
+    }
+
+    #[bench]
+    fn concat(b: &mut Bencher) {
+        let xss: Vec<Vec<i32>> =
+            (0..100).map(|i| (0..i).collect()).collect();
+        b.iter(|| {
+            xss.concat();
+        });
+    }
+
+    #[bench]
+    fn connect(b: &mut Bencher) {
+        let xss: Vec<Vec<i32>> =
+            (0..100).map(|i| (0..i).collect()).collect();
+        b.iter(|| {
+            xss.connect(&0)
+        });
+    }
+
+    #[bench]
+    fn push(b: &mut Bencher) {
+        let mut vec = Vec::<i32>::new();
+        b.iter(|| {
+            vec.push(0);
+            black_box(&vec);
+        });
+    }
+
+    #[bench]
+    fn starts_with_same_vector(b: &mut Bencher) {
+        let vec: Vec<_> = (0..100).collect();
+        b.iter(|| {
+            vec.starts_with(&vec)
+        })
+    }
+
+    #[bench]
+    fn starts_with_single_element(b: &mut Bencher) {
+        let vec: Vec<_> = vec![0];
+        b.iter(|| {
+            vec.starts_with(&vec)
+        })
+    }
+
+    #[bench]
+    fn starts_with_diff_one_element_at_end(b: &mut Bencher) {
+        let vec: Vec<_> = (0..100).collect();
+        let mut match_vec: Vec<_> = (0..99).collect();
+        match_vec.push(0);
+        b.iter(|| {
+            vec.starts_with(&match_vec)
+        })
+    }
+
+    #[bench]
+    fn ends_with_same_vector(b: &mut Bencher) {
+        let vec: Vec<_> = (0..100).collect();
+        b.iter(|| {
+            vec.ends_with(&vec)
+        })
+    }
+
+    #[bench]
+    fn ends_with_single_element(b: &mut Bencher) {
+        let vec: Vec<_> = vec![0];
+        b.iter(|| {
+            vec.ends_with(&vec)
+        })
+    }
+
+    #[bench]
+    fn ends_with_diff_one_element_at_beginning(b: &mut Bencher) {
+        let vec: Vec<_> = (0..100).collect();
+        let mut match_vec: Vec<_> = (0..100).collect();
+        match_vec[0] = 200;
+        b.iter(|| {
+            vec.starts_with(&match_vec)
+        })
+    }
+
+    #[bench]
+    fn contains_last_element(b: &mut Bencher) {
+        let vec: Vec<_> = (0..100).collect();
+        b.iter(|| {
+            vec.contains(&99)
+        })
+    }
+
+    #[bench]
+    fn zero_1kb_from_elem(b: &mut Bencher) {
+        b.iter(|| {
+            repeat(0u8).take(1024).collect::<Vec<_>>()
+        });
+    }
+
+    #[bench]
+    fn zero_1kb_set_memory(b: &mut Bencher) {
+        b.iter(|| {
+            let mut v = Vec::<u8>::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_loop_set(b: &mut Bencher) {
+        b.iter(|| {
+            let mut v = Vec::<u8>::with_capacity(1024);
+            unsafe {
+                v.set_len(1024);
+            }
+            for i in 0..1024 {
+                v[i] = 0;
+            }
+        });
+    }
+
+    #[bench]
+    fn zero_1kb_mut_iter(b: &mut Bencher) {
+        b.iter(|| {
+            let mut v = Vec::<u8>::with_capacity(1024);
+            unsafe {
+                v.set_len(1024);
+            }
+            for x in &mut v {
+                *x = 0;
+            }
+            v
+        });
+    }
+
+    #[bench]
+    fn random_inserts(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v: Vec<_> = repeat((0, 0)).take(30).collect();
+            for _ in 0..100 {
+                let l = v.len();
+                v.insert(rng.gen::<usize>() % (l + 1),
+                         (1, 1));
+            }
+        })
+    }
+    #[bench]
+    fn random_removes(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v: Vec<_> = repeat((0, 0)).take(130).collect();
+            for _ in 0..100 {
+                let l = v.len();
+                v.remove(rng.gen::<usize>() % l);
+            }
+        })
+    }
+
+    #[bench]
+    fn sort_random_small(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v: Vec<_> = rng.gen_iter::<u64>().take(5).collect();
+            v.sort();
+        });
+        b.bytes = 5 * mem::size_of::<u64>() as u64;
+    }
+
+    #[bench]
+    fn sort_random_medium(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v: Vec<_> = rng.gen_iter::<u64>().take(100).collect();
+            v.sort();
+        });
+        b.bytes = 100 * mem::size_of::<u64>() as u64;
+    }
+
+    #[bench]
+    fn sort_random_large(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v: Vec<_> = rng.gen_iter::<u64>().take(10000).collect();
+            v.sort();
+        });
+        b.bytes = 10000 * mem::size_of::<u64>() as u64;
+    }
+
+    #[bench]
+    fn sort_sorted(b: &mut Bencher) {
+        let mut v: Vec<_> = (0..10000).collect();
+        b.iter(|| {
+            v.sort();
+        });
+        b.bytes = (v.len() * mem::size_of_val(&v[0])) as u64;
+    }
+
+    type BigSortable = (u64, u64, u64, u64);
+
+    #[bench]
+    fn sort_big_random_small(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v = rng.gen_iter::<BigSortable>().take(5)
+                           .collect::<Vec<BigSortable>>();
+            v.sort();
+        });
+        b.bytes = 5 * mem::size_of::<BigSortable>() as u64;
+    }
+
+    #[bench]
+    fn sort_big_random_medium(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v = rng.gen_iter::<BigSortable>().take(100)
+                           .collect::<Vec<BigSortable>>();
+            v.sort();
+        });
+        b.bytes = 100 * mem::size_of::<BigSortable>() as u64;
+    }
+
+    #[bench]
+    fn sort_big_random_large(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v = rng.gen_iter::<BigSortable>().take(10000)
+                           .collect::<Vec<BigSortable>>();
+            v.sort();
+        });
+        b.bytes = 10000 * mem::size_of::<BigSortable>() as u64;
+    }
+
+    #[bench]
+    fn sort_big_sorted(b: &mut Bencher) {
+        let mut v: Vec<BigSortable> = (0..10000).map(|i| (i, i, i, i)).collect();
+        b.iter(|| {
+            v.sort();
+        });
+        b.bytes = (v.len() * mem::size_of_val(&v[0])) as u64;
+    }
+}
diff --git a/src/libcollectionstest/str.rs b/src/libcollectionstest/str.rs
new file mode 100644
index 00000000000..79c2d719862
--- /dev/null
+++ b/src/libcollectionstest/str.rs
@@ -0,0 +1,1668 @@
+// 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.
+
+use std::cmp::Ordering::{Equal, Greater, Less};
+use std::iter::AdditiveIterator;
+use std::str::{Utf8Error, from_utf8};
+
+#[test]
+fn test_le() {
+    assert!("" <= "");
+    assert!("" <= "foo");
+    assert!("foo" <= "foo");
+    assert!("foo" != "bar");
+}
+
+#[test]
+fn test_len() {
+    assert_eq!("".len(), 0);
+    assert_eq!("hello world".len(), 11);
+    assert_eq!("\x63".len(), 1);
+    assert_eq!("\u{a2}".len(), 2);
+    assert_eq!("\u{3c0}".len(), 2);
+    assert_eq!("\u{2620}".len(), 3);
+    assert_eq!("\u{1d11e}".len(), 4);
+
+    assert_eq!("".chars().count(), 0);
+    assert_eq!("hello world".chars().count(), 11);
+    assert_eq!("\x63".chars().count(), 1);
+    assert_eq!("\u{a2}".chars().count(), 1);
+    assert_eq!("\u{3c0}".chars().count(), 1);
+    assert_eq!("\u{2620}".chars().count(), 1);
+    assert_eq!("\u{1d11e}".chars().count(), 1);
+    assert_eq!("ประเทศไทย中华Việt Nam".chars().count(), 19);
+
+    assert_eq!("hello".width(false), 10);
+    assert_eq!("hello".width(true), 10);
+    assert_eq!("\0\0\0\0\0".width(false), 0);
+    assert_eq!("\0\0\0\0\0".width(true), 0);
+    assert_eq!("".width(false), 0);
+    assert_eq!("".width(true), 0);
+    assert_eq!("\u{2081}\u{2082}\u{2083}\u{2084}".width(false), 4);
+    assert_eq!("\u{2081}\u{2082}\u{2083}\u{2084}".width(true), 8);
+}
+
+#[test]
+fn test_find() {
+    assert_eq!("hello".find('l'), Some(2));
+    assert_eq!("hello".find(|c:char| c == 'o'), Some(4));
+    assert!("hello".find('x').is_none());
+    assert!("hello".find(|c:char| c == 'x').is_none());
+    assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30));
+    assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30));
+}
+
+#[test]
+fn test_rfind() {
+    assert_eq!("hello".rfind('l'), Some(3));
+    assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4));
+    assert!("hello".rfind('x').is_none());
+    assert!("hello".rfind(|c:char| c == 'x').is_none());
+    assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30));
+    assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30));
+}
+
+#[test]
+fn test_collect() {
+    let empty = String::from_str("");
+    let s: String = empty.chars().collect();
+    assert_eq!(empty, s);
+    let data = String::from_str("ประเทศไทย中");
+    let s: String = data.chars().collect();
+    assert_eq!(data, s);
+}
+
+#[test]
+fn test_into_bytes() {
+    let data = String::from_str("asdf");
+    let buf = data.into_bytes();
+    assert_eq!(b"asdf", buf);
+}
+
+#[test]
+fn test_find_str() {
+    // byte positions
+    assert_eq!("".find_str(""), Some(0));
+    assert!("banana".find_str("apple pie").is_none());
+
+    let data = "abcabc";
+    assert_eq!(data[0..6].find_str("ab"), Some(0));
+    assert_eq!(data[2..6].find_str("ab"), Some(3 - 2));
+    assert!(data[2..4].find_str("ab").is_none());
+
+    let string = "ประเทศไทย中华Việt Nam";
+    let mut data = String::from_str(string);
+    data.push_str(string);
+    assert!(data.find_str("ไท华").is_none());
+    assert_eq!(data[0..43].find_str(""), Some(0));
+    assert_eq!(data[6..43].find_str(""), Some(6 - 6));
+
+    assert_eq!(data[0..43].find_str("ประ"), Some( 0));
+    assert_eq!(data[0..43].find_str("ทศไ"), Some(12));
+    assert_eq!(data[0..43].find_str("ย中"), Some(24));
+    assert_eq!(data[0..43].find_str("iệt"), Some(34));
+    assert_eq!(data[0..43].find_str("Nam"), Some(40));
+
+    assert_eq!(data[43..86].find_str("ประ"), Some(43 - 43));
+    assert_eq!(data[43..86].find_str("ทศไ"), Some(55 - 43));
+    assert_eq!(data[43..86].find_str("ย中"), Some(67 - 43));
+    assert_eq!(data[43..86].find_str("iệt"), Some(77 - 43));
+    assert_eq!(data[43..86].find_str("Nam"), Some(83 - 43));
+}
+
+#[test]
+fn test_slice_chars() {
+    fn t(a: &str, b: &str, start: usize) {
+        assert_eq!(a.slice_chars(start, start + b.chars().count()), b);
+    }
+    t("", "", 0);
+    t("hello", "llo", 2);
+    t("hello", "el", 1);
+    t("αβλ", "β", 1);
+    t("αβλ", "", 3);
+    assert_eq!("ะเทศไท", "ประเทศไทย中华Việt Nam".slice_chars(2, 8));
+}
+
+fn s(x: &str) -> String { x.to_string() }
+
+macro_rules! test_concat {
+    ($expected: expr, $string: expr) => {
+        {
+            let s: String = $string.concat();
+            assert_eq!($expected, s);
+        }
+    }
+}
+
+#[test]
+fn test_concat_for_different_types() {
+    test_concat!("ab", vec![s("a"), s("b")]);
+    test_concat!("ab", vec!["a", "b"]);
+    test_concat!("ab", vec!["a", "b"]);
+    test_concat!("ab", vec![s("a"), s("b")]);
+}
+
+#[test]
+fn test_concat_for_different_lengths() {
+    let empty: &[&str] = &[];
+    test_concat!("", empty);
+    test_concat!("a", ["a"]);
+    test_concat!("ab", ["a", "b"]);
+    test_concat!("abc", ["", "a", "bc"]);
+}
+
+macro_rules! test_connect {
+    ($expected: expr, $string: expr, $delim: expr) => {
+        {
+            let s = $string.connect($delim);
+            assert_eq!($expected, s);
+        }
+    }
+}
+
+#[test]
+fn test_connect_for_different_types() {
+    test_connect!("a-b", ["a", "b"], "-");
+    let hyphen = "-".to_string();
+    test_connect!("a-b", [s("a"), s("b")], &*hyphen);
+    test_connect!("a-b", vec!["a", "b"], &*hyphen);
+    test_connect!("a-b", &*vec!["a", "b"], "-");
+    test_connect!("a-b", vec![s("a"), s("b")], "-");
+}
+
+#[test]
+fn test_connect_for_different_lengths() {
+    let empty: &[&str] = &[];
+    test_connect!("", empty, "-");
+    test_connect!("a", ["a"], "-");
+    test_connect!("a-b", ["a", "b"], "-");
+    test_connect!("-a-bc", ["", "a", "bc"], "-");
+}
+
+#[test]
+fn test_unsafe_slice() {
+    assert_eq!("ab", unsafe {"abc".slice_unchecked(0, 2)});
+    assert_eq!("bc", unsafe {"abc".slice_unchecked(1, 3)});
+    assert_eq!("", unsafe {"abc".slice_unchecked(1, 1)});
+    fn a_million_letter_a() -> String {
+        let mut i = 0;
+        let mut rs = String::new();
+        while i < 100000 {
+            rs.push_str("aaaaaaaaaa");
+            i += 1;
+        }
+        rs
+    }
+    fn half_a_million_letter_a() -> String {
+        let mut i = 0;
+        let mut rs = String::new();
+        while i < 100000 {
+            rs.push_str("aaaaa");
+            i += 1;
+        }
+        rs
+    }
+    let letters = a_million_letter_a();
+    assert!(half_a_million_letter_a() ==
+        unsafe {String::from_str(letters.slice_unchecked(
+                                 0,
+                                 500000))});
+}
+
+#[test]
+fn test_starts_with() {
+    assert!(("".starts_with("")));
+    assert!(("abc".starts_with("")));
+    assert!(("abc".starts_with("a")));
+    assert!((!"a".starts_with("abc")));
+    assert!((!"".starts_with("abc")));
+    assert!((!"ödd".starts_with("-")));
+    assert!(("ödd".starts_with("öd")));
+}
+
+#[test]
+fn test_ends_with() {
+    assert!(("".ends_with("")));
+    assert!(("abc".ends_with("")));
+    assert!(("abc".ends_with("c")));
+    assert!((!"a".ends_with("abc")));
+    assert!((!"".ends_with("abc")));
+    assert!((!"ddö".ends_with("-")));
+    assert!(("ddö".ends_with("dö")));
+}
+
+#[test]
+fn test_is_empty() {
+    assert!("".is_empty());
+    assert!(!"a".is_empty());
+}
+
+#[test]
+fn test_replace() {
+    let a = "a";
+    assert_eq!("".replace(a, "b"), String::from_str(""));
+    assert_eq!("a".replace(a, "b"), String::from_str("b"));
+    assert_eq!("ab".replace(a, "b"), String::from_str("bb"));
+    let test = "test";
+    assert!(" test test ".replace(test, "toast") ==
+        String::from_str(" toast toast "));
+    assert_eq!(" test test ".replace(test, ""), String::from_str("   "));
+}
+
+#[test]
+fn test_replace_2a() {
+    let data = "ประเทศไทย中华";
+    let repl = "دولة الكويت";
+
+    let a = "ประเ";
+    let a2 = "دولة الكويتทศไทย中华";
+    assert_eq!(data.replace(a, repl), a2);
+}
+
+#[test]
+fn test_replace_2b() {
+    let data = "ประเทศไทย中华";
+    let repl = "دولة الكويت";
+
+    let b = "ะเ";
+    let b2 = "ปรدولة الكويتทศไทย中华";
+    assert_eq!(data.replace(b, repl), b2);
+}
+
+#[test]
+fn test_replace_2c() {
+    let data = "ประเทศไทย中华";
+    let repl = "دولة الكويت";
+
+    let c = "中华";
+    let c2 = "ประเทศไทยدولة الكويت";
+    assert_eq!(data.replace(c, repl), c2);
+}
+
+#[test]
+fn test_replace_2d() {
+    let data = "ประเทศไทย中华";
+    let repl = "دولة الكويت";
+
+    let d = "ไท华";
+    assert_eq!(data.replace(d, repl), data);
+}
+
+#[test]
+fn test_slice() {
+    assert_eq!("ab", "abc".slice(0, 2));
+    assert_eq!("bc", "abc".slice(1, 3));
+    assert_eq!("", "abc".slice(1, 1));
+    assert_eq!("\u{65e5}", "\u{65e5}\u{672c}".slice(0, 3));
+
+    let data = "ประเทศไทย中华";
+    assert_eq!("ป", data.slice(0, 3));
+    assert_eq!("ร", data.slice(3, 6));
+    assert_eq!("", data.slice(3, 3));
+    assert_eq!("华", data.slice(30, 33));
+
+    fn a_million_letter_x() -> String {
+        let mut i = 0;
+        let mut rs = String::new();
+        while i < 100000 {
+            rs.push_str("华华华华华华华华华华");
+            i += 1;
+        }
+        rs
+    }
+    fn half_a_million_letter_x() -> String {
+        let mut i = 0;
+        let mut rs = String::new();
+        while i < 100000 {
+            rs.push_str("华华华华华");
+            i += 1;
+        }
+        rs
+    }
+    let letters = a_million_letter_x();
+    assert!(half_a_million_letter_x() ==
+        String::from_str(letters.slice(0, 3 * 500000)));
+}
+
+#[test]
+fn test_slice_2() {
+    let ss = "中华Việt Nam";
+
+    assert_eq!("华", ss.slice(3, 6));
+    assert_eq!("Việt Nam", ss.slice(6, 16));
+
+    assert_eq!("ab", "abc".slice(0, 2));
+    assert_eq!("bc", "abc".slice(1, 3));
+    assert_eq!("", "abc".slice(1, 1));
+
+    assert_eq!("中", ss.slice(0, 3));
+    assert_eq!("华V", ss.slice(3, 7));
+    assert_eq!("", ss.slice(3, 3));
+    /*0: 中
+      3: 华
+      6: V
+      7: i
+      8: ệ
+     11: t
+     12:
+     13: N
+     14: a
+     15: m */
+}
+
+#[test]
+#[should_panic]
+fn test_slice_fail() {
+    "中华Việt Nam".slice(0, 2);
+}
+
+#[test]
+fn test_slice_from() {
+    assert_eq!("abcd".slice_from(0), "abcd");
+    assert_eq!("abcd".slice_from(2), "cd");
+    assert_eq!("abcd".slice_from(4), "");
+}
+#[test]
+fn test_slice_to() {
+    assert_eq!("abcd".slice_to(0), "");
+    assert_eq!("abcd".slice_to(2), "ab");
+    assert_eq!("abcd".slice_to(4), "abcd");
+}
+
+#[test]
+fn test_trim_left_matches() {
+    let v: &[char] = &[];
+    assert_eq!(" *** foo *** ".trim_left_matches(v), " *** foo *** ");
+    let chars: &[char] = &['*', ' '];
+    assert_eq!(" *** foo *** ".trim_left_matches(chars), "foo *** ");
+    assert_eq!(" ***  *** ".trim_left_matches(chars), "");
+    assert_eq!("foo *** ".trim_left_matches(chars), "foo *** ");
+
+    assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
+    let chars: &[char] = &['1', '2'];
+    assert_eq!("12foo1bar12".trim_left_matches(chars), "foo1bar12");
+    assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123");
+}
+
+#[test]
+fn test_trim_right_matches() {
+    let v: &[char] = &[];
+    assert_eq!(" *** foo *** ".trim_right_matches(v), " *** foo *** ");
+    let chars: &[char] = &['*', ' '];
+    assert_eq!(" *** foo *** ".trim_right_matches(chars), " *** foo");
+    assert_eq!(" ***  *** ".trim_right_matches(chars), "");
+    assert_eq!(" *** foo".trim_right_matches(chars), " *** foo");
+
+    assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
+    let chars: &[char] = &['1', '2'];
+    assert_eq!("12foo1bar12".trim_right_matches(chars), "12foo1bar");
+    assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar");
+}
+
+#[test]
+fn test_trim_matches() {
+    let v: &[char] = &[];
+    assert_eq!(" *** foo *** ".trim_matches(v), " *** foo *** ");
+    let chars: &[char] = &['*', ' '];
+    assert_eq!(" *** foo *** ".trim_matches(chars), "foo");
+    assert_eq!(" ***  *** ".trim_matches(chars), "");
+    assert_eq!("foo".trim_matches(chars), "foo");
+
+    assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
+    let chars: &[char] = &['1', '2'];
+    assert_eq!("12foo1bar12".trim_matches(chars), "foo1bar");
+    assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar");
+}
+
+#[test]
+fn test_trim_left() {
+    assert_eq!("".trim_left(), "");
+    assert_eq!("a".trim_left(), "a");
+    assert_eq!("    ".trim_left(), "");
+    assert_eq!("     blah".trim_left(), "blah");
+    assert_eq!("   \u{3000}  wut".trim_left(), "wut");
+    assert_eq!("hey ".trim_left(), "hey ");
+}
+
+#[test]
+fn test_trim_right() {
+    assert_eq!("".trim_right(), "");
+    assert_eq!("a".trim_right(), "a");
+    assert_eq!("    ".trim_right(), "");
+    assert_eq!("blah     ".trim_right(), "blah");
+    assert_eq!("wut   \u{3000}  ".trim_right(), "wut");
+    assert_eq!(" hey".trim_right(), " hey");
+}
+
+#[test]
+fn test_trim() {
+    assert_eq!("".trim(), "");
+    assert_eq!("a".trim(), "a");
+    assert_eq!("    ".trim(), "");
+    assert_eq!("    blah     ".trim(), "blah");
+    assert_eq!("\nwut   \u{3000}  ".trim(), "wut");
+    assert_eq!(" hey dude ".trim(), "hey dude");
+}
+
+#[test]
+fn test_is_whitespace() {
+    assert!("".chars().all(|c| c.is_whitespace()));
+    assert!(" ".chars().all(|c| c.is_whitespace()));
+    assert!("\u{2009}".chars().all(|c| c.is_whitespace())); // Thin space
+    assert!("  \n\t   ".chars().all(|c| c.is_whitespace()));
+    assert!(!"   _   ".chars().all(|c| c.is_whitespace()));
+}
+
+#[test]
+fn test_slice_shift_char() {
+    let data = "ประเทศไทย中";
+    assert_eq!(data.slice_shift_char(), Some(('ป', "ระเทศไทย中")));
+}
+
+#[test]
+fn test_slice_shift_char_2() {
+    let empty = "";
+    assert_eq!(empty.slice_shift_char(), None);
+}
+
+#[test]
+fn test_is_utf8() {
+    // deny overlong encodings
+    assert!(from_utf8(&[0xc0, 0x80]).is_err());
+    assert!(from_utf8(&[0xc0, 0xae]).is_err());
+    assert!(from_utf8(&[0xe0, 0x80, 0x80]).is_err());
+    assert!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err());
+    assert!(from_utf8(&[0xe0, 0x81, 0x81]).is_err());
+    assert!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err());
+    assert!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err());
+
+    // deny surrogates
+    assert!(from_utf8(&[0xED, 0xA0, 0x80]).is_err());
+    assert!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err());
+
+    assert!(from_utf8(&[0xC2, 0x80]).is_ok());
+    assert!(from_utf8(&[0xDF, 0xBF]).is_ok());
+    assert!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok());
+    assert!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok());
+    assert!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok());
+    assert!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok());
+    assert!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok());
+    assert!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok());
+}
+
+#[test]
+fn test_is_utf16() {
+    use unicode::str::is_utf16;
+
+    macro_rules! pos {
+        ($($e:expr),*) => { { $(assert!(is_utf16($e));)* } }
+    }
+
+    // non-surrogates
+    pos!(&[0x0000],
+         &[0x0001, 0x0002],
+         &[0xD7FF],
+         &[0xE000]);
+
+    // surrogate pairs (randomly generated with Python 3's
+    // .encode('utf-16be'))
+    pos!(&[0xdb54, 0xdf16, 0xd880, 0xdee0, 0xdb6a, 0xdd45],
+         &[0xd91f, 0xdeb1, 0xdb31, 0xdd84, 0xd8e2, 0xde14],
+         &[0xdb9f, 0xdc26, 0xdb6f, 0xde58, 0xd850, 0xdfae]);
+
+    // mixtures (also random)
+    pos!(&[0xd921, 0xdcc2, 0x002d, 0x004d, 0xdb32, 0xdf65],
+         &[0xdb45, 0xdd2d, 0x006a, 0xdacd, 0xddfe, 0x0006],
+         &[0x0067, 0xd8ff, 0xddb7, 0x000f, 0xd900, 0xdc80]);
+
+    // negative tests
+    macro_rules! neg {
+        ($($e:expr),*) => { { $(assert!(!is_utf16($e));)* } }
+    }
+
+    neg!(
+        // surrogate + regular unit
+        &[0xdb45, 0x0000],
+        // surrogate + lead surrogate
+        &[0xd900, 0xd900],
+        // unterminated surrogate
+        &[0xd8ff],
+        // trail surrogate without a lead
+        &[0xddb7]);
+
+    // random byte sequences that Python 3's .decode('utf-16be')
+    // failed on
+    neg!(&[0x5b3d, 0x0141, 0xde9e, 0x8fdc, 0xc6e7],
+         &[0xdf5a, 0x82a5, 0x62b9, 0xb447, 0x92f3],
+         &[0xda4e, 0x42bc, 0x4462, 0xee98, 0xc2ca],
+         &[0xbe00, 0xb04a, 0x6ecb, 0xdd89, 0xe278],
+         &[0x0465, 0xab56, 0xdbb6, 0xa893, 0x665e],
+         &[0x6b7f, 0x0a19, 0x40f4, 0xa657, 0xdcc5],
+         &[0x9b50, 0xda5e, 0x24ec, 0x03ad, 0x6dee],
+         &[0x8d17, 0xcaa7, 0xf4ae, 0xdf6e, 0xbed7],
+         &[0xdaee, 0x2584, 0x7d30, 0xa626, 0x121a],
+         &[0xd956, 0x4b43, 0x7570, 0xccd6, 0x4f4a],
+         &[0x9dcf, 0x1b49, 0x4ba5, 0xfce9, 0xdffe],
+         &[0x6572, 0xce53, 0xb05a, 0xf6af, 0xdacf],
+         &[0x1b90, 0x728c, 0x9906, 0xdb68, 0xf46e],
+         &[0x1606, 0xbeca, 0xbe76, 0x860f, 0xdfa5],
+         &[0x8b4f, 0xde7a, 0xd220, 0x9fac, 0x2b6f],
+         &[0xb8fe, 0xebbe, 0xda32, 0x1a5f, 0x8b8b],
+         &[0x934b, 0x8956, 0xc434, 0x1881, 0xddf7],
+         &[0x5a95, 0x13fc, 0xf116, 0xd89b, 0x93f9],
+         &[0xd640, 0x71f1, 0xdd7d, 0x77eb, 0x1cd8],
+         &[0x348b, 0xaef0, 0xdb2c, 0xebf1, 0x1282],
+         &[0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]);
+}
+
+#[test]
+fn test_as_bytes() {
+    // no null
+    let v = [
+        224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
+        184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
+        109
+    ];
+    let b: &[u8] = &[];
+    assert_eq!("".as_bytes(), b);
+    assert_eq!("abc".as_bytes(), b"abc");
+    assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
+}
+
+#[test]
+#[should_panic]
+fn test_as_bytes_fail() {
+    // Don't double free. (I'm not sure if this exercises the
+    // original problem code path anymore.)
+    let s = String::from_str("");
+    let _bytes = s.as_bytes();
+    panic!();
+}
+
+#[test]
+fn test_as_ptr() {
+    let buf = "hello".as_ptr();
+    unsafe {
+        assert_eq!(*buf.offset(0), b'h');
+        assert_eq!(*buf.offset(1), b'e');
+        assert_eq!(*buf.offset(2), b'l');
+        assert_eq!(*buf.offset(3), b'l');
+        assert_eq!(*buf.offset(4), b'o');
+    }
+}
+
+#[test]
+fn test_subslice_offset() {
+    let a = "kernelsprite";
+    let b = &a[7..a.len()];
+    let c = &a[0..a.len() - 6];
+    assert_eq!(a.subslice_offset(b), 7);
+    assert_eq!(a.subslice_offset(c), 0);
+
+    let string = "a\nb\nc";
+    let lines: Vec<&str> = string.lines().collect();
+    assert_eq!(string.subslice_offset(lines[0]), 0);
+    assert_eq!(string.subslice_offset(lines[1]), 2);
+    assert_eq!(string.subslice_offset(lines[2]), 4);
+}
+
+#[test]
+#[should_panic]
+fn test_subslice_offset_2() {
+    let a = "alchemiter";
+    let b = "cruxtruder";
+    a.subslice_offset(b);
+}
+
+#[test]
+fn vec_str_conversions() {
+    let s1: String = String::from_str("All mimsy were the borogoves");
+
+    let v: Vec<u8> = s1.as_bytes().to_vec();
+    let s2: String = String::from_str(from_utf8(&v).unwrap());
+    let mut i = 0;
+    let n1 = s1.len();
+    let n2 = v.len();
+    assert_eq!(n1, n2);
+    while i < n1 {
+        let a: u8 = s1.as_bytes()[i];
+        let b: u8 = s2.as_bytes()[i];
+        debug!("{}", a);
+        debug!("{}", b);
+        assert_eq!(a, b);
+        i += 1;
+    }
+}
+
+#[test]
+fn test_contains() {
+    assert!("abcde".contains("bcd"));
+    assert!("abcde".contains("abcd"));
+    assert!("abcde".contains("bcde"));
+    assert!("abcde".contains(""));
+    assert!("".contains(""));
+    assert!(!"abcde".contains("def"));
+    assert!(!"".contains("a"));
+
+    let data = "ประเทศไทย中华Việt Nam";
+    assert!(data.contains("ประเ"));
+    assert!(data.contains("ะเ"));
+    assert!(data.contains("中华"));
+    assert!(!data.contains("ไท华"));
+}
+
+#[test]
+fn test_contains_char() {
+    assert!("abc".contains_char('b'));
+    assert!("a".contains_char('a'));
+    assert!(!"abc".contains_char('d'));
+    assert!(!"".contains_char('a'));
+}
+
+#[test]
+fn test_char_at() {
+    let s = "ศไทย中华Việt Nam";
+    let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
+    let mut pos = 0;
+    for ch in &v {
+        assert!(s.char_at(pos) == *ch);
+        pos += ch.to_string().len();
+    }
+}
+
+#[test]
+fn test_char_at_reverse() {
+    let s = "ศไทย中华Việt Nam";
+    let v = vec!['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
+    let mut pos = s.len();
+    for ch in v.iter().rev() {
+        assert!(s.char_at_reverse(pos) == *ch);
+        pos -= ch.to_string().len();
+    }
+}
+
+#[test]
+fn test_escape_unicode() {
+    assert_eq!("abc".escape_unicode(),
+               String::from_str("\\u{61}\\u{62}\\u{63}"));
+    assert_eq!("a c".escape_unicode(),
+               String::from_str("\\u{61}\\u{20}\\u{63}"));
+    assert_eq!("\r\n\t".escape_unicode(),
+               String::from_str("\\u{d}\\u{a}\\u{9}"));
+    assert_eq!("'\"\\".escape_unicode(),
+               String::from_str("\\u{27}\\u{22}\\u{5c}"));
+    assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(),
+               String::from_str("\\u{0}\\u{1}\\u{fe}\\u{ff}"));
+    assert_eq!("\u{100}\u{ffff}".escape_unicode(),
+               String::from_str("\\u{100}\\u{ffff}"));
+    assert_eq!("\u{10000}\u{10ffff}".escape_unicode(),
+               String::from_str("\\u{10000}\\u{10ffff}"));
+    assert_eq!("ab\u{fb00}".escape_unicode(),
+               String::from_str("\\u{61}\\u{62}\\u{fb00}"));
+    assert_eq!("\u{1d4ea}\r".escape_unicode(),
+               String::from_str("\\u{1d4ea}\\u{d}"));
+}
+
+#[test]
+fn test_escape_default() {
+    assert_eq!("abc".escape_default(), String::from_str("abc"));
+    assert_eq!("a c".escape_default(), String::from_str("a c"));
+    assert_eq!("\r\n\t".escape_default(), String::from_str("\\r\\n\\t"));
+    assert_eq!("'\"\\".escape_default(), String::from_str("\\'\\\"\\\\"));
+    assert_eq!("\u{100}\u{ffff}".escape_default(),
+               String::from_str("\\u{100}\\u{ffff}"));
+    assert_eq!("\u{10000}\u{10ffff}".escape_default(),
+               String::from_str("\\u{10000}\\u{10ffff}"));
+    assert_eq!("ab\u{fb00}".escape_default(),
+               String::from_str("ab\\u{fb00}"));
+    assert_eq!("\u{1d4ea}\r".escape_default(),
+               String::from_str("\\u{1d4ea}\\r"));
+}
+
+#[test]
+fn test_total_ord() {
+    "1234".cmp("123") == Greater;
+    "123".cmp("1234") == Less;
+    "1234".cmp("1234") == Equal;
+    "12345555".cmp("123456") == Less;
+    "22".cmp("1234") == Greater;
+}
+
+#[test]
+fn test_char_range_at() {
+    let data = "b¢€𤭢𤭢€¢b";
+    assert_eq!('b', data.char_range_at(0).ch);
+    assert_eq!('¢', data.char_range_at(1).ch);
+    assert_eq!('€', data.char_range_at(3).ch);
+    assert_eq!('𤭢', data.char_range_at(6).ch);
+    assert_eq!('𤭢', data.char_range_at(10).ch);
+    assert_eq!('€', data.char_range_at(14).ch);
+    assert_eq!('¢', data.char_range_at(17).ch);
+    assert_eq!('b', data.char_range_at(19).ch);
+}
+
+#[test]
+fn test_char_range_at_reverse_underflow() {
+    assert_eq!("abc".char_range_at_reverse(0).next, 0);
+}
+
+#[test]
+fn test_iterator() {
+    let s = "ศไทย中华Việt Nam";
+    let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
+
+    let mut pos = 0;
+    let it = s.chars();
+
+    for c in it {
+        assert_eq!(c, v[pos]);
+        pos += 1;
+    }
+    assert_eq!(pos, v.len());
+}
+
+#[test]
+fn test_rev_iterator() {
+    let s = "ศไทย中华Việt Nam";
+    let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
+
+    let mut pos = 0;
+    let it = s.chars().rev();
+
+    for c in it {
+        assert_eq!(c, v[pos]);
+        pos += 1;
+    }
+    assert_eq!(pos, v.len());
+}
+
+#[test]
+fn test_chars_decoding() {
+    let mut bytes = [0; 4];
+    for c in (0..0x110000).filter_map(::std::char::from_u32) {
+        let len = c.encode_utf8(&mut bytes).unwrap_or(0);
+        let s = ::std::str::from_utf8(&bytes[..len]).unwrap();
+        if Some(c) != s.chars().next() {
+            panic!("character {:x}={} does not decode correctly", c as u32, c);
+        }
+    }
+}
+
+#[test]
+fn test_chars_rev_decoding() {
+    let mut bytes = [0; 4];
+    for c in (0..0x110000).filter_map(::std::char::from_u32) {
+        let len = c.encode_utf8(&mut bytes).unwrap_or(0);
+        let s = ::std::str::from_utf8(&bytes[..len]).unwrap();
+        if Some(c) != s.chars().rev().next() {
+            panic!("character {:x}={} does not decode correctly", c as u32, c);
+        }
+    }
+}
+
+#[test]
+fn test_iterator_clone() {
+    let s = "ศไทย中华Việt Nam";
+    let mut it = s.chars();
+    it.next();
+    assert!(it.clone().zip(it).all(|(x,y)| x == y));
+}
+
+#[test]
+fn test_bytesator() {
+    let s = "ศไทย中华Việt Nam";
+    let v = [
+        224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
+        184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
+        109
+    ];
+    let mut pos = 0;
+
+    for b in s.bytes() {
+        assert_eq!(b, v[pos]);
+        pos += 1;
+    }
+}
+
+#[test]
+fn test_bytes_revator() {
+    let s = "ศไทย中华Việt Nam";
+    let v = [
+        224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
+        184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
+        109
+    ];
+    let mut pos = v.len();
+
+    for b in s.bytes().rev() {
+        pos -= 1;
+        assert_eq!(b, v[pos]);
+    }
+}
+
+#[test]
+fn test_char_indicesator() {
+    let s = "ศไทย中华Việt Nam";
+    let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
+    let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
+
+    let mut pos = 0;
+    let it = s.char_indices();
+
+    for c in it {
+        assert_eq!(c, (p[pos], v[pos]));
+        pos += 1;
+    }
+    assert_eq!(pos, v.len());
+    assert_eq!(pos, p.len());
+}
+
+#[test]
+fn test_char_indices_revator() {
+    let s = "ศไทย中华Việt Nam";
+    let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
+    let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
+
+    let mut pos = 0;
+    let it = s.char_indices().rev();
+
+    for c in it {
+        assert_eq!(c, (p[pos], v[pos]));
+        pos += 1;
+    }
+    assert_eq!(pos, v.len());
+    assert_eq!(pos, p.len());
+}
+
+#[test]
+fn test_splitn_char_iterator() {
+    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+    let split: Vec<&str> = data.splitn(3, ' ').collect();
+    assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
+
+    let split: Vec<&str> = data.splitn(3, |c: char| c == ' ').collect();
+    assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
+
+    // Unicode
+    let split: Vec<&str> = data.splitn(3, 'ä').collect();
+    assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
+
+    let split: Vec<&str> = data.splitn(3, |c: char| c == 'ä').collect();
+    assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
+}
+
+#[test]
+fn test_split_char_iterator_no_trailing() {
+    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+    let split: Vec<&str> = data.split('\n').collect();
+    assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
+
+    let split: Vec<&str> = data.split_terminator('\n').collect();
+    assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
+}
+
+#[test]
+fn test_words() {
+    let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
+    let words: Vec<&str> = data.words().collect();
+    assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
+}
+
+#[test]
+fn test_nfd_chars() {
+    macro_rules! t {
+        ($input: expr, $expected: expr) => {
+            assert_eq!($input.nfd_chars().collect::<String>(), $expected);
+        }
+    }
+    t!("abc", "abc");
+    t!("\u{1e0b}\u{1c4}", "d\u{307}\u{1c4}");
+    t!("\u{2026}", "\u{2026}");
+    t!("\u{2126}", "\u{3a9}");
+    t!("\u{1e0b}\u{323}", "d\u{323}\u{307}");
+    t!("\u{1e0d}\u{307}", "d\u{323}\u{307}");
+    t!("a\u{301}", "a\u{301}");
+    t!("\u{301}a", "\u{301}a");
+    t!("\u{d4db}", "\u{1111}\u{1171}\u{11b6}");
+    t!("\u{ac1c}", "\u{1100}\u{1162}");
+}
+
+#[test]
+fn test_nfkd_chars() {
+    macro_rules! t {
+        ($input: expr, $expected: expr) => {
+            assert_eq!($input.nfkd_chars().collect::<String>(), $expected);
+        }
+    }
+    t!("abc", "abc");
+    t!("\u{1e0b}\u{1c4}", "d\u{307}DZ\u{30c}");
+    t!("\u{2026}", "...");
+    t!("\u{2126}", "\u{3a9}");
+    t!("\u{1e0b}\u{323}", "d\u{323}\u{307}");
+    t!("\u{1e0d}\u{307}", "d\u{323}\u{307}");
+    t!("a\u{301}", "a\u{301}");
+    t!("\u{301}a", "\u{301}a");
+    t!("\u{d4db}", "\u{1111}\u{1171}\u{11b6}");
+    t!("\u{ac1c}", "\u{1100}\u{1162}");
+}
+
+#[test]
+fn test_nfc_chars() {
+    macro_rules! t {
+        ($input: expr, $expected: expr) => {
+            assert_eq!($input.nfc_chars().collect::<String>(), $expected);
+        }
+    }
+    t!("abc", "abc");
+    t!("\u{1e0b}\u{1c4}", "\u{1e0b}\u{1c4}");
+    t!("\u{2026}", "\u{2026}");
+    t!("\u{2126}", "\u{3a9}");
+    t!("\u{1e0b}\u{323}", "\u{1e0d}\u{307}");
+    t!("\u{1e0d}\u{307}", "\u{1e0d}\u{307}");
+    t!("a\u{301}", "\u{e1}");
+    t!("\u{301}a", "\u{301}a");
+    t!("\u{d4db}", "\u{d4db}");
+    t!("\u{ac1c}", "\u{ac1c}");
+    t!("a\u{300}\u{305}\u{315}\u{5ae}b", "\u{e0}\u{5ae}\u{305}\u{315}b");
+}
+
+#[test]
+fn test_nfkc_chars() {
+    macro_rules! t {
+        ($input: expr, $expected: expr) => {
+            assert_eq!($input.nfkc_chars().collect::<String>(), $expected);
+        }
+    }
+    t!("abc", "abc");
+    t!("\u{1e0b}\u{1c4}", "\u{1e0b}D\u{17d}");
+    t!("\u{2026}", "...");
+    t!("\u{2126}", "\u{3a9}");
+    t!("\u{1e0b}\u{323}", "\u{1e0d}\u{307}");
+    t!("\u{1e0d}\u{307}", "\u{1e0d}\u{307}");
+    t!("a\u{301}", "\u{e1}");
+    t!("\u{301}a", "\u{301}a");
+    t!("\u{d4db}", "\u{d4db}");
+    t!("\u{ac1c}", "\u{ac1c}");
+    t!("a\u{300}\u{305}\u{315}\u{5ae}b", "\u{e0}\u{5ae}\u{305}\u{315}b");
+}
+
+#[test]
+fn test_lines() {
+    let data = "\nMäry häd ä little lämb\n\nLittle lämb\n";
+    let lines: Vec<&str> = data.lines().collect();
+    assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
+
+    let data = "\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
+    let lines: Vec<&str> = data.lines().collect();
+    assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
+}
+
+#[test]
+fn test_graphemes() {
+    use std::iter::order;
+
+    // official Unicode test data
+    // from http://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakTest.txt
+    let test_same: [(_, &[_]); 325] = [
+        ("\u{20}\u{20}", &["\u{20}", "\u{20}"]),
+        ("\u{20}\u{308}\u{20}", &["\u{20}\u{308}", "\u{20}"]),
+        ("\u{20}\u{D}", &["\u{20}", "\u{D}"]),
+        ("\u{20}\u{308}\u{D}", &["\u{20}\u{308}", "\u{D}"]),
+        ("\u{20}\u{A}", &["\u{20}", "\u{A}"]),
+        ("\u{20}\u{308}\u{A}", &["\u{20}\u{308}", "\u{A}"]),
+        ("\u{20}\u{1}", &["\u{20}", "\u{1}"]),
+        ("\u{20}\u{308}\u{1}", &["\u{20}\u{308}", "\u{1}"]),
+        ("\u{20}\u{300}", &["\u{20}\u{300}"]),
+        ("\u{20}\u{308}\u{300}", &["\u{20}\u{308}\u{300}"]),
+        ("\u{20}\u{1100}", &["\u{20}", "\u{1100}"]),
+        ("\u{20}\u{308}\u{1100}", &["\u{20}\u{308}", "\u{1100}"]),
+        ("\u{20}\u{1160}", &["\u{20}", "\u{1160}"]),
+        ("\u{20}\u{308}\u{1160}", &["\u{20}\u{308}", "\u{1160}"]),
+        ("\u{20}\u{11A8}", &["\u{20}", "\u{11A8}"]),
+        ("\u{20}\u{308}\u{11A8}", &["\u{20}\u{308}", "\u{11A8}"]),
+        ("\u{20}\u{AC00}", &["\u{20}", "\u{AC00}"]),
+        ("\u{20}\u{308}\u{AC00}", &["\u{20}\u{308}", "\u{AC00}"]),
+        ("\u{20}\u{AC01}", &["\u{20}", "\u{AC01}"]),
+        ("\u{20}\u{308}\u{AC01}", &["\u{20}\u{308}", "\u{AC01}"]),
+        ("\u{20}\u{1F1E6}", &["\u{20}", "\u{1F1E6}"]),
+        ("\u{20}\u{308}\u{1F1E6}", &["\u{20}\u{308}", "\u{1F1E6}"]),
+        ("\u{20}\u{378}", &["\u{20}", "\u{378}"]),
+        ("\u{20}\u{308}\u{378}", &["\u{20}\u{308}", "\u{378}"]),
+        ("\u{D}\u{20}", &["\u{D}", "\u{20}"]),
+        ("\u{D}\u{308}\u{20}", &["\u{D}", "\u{308}", "\u{20}"]),
+        ("\u{D}\u{D}", &["\u{D}", "\u{D}"]),
+        ("\u{D}\u{308}\u{D}", &["\u{D}", "\u{308}", "\u{D}"]),
+        ("\u{D}\u{A}", &["\u{D}\u{A}"]),
+        ("\u{D}\u{308}\u{A}", &["\u{D}", "\u{308}", "\u{A}"]),
+        ("\u{D}\u{1}", &["\u{D}", "\u{1}"]),
+        ("\u{D}\u{308}\u{1}", &["\u{D}", "\u{308}", "\u{1}"]),
+        ("\u{D}\u{300}", &["\u{D}", "\u{300}"]),
+        ("\u{D}\u{308}\u{300}", &["\u{D}", "\u{308}\u{300}"]),
+        ("\u{D}\u{903}", &["\u{D}", "\u{903}"]),
+        ("\u{D}\u{1100}", &["\u{D}", "\u{1100}"]),
+        ("\u{D}\u{308}\u{1100}", &["\u{D}", "\u{308}", "\u{1100}"]),
+        ("\u{D}\u{1160}", &["\u{D}", "\u{1160}"]),
+        ("\u{D}\u{308}\u{1160}", &["\u{D}", "\u{308}", "\u{1160}"]),
+        ("\u{D}\u{11A8}", &["\u{D}", "\u{11A8}"]),
+        ("\u{D}\u{308}\u{11A8}", &["\u{D}", "\u{308}", "\u{11A8}"]),
+        ("\u{D}\u{AC00}", &["\u{D}", "\u{AC00}"]),
+        ("\u{D}\u{308}\u{AC00}", &["\u{D}", "\u{308}", "\u{AC00}"]),
+        ("\u{D}\u{AC01}", &["\u{D}", "\u{AC01}"]),
+        ("\u{D}\u{308}\u{AC01}", &["\u{D}", "\u{308}", "\u{AC01}"]),
+        ("\u{D}\u{1F1E6}", &["\u{D}", "\u{1F1E6}"]),
+        ("\u{D}\u{308}\u{1F1E6}", &["\u{D}", "\u{308}", "\u{1F1E6}"]),
+        ("\u{D}\u{378}", &["\u{D}", "\u{378}"]),
+        ("\u{D}\u{308}\u{378}", &["\u{D}", "\u{308}", "\u{378}"]),
+        ("\u{A}\u{20}", &["\u{A}", "\u{20}"]),
+        ("\u{A}\u{308}\u{20}", &["\u{A}", "\u{308}", "\u{20}"]),
+        ("\u{A}\u{D}", &["\u{A}", "\u{D}"]),
+        ("\u{A}\u{308}\u{D}", &["\u{A}", "\u{308}", "\u{D}"]),
+        ("\u{A}\u{A}", &["\u{A}", "\u{A}"]),
+        ("\u{A}\u{308}\u{A}", &["\u{A}", "\u{308}", "\u{A}"]),
+        ("\u{A}\u{1}", &["\u{A}", "\u{1}"]),
+        ("\u{A}\u{308}\u{1}", &["\u{A}", "\u{308}", "\u{1}"]),
+        ("\u{A}\u{300}", &["\u{A}", "\u{300}"]),
+        ("\u{A}\u{308}\u{300}", &["\u{A}", "\u{308}\u{300}"]),
+        ("\u{A}\u{903}", &["\u{A}", "\u{903}"]),
+        ("\u{A}\u{1100}", &["\u{A}", "\u{1100}"]),
+        ("\u{A}\u{308}\u{1100}", &["\u{A}", "\u{308}", "\u{1100}"]),
+        ("\u{A}\u{1160}", &["\u{A}", "\u{1160}"]),
+        ("\u{A}\u{308}\u{1160}", &["\u{A}", "\u{308}", "\u{1160}"]),
+        ("\u{A}\u{11A8}", &["\u{A}", "\u{11A8}"]),
+        ("\u{A}\u{308}\u{11A8}", &["\u{A}", "\u{308}", "\u{11A8}"]),
+        ("\u{A}\u{AC00}", &["\u{A}", "\u{AC00}"]),
+        ("\u{A}\u{308}\u{AC00}", &["\u{A}", "\u{308}", "\u{AC00}"]),
+        ("\u{A}\u{AC01}", &["\u{A}", "\u{AC01}"]),
+        ("\u{A}\u{308}\u{AC01}", &["\u{A}", "\u{308}", "\u{AC01}"]),
+        ("\u{A}\u{1F1E6}", &["\u{A}", "\u{1F1E6}"]),
+        ("\u{A}\u{308}\u{1F1E6}", &["\u{A}", "\u{308}", "\u{1F1E6}"]),
+        ("\u{A}\u{378}", &["\u{A}", "\u{378}"]),
+        ("\u{A}\u{308}\u{378}", &["\u{A}", "\u{308}", "\u{378}"]),
+        ("\u{1}\u{20}", &["\u{1}", "\u{20}"]),
+        ("\u{1}\u{308}\u{20}", &["\u{1}", "\u{308}", "\u{20}"]),
+        ("\u{1}\u{D}", &["\u{1}", "\u{D}"]),
+        ("\u{1}\u{308}\u{D}", &["\u{1}", "\u{308}", "\u{D}"]),
+        ("\u{1}\u{A}", &["\u{1}", "\u{A}"]),
+        ("\u{1}\u{308}\u{A}", &["\u{1}", "\u{308}", "\u{A}"]),
+        ("\u{1}\u{1}", &["\u{1}", "\u{1}"]),
+        ("\u{1}\u{308}\u{1}", &["\u{1}", "\u{308}", "\u{1}"]),
+        ("\u{1}\u{300}", &["\u{1}", "\u{300}"]),
+        ("\u{1}\u{308}\u{300}", &["\u{1}", "\u{308}\u{300}"]),
+        ("\u{1}\u{903}", &["\u{1}", "\u{903}"]),
+        ("\u{1}\u{1100}", &["\u{1}", "\u{1100}"]),
+        ("\u{1}\u{308}\u{1100}", &["\u{1}", "\u{308}", "\u{1100}"]),
+        ("\u{1}\u{1160}", &["\u{1}", "\u{1160}"]),
+        ("\u{1}\u{308}\u{1160}", &["\u{1}", "\u{308}", "\u{1160}"]),
+        ("\u{1}\u{11A8}", &["\u{1}", "\u{11A8}"]),
+        ("\u{1}\u{308}\u{11A8}", &["\u{1}", "\u{308}", "\u{11A8}"]),
+        ("\u{1}\u{AC00}", &["\u{1}", "\u{AC00}"]),
+        ("\u{1}\u{308}\u{AC00}", &["\u{1}", "\u{308}", "\u{AC00}"]),
+        ("\u{1}\u{AC01}", &["\u{1}", "\u{AC01}"]),
+        ("\u{1}\u{308}\u{AC01}", &["\u{1}", "\u{308}", "\u{AC01}"]),
+        ("\u{1}\u{1F1E6}", &["\u{1}", "\u{1F1E6}"]),
+        ("\u{1}\u{308}\u{1F1E6}", &["\u{1}", "\u{308}", "\u{1F1E6}"]),
+        ("\u{1}\u{378}", &["\u{1}", "\u{378}"]),
+        ("\u{1}\u{308}\u{378}", &["\u{1}", "\u{308}", "\u{378}"]),
+        ("\u{300}\u{20}", &["\u{300}", "\u{20}"]),
+        ("\u{300}\u{308}\u{20}", &["\u{300}\u{308}", "\u{20}"]),
+        ("\u{300}\u{D}", &["\u{300}", "\u{D}"]),
+        ("\u{300}\u{308}\u{D}", &["\u{300}\u{308}", "\u{D}"]),
+        ("\u{300}\u{A}", &["\u{300}", "\u{A}"]),
+        ("\u{300}\u{308}\u{A}", &["\u{300}\u{308}", "\u{A}"]),
+        ("\u{300}\u{1}", &["\u{300}", "\u{1}"]),
+        ("\u{300}\u{308}\u{1}", &["\u{300}\u{308}", "\u{1}"]),
+        ("\u{300}\u{300}", &["\u{300}\u{300}"]),
+        ("\u{300}\u{308}\u{300}", &["\u{300}\u{308}\u{300}"]),
+        ("\u{300}\u{1100}", &["\u{300}", "\u{1100}"]),
+        ("\u{300}\u{308}\u{1100}", &["\u{300}\u{308}", "\u{1100}"]),
+        ("\u{300}\u{1160}", &["\u{300}", "\u{1160}"]),
+        ("\u{300}\u{308}\u{1160}", &["\u{300}\u{308}", "\u{1160}"]),
+        ("\u{300}\u{11A8}", &["\u{300}", "\u{11A8}"]),
+        ("\u{300}\u{308}\u{11A8}", &["\u{300}\u{308}", "\u{11A8}"]),
+        ("\u{300}\u{AC00}", &["\u{300}", "\u{AC00}"]),
+        ("\u{300}\u{308}\u{AC00}", &["\u{300}\u{308}", "\u{AC00}"]),
+        ("\u{300}\u{AC01}", &["\u{300}", "\u{AC01}"]),
+        ("\u{300}\u{308}\u{AC01}", &["\u{300}\u{308}", "\u{AC01}"]),
+        ("\u{300}\u{1F1E6}", &["\u{300}", "\u{1F1E6}"]),
+        ("\u{300}\u{308}\u{1F1E6}", &["\u{300}\u{308}", "\u{1F1E6}"]),
+        ("\u{300}\u{378}", &["\u{300}", "\u{378}"]),
+        ("\u{300}\u{308}\u{378}", &["\u{300}\u{308}", "\u{378}"]),
+        ("\u{903}\u{20}", &["\u{903}", "\u{20}"]),
+        ("\u{903}\u{308}\u{20}", &["\u{903}\u{308}", "\u{20}"]),
+        ("\u{903}\u{D}", &["\u{903}", "\u{D}"]),
+        ("\u{903}\u{308}\u{D}", &["\u{903}\u{308}", "\u{D}"]),
+        ("\u{903}\u{A}", &["\u{903}", "\u{A}"]),
+        ("\u{903}\u{308}\u{A}", &["\u{903}\u{308}", "\u{A}"]),
+        ("\u{903}\u{1}", &["\u{903}", "\u{1}"]),
+        ("\u{903}\u{308}\u{1}", &["\u{903}\u{308}", "\u{1}"]),
+        ("\u{903}\u{300}", &["\u{903}\u{300}"]),
+        ("\u{903}\u{308}\u{300}", &["\u{903}\u{308}\u{300}"]),
+        ("\u{903}\u{1100}", &["\u{903}", "\u{1100}"]),
+        ("\u{903}\u{308}\u{1100}", &["\u{903}\u{308}", "\u{1100}"]),
+        ("\u{903}\u{1160}", &["\u{903}", "\u{1160}"]),
+        ("\u{903}\u{308}\u{1160}", &["\u{903}\u{308}", "\u{1160}"]),
+        ("\u{903}\u{11A8}", &["\u{903}", "\u{11A8}"]),
+        ("\u{903}\u{308}\u{11A8}", &["\u{903}\u{308}", "\u{11A8}"]),
+        ("\u{903}\u{AC00}", &["\u{903}", "\u{AC00}"]),
+        ("\u{903}\u{308}\u{AC00}", &["\u{903}\u{308}", "\u{AC00}"]),
+        ("\u{903}\u{AC01}", &["\u{903}", "\u{AC01}"]),
+        ("\u{903}\u{308}\u{AC01}", &["\u{903}\u{308}", "\u{AC01}"]),
+        ("\u{903}\u{1F1E6}", &["\u{903}", "\u{1F1E6}"]),
+        ("\u{903}\u{308}\u{1F1E6}", &["\u{903}\u{308}", "\u{1F1E6}"]),
+        ("\u{903}\u{378}", &["\u{903}", "\u{378}"]),
+        ("\u{903}\u{308}\u{378}", &["\u{903}\u{308}", "\u{378}"]),
+        ("\u{1100}\u{20}", &["\u{1100}", "\u{20}"]),
+        ("\u{1100}\u{308}\u{20}", &["\u{1100}\u{308}", "\u{20}"]),
+        ("\u{1100}\u{D}", &["\u{1100}", "\u{D}"]),
+        ("\u{1100}\u{308}\u{D}", &["\u{1100}\u{308}", "\u{D}"]),
+        ("\u{1100}\u{A}", &["\u{1100}", "\u{A}"]),
+        ("\u{1100}\u{308}\u{A}", &["\u{1100}\u{308}", "\u{A}"]),
+        ("\u{1100}\u{1}", &["\u{1100}", "\u{1}"]),
+        ("\u{1100}\u{308}\u{1}", &["\u{1100}\u{308}", "\u{1}"]),
+        ("\u{1100}\u{300}", &["\u{1100}\u{300}"]),
+        ("\u{1100}\u{308}\u{300}", &["\u{1100}\u{308}\u{300}"]),
+        ("\u{1100}\u{1100}", &["\u{1100}\u{1100}"]),
+        ("\u{1100}\u{308}\u{1100}", &["\u{1100}\u{308}", "\u{1100}"]),
+        ("\u{1100}\u{1160}", &["\u{1100}\u{1160}"]),
+        ("\u{1100}\u{308}\u{1160}", &["\u{1100}\u{308}", "\u{1160}"]),
+        ("\u{1100}\u{11A8}", &["\u{1100}", "\u{11A8}"]),
+        ("\u{1100}\u{308}\u{11A8}", &["\u{1100}\u{308}", "\u{11A8}"]),
+        ("\u{1100}\u{AC00}", &["\u{1100}\u{AC00}"]),
+        ("\u{1100}\u{308}\u{AC00}", &["\u{1100}\u{308}", "\u{AC00}"]),
+        ("\u{1100}\u{AC01}", &["\u{1100}\u{AC01}"]),
+        ("\u{1100}\u{308}\u{AC01}", &["\u{1100}\u{308}", "\u{AC01}"]),
+        ("\u{1100}\u{1F1E6}", &["\u{1100}", "\u{1F1E6}"]),
+        ("\u{1100}\u{308}\u{1F1E6}", &["\u{1100}\u{308}", "\u{1F1E6}"]),
+        ("\u{1100}\u{378}", &["\u{1100}", "\u{378}"]),
+        ("\u{1100}\u{308}\u{378}", &["\u{1100}\u{308}", "\u{378}"]),
+        ("\u{1160}\u{20}", &["\u{1160}", "\u{20}"]),
+        ("\u{1160}\u{308}\u{20}", &["\u{1160}\u{308}", "\u{20}"]),
+        ("\u{1160}\u{D}", &["\u{1160}", "\u{D}"]),
+        ("\u{1160}\u{308}\u{D}", &["\u{1160}\u{308}", "\u{D}"]),
+        ("\u{1160}\u{A}", &["\u{1160}", "\u{A}"]),
+        ("\u{1160}\u{308}\u{A}", &["\u{1160}\u{308}", "\u{A}"]),
+        ("\u{1160}\u{1}", &["\u{1160}", "\u{1}"]),
+        ("\u{1160}\u{308}\u{1}", &["\u{1160}\u{308}", "\u{1}"]),
+        ("\u{1160}\u{300}", &["\u{1160}\u{300}"]),
+        ("\u{1160}\u{308}\u{300}", &["\u{1160}\u{308}\u{300}"]),
+        ("\u{1160}\u{1100}", &["\u{1160}", "\u{1100}"]),
+        ("\u{1160}\u{308}\u{1100}", &["\u{1160}\u{308}", "\u{1100}"]),
+        ("\u{1160}\u{1160}", &["\u{1160}\u{1160}"]),
+        ("\u{1160}\u{308}\u{1160}", &["\u{1160}\u{308}", "\u{1160}"]),
+        ("\u{1160}\u{11A8}", &["\u{1160}\u{11A8}"]),
+        ("\u{1160}\u{308}\u{11A8}", &["\u{1160}\u{308}", "\u{11A8}"]),
+        ("\u{1160}\u{AC00}", &["\u{1160}", "\u{AC00}"]),
+        ("\u{1160}\u{308}\u{AC00}", &["\u{1160}\u{308}", "\u{AC00}"]),
+        ("\u{1160}\u{AC01}", &["\u{1160}", "\u{AC01}"]),
+        ("\u{1160}\u{308}\u{AC01}", &["\u{1160}\u{308}", "\u{AC01}"]),
+        ("\u{1160}\u{1F1E6}", &["\u{1160}", "\u{1F1E6}"]),
+        ("\u{1160}\u{308}\u{1F1E6}", &["\u{1160}\u{308}", "\u{1F1E6}"]),
+        ("\u{1160}\u{378}", &["\u{1160}", "\u{378}"]),
+        ("\u{1160}\u{308}\u{378}", &["\u{1160}\u{308}", "\u{378}"]),
+        ("\u{11A8}\u{20}", &["\u{11A8}", "\u{20}"]),
+        ("\u{11A8}\u{308}\u{20}", &["\u{11A8}\u{308}", "\u{20}"]),
+        ("\u{11A8}\u{D}", &["\u{11A8}", "\u{D}"]),
+        ("\u{11A8}\u{308}\u{D}", &["\u{11A8}\u{308}", "\u{D}"]),
+        ("\u{11A8}\u{A}", &["\u{11A8}", "\u{A}"]),
+        ("\u{11A8}\u{308}\u{A}", &["\u{11A8}\u{308}", "\u{A}"]),
+        ("\u{11A8}\u{1}", &["\u{11A8}", "\u{1}"]),
+        ("\u{11A8}\u{308}\u{1}", &["\u{11A8}\u{308}", "\u{1}"]),
+        ("\u{11A8}\u{300}", &["\u{11A8}\u{300}"]),
+        ("\u{11A8}\u{308}\u{300}", &["\u{11A8}\u{308}\u{300}"]),
+        ("\u{11A8}\u{1100}", &["\u{11A8}", "\u{1100}"]),
+        ("\u{11A8}\u{308}\u{1100}", &["\u{11A8}\u{308}", "\u{1100}"]),
+        ("\u{11A8}\u{1160}", &["\u{11A8}", "\u{1160}"]),
+        ("\u{11A8}\u{308}\u{1160}", &["\u{11A8}\u{308}", "\u{1160}"]),
+        ("\u{11A8}\u{11A8}", &["\u{11A8}\u{11A8}"]),
+        ("\u{11A8}\u{308}\u{11A8}", &["\u{11A8}\u{308}", "\u{11A8}"]),
+        ("\u{11A8}\u{AC00}", &["\u{11A8}", "\u{AC00}"]),
+        ("\u{11A8}\u{308}\u{AC00}", &["\u{11A8}\u{308}", "\u{AC00}"]),
+        ("\u{11A8}\u{AC01}", &["\u{11A8}", "\u{AC01}"]),
+        ("\u{11A8}\u{308}\u{AC01}", &["\u{11A8}\u{308}", "\u{AC01}"]),
+        ("\u{11A8}\u{1F1E6}", &["\u{11A8}", "\u{1F1E6}"]),
+        ("\u{11A8}\u{308}\u{1F1E6}", &["\u{11A8}\u{308}", "\u{1F1E6}"]),
+        ("\u{11A8}\u{378}", &["\u{11A8}", "\u{378}"]),
+        ("\u{11A8}\u{308}\u{378}", &["\u{11A8}\u{308}", "\u{378}"]),
+        ("\u{AC00}\u{20}", &["\u{AC00}", "\u{20}"]),
+        ("\u{AC00}\u{308}\u{20}", &["\u{AC00}\u{308}", "\u{20}"]),
+        ("\u{AC00}\u{D}", &["\u{AC00}", "\u{D}"]),
+        ("\u{AC00}\u{308}\u{D}", &["\u{AC00}\u{308}", "\u{D}"]),
+        ("\u{AC00}\u{A}", &["\u{AC00}", "\u{A}"]),
+        ("\u{AC00}\u{308}\u{A}", &["\u{AC00}\u{308}", "\u{A}"]),
+        ("\u{AC00}\u{1}", &["\u{AC00}", "\u{1}"]),
+        ("\u{AC00}\u{308}\u{1}", &["\u{AC00}\u{308}", "\u{1}"]),
+        ("\u{AC00}\u{300}", &["\u{AC00}\u{300}"]),
+        ("\u{AC00}\u{308}\u{300}", &["\u{AC00}\u{308}\u{300}"]),
+        ("\u{AC00}\u{1100}", &["\u{AC00}", "\u{1100}"]),
+        ("\u{AC00}\u{308}\u{1100}", &["\u{AC00}\u{308}", "\u{1100}"]),
+        ("\u{AC00}\u{1160}", &["\u{AC00}\u{1160}"]),
+        ("\u{AC00}\u{308}\u{1160}", &["\u{AC00}\u{308}", "\u{1160}"]),
+        ("\u{AC00}\u{11A8}", &["\u{AC00}\u{11A8}"]),
+        ("\u{AC00}\u{308}\u{11A8}", &["\u{AC00}\u{308}", "\u{11A8}"]),
+        ("\u{AC00}\u{AC00}", &["\u{AC00}", "\u{AC00}"]),
+        ("\u{AC00}\u{308}\u{AC00}", &["\u{AC00}\u{308}", "\u{AC00}"]),
+        ("\u{AC00}\u{AC01}", &["\u{AC00}", "\u{AC01}"]),
+        ("\u{AC00}\u{308}\u{AC01}", &["\u{AC00}\u{308}", "\u{AC01}"]),
+        ("\u{AC00}\u{1F1E6}", &["\u{AC00}", "\u{1F1E6}"]),
+        ("\u{AC00}\u{308}\u{1F1E6}", &["\u{AC00}\u{308}", "\u{1F1E6}"]),
+        ("\u{AC00}\u{378}", &["\u{AC00}", "\u{378}"]),
+        ("\u{AC00}\u{308}\u{378}", &["\u{AC00}\u{308}", "\u{378}"]),
+        ("\u{AC01}\u{20}", &["\u{AC01}", "\u{20}"]),
+        ("\u{AC01}\u{308}\u{20}", &["\u{AC01}\u{308}", "\u{20}"]),
+        ("\u{AC01}\u{D}", &["\u{AC01}", "\u{D}"]),
+        ("\u{AC01}\u{308}\u{D}", &["\u{AC01}\u{308}", "\u{D}"]),
+        ("\u{AC01}\u{A}", &["\u{AC01}", "\u{A}"]),
+        ("\u{AC01}\u{308}\u{A}", &["\u{AC01}\u{308}", "\u{A}"]),
+        ("\u{AC01}\u{1}", &["\u{AC01}", "\u{1}"]),
+        ("\u{AC01}\u{308}\u{1}", &["\u{AC01}\u{308}", "\u{1}"]),
+        ("\u{AC01}\u{300}", &["\u{AC01}\u{300}"]),
+        ("\u{AC01}\u{308}\u{300}", &["\u{AC01}\u{308}\u{300}"]),
+        ("\u{AC01}\u{1100}", &["\u{AC01}", "\u{1100}"]),
+        ("\u{AC01}\u{308}\u{1100}", &["\u{AC01}\u{308}", "\u{1100}"]),
+        ("\u{AC01}\u{1160}", &["\u{AC01}", "\u{1160}"]),
+        ("\u{AC01}\u{308}\u{1160}", &["\u{AC01}\u{308}", "\u{1160}"]),
+        ("\u{AC01}\u{11A8}", &["\u{AC01}\u{11A8}"]),
+        ("\u{AC01}\u{308}\u{11A8}", &["\u{AC01}\u{308}", "\u{11A8}"]),
+        ("\u{AC01}\u{AC00}", &["\u{AC01}", "\u{AC00}"]),
+        ("\u{AC01}\u{308}\u{AC00}", &["\u{AC01}\u{308}", "\u{AC00}"]),
+        ("\u{AC01}\u{AC01}", &["\u{AC01}", "\u{AC01}"]),
+        ("\u{AC01}\u{308}\u{AC01}", &["\u{AC01}\u{308}", "\u{AC01}"]),
+        ("\u{AC01}\u{1F1E6}", &["\u{AC01}", "\u{1F1E6}"]),
+        ("\u{AC01}\u{308}\u{1F1E6}", &["\u{AC01}\u{308}", "\u{1F1E6}"]),
+        ("\u{AC01}\u{378}", &["\u{AC01}", "\u{378}"]),
+        ("\u{AC01}\u{308}\u{378}", &["\u{AC01}\u{308}", "\u{378}"]),
+        ("\u{1F1E6}\u{20}", &["\u{1F1E6}", "\u{20}"]),
+        ("\u{1F1E6}\u{308}\u{20}", &["\u{1F1E6}\u{308}", "\u{20}"]),
+        ("\u{1F1E6}\u{D}", &["\u{1F1E6}", "\u{D}"]),
+        ("\u{1F1E6}\u{308}\u{D}", &["\u{1F1E6}\u{308}", "\u{D}"]),
+        ("\u{1F1E6}\u{A}", &["\u{1F1E6}", "\u{A}"]),
+        ("\u{1F1E6}\u{308}\u{A}", &["\u{1F1E6}\u{308}", "\u{A}"]),
+        ("\u{1F1E6}\u{1}", &["\u{1F1E6}", "\u{1}"]),
+        ("\u{1F1E6}\u{308}\u{1}", &["\u{1F1E6}\u{308}", "\u{1}"]),
+        ("\u{1F1E6}\u{300}", &["\u{1F1E6}\u{300}"]),
+        ("\u{1F1E6}\u{308}\u{300}", &["\u{1F1E6}\u{308}\u{300}"]),
+        ("\u{1F1E6}\u{1100}", &["\u{1F1E6}", "\u{1100}"]),
+        ("\u{1F1E6}\u{308}\u{1100}", &["\u{1F1E6}\u{308}", "\u{1100}"]),
+        ("\u{1F1E6}\u{1160}", &["\u{1F1E6}", "\u{1160}"]),
+        ("\u{1F1E6}\u{308}\u{1160}", &["\u{1F1E6}\u{308}", "\u{1160}"]),
+        ("\u{1F1E6}\u{11A8}", &["\u{1F1E6}", "\u{11A8}"]),
+        ("\u{1F1E6}\u{308}\u{11A8}", &["\u{1F1E6}\u{308}", "\u{11A8}"]),
+        ("\u{1F1E6}\u{AC00}", &["\u{1F1E6}", "\u{AC00}"]),
+        ("\u{1F1E6}\u{308}\u{AC00}", &["\u{1F1E6}\u{308}", "\u{AC00}"]),
+        ("\u{1F1E6}\u{AC01}", &["\u{1F1E6}", "\u{AC01}"]),
+        ("\u{1F1E6}\u{308}\u{AC01}", &["\u{1F1E6}\u{308}", "\u{AC01}"]),
+        ("\u{1F1E6}\u{1F1E6}", &["\u{1F1E6}\u{1F1E6}"]),
+        ("\u{1F1E6}\u{308}\u{1F1E6}", &["\u{1F1E6}\u{308}", "\u{1F1E6}"]),
+        ("\u{1F1E6}\u{378}", &["\u{1F1E6}", "\u{378}"]),
+        ("\u{1F1E6}\u{308}\u{378}", &["\u{1F1E6}\u{308}", "\u{378}"]),
+        ("\u{378}\u{20}", &["\u{378}", "\u{20}"]),
+        ("\u{378}\u{308}\u{20}", &["\u{378}\u{308}", "\u{20}"]),
+        ("\u{378}\u{D}", &["\u{378}", "\u{D}"]),
+        ("\u{378}\u{308}\u{D}", &["\u{378}\u{308}", "\u{D}"]),
+        ("\u{378}\u{A}", &["\u{378}", "\u{A}"]),
+        ("\u{378}\u{308}\u{A}", &["\u{378}\u{308}", "\u{A}"]),
+        ("\u{378}\u{1}", &["\u{378}", "\u{1}"]),
+        ("\u{378}\u{308}\u{1}", &["\u{378}\u{308}", "\u{1}"]),
+        ("\u{378}\u{300}", &["\u{378}\u{300}"]),
+        ("\u{378}\u{308}\u{300}", &["\u{378}\u{308}\u{300}"]),
+        ("\u{378}\u{1100}", &["\u{378}", "\u{1100}"]),
+        ("\u{378}\u{308}\u{1100}", &["\u{378}\u{308}", "\u{1100}"]),
+        ("\u{378}\u{1160}", &["\u{378}", "\u{1160}"]),
+        ("\u{378}\u{308}\u{1160}", &["\u{378}\u{308}", "\u{1160}"]),
+        ("\u{378}\u{11A8}", &["\u{378}", "\u{11A8}"]),
+        ("\u{378}\u{308}\u{11A8}", &["\u{378}\u{308}", "\u{11A8}"]),
+        ("\u{378}\u{AC00}", &["\u{378}", "\u{AC00}"]),
+        ("\u{378}\u{308}\u{AC00}", &["\u{378}\u{308}", "\u{AC00}"]),
+        ("\u{378}\u{AC01}", &["\u{378}", "\u{AC01}"]),
+        ("\u{378}\u{308}\u{AC01}", &["\u{378}\u{308}", "\u{AC01}"]),
+        ("\u{378}\u{1F1E6}", &["\u{378}", "\u{1F1E6}"]),
+        ("\u{378}\u{308}\u{1F1E6}", &["\u{378}\u{308}", "\u{1F1E6}"]),
+        ("\u{378}\u{378}", &["\u{378}", "\u{378}"]),
+        ("\u{378}\u{308}\u{378}", &["\u{378}\u{308}", "\u{378}"]),
+        ("\u{61}\u{1F1E6}\u{62}", &["\u{61}", "\u{1F1E6}", "\u{62}"]),
+        ("\u{1F1F7}\u{1F1FA}", &["\u{1F1F7}\u{1F1FA}"]),
+        ("\u{1F1F7}\u{1F1FA}\u{1F1F8}", &["\u{1F1F7}\u{1F1FA}\u{1F1F8}"]),
+        ("\u{1F1F7}\u{1F1FA}\u{1F1F8}\u{1F1EA}",
+        &["\u{1F1F7}\u{1F1FA}\u{1F1F8}\u{1F1EA}"]),
+        ("\u{1F1F7}\u{1F1FA}\u{200B}\u{1F1F8}\u{1F1EA}",
+         &["\u{1F1F7}\u{1F1FA}", "\u{200B}", "\u{1F1F8}\u{1F1EA}"]),
+        ("\u{1F1E6}\u{1F1E7}\u{1F1E8}", &["\u{1F1E6}\u{1F1E7}\u{1F1E8}"]),
+        ("\u{1F1E6}\u{200D}\u{1F1E7}\u{1F1E8}", &["\u{1F1E6}\u{200D}",
+         "\u{1F1E7}\u{1F1E8}"]),
+        ("\u{1F1E6}\u{1F1E7}\u{200D}\u{1F1E8}",
+         &["\u{1F1E6}\u{1F1E7}\u{200D}", "\u{1F1E8}"]),
+        ("\u{20}\u{200D}\u{646}", &["\u{20}\u{200D}", "\u{646}"]),
+        ("\u{646}\u{200D}\u{20}", &["\u{646}\u{200D}", "\u{20}"]),
+    ];
+
+    let test_diff: [(_, &[_], &[_]); 23] = [
+        ("\u{20}\u{903}", &["\u{20}\u{903}"], &["\u{20}", "\u{903}"]), ("\u{20}\u{308}\u{903}",
+        &["\u{20}\u{308}\u{903}"], &["\u{20}\u{308}", "\u{903}"]), ("\u{D}\u{308}\u{903}",
+        &["\u{D}", "\u{308}\u{903}"], &["\u{D}", "\u{308}", "\u{903}"]), ("\u{A}\u{308}\u{903}",
+        &["\u{A}", "\u{308}\u{903}"], &["\u{A}", "\u{308}", "\u{903}"]), ("\u{1}\u{308}\u{903}",
+        &["\u{1}", "\u{308}\u{903}"], &["\u{1}", "\u{308}", "\u{903}"]), ("\u{300}\u{903}",
+        &["\u{300}\u{903}"], &["\u{300}", "\u{903}"]), ("\u{300}\u{308}\u{903}",
+        &["\u{300}\u{308}\u{903}"], &["\u{300}\u{308}", "\u{903}"]), ("\u{903}\u{903}",
+        &["\u{903}\u{903}"], &["\u{903}", "\u{903}"]), ("\u{903}\u{308}\u{903}",
+        &["\u{903}\u{308}\u{903}"], &["\u{903}\u{308}", "\u{903}"]), ("\u{1100}\u{903}",
+        &["\u{1100}\u{903}"], &["\u{1100}", "\u{903}"]), ("\u{1100}\u{308}\u{903}",
+        &["\u{1100}\u{308}\u{903}"], &["\u{1100}\u{308}", "\u{903}"]), ("\u{1160}\u{903}",
+        &["\u{1160}\u{903}"], &["\u{1160}", "\u{903}"]), ("\u{1160}\u{308}\u{903}",
+        &["\u{1160}\u{308}\u{903}"], &["\u{1160}\u{308}", "\u{903}"]), ("\u{11A8}\u{903}",
+        &["\u{11A8}\u{903}"], &["\u{11A8}", "\u{903}"]), ("\u{11A8}\u{308}\u{903}",
+        &["\u{11A8}\u{308}\u{903}"], &["\u{11A8}\u{308}", "\u{903}"]), ("\u{AC00}\u{903}",
+        &["\u{AC00}\u{903}"], &["\u{AC00}", "\u{903}"]), ("\u{AC00}\u{308}\u{903}",
+        &["\u{AC00}\u{308}\u{903}"], &["\u{AC00}\u{308}", "\u{903}"]), ("\u{AC01}\u{903}",
+        &["\u{AC01}\u{903}"], &["\u{AC01}", "\u{903}"]), ("\u{AC01}\u{308}\u{903}",
+        &["\u{AC01}\u{308}\u{903}"], &["\u{AC01}\u{308}", "\u{903}"]), ("\u{1F1E6}\u{903}",
+        &["\u{1F1E6}\u{903}"], &["\u{1F1E6}", "\u{903}"]), ("\u{1F1E6}\u{308}\u{903}",
+        &["\u{1F1E6}\u{308}\u{903}"], &["\u{1F1E6}\u{308}", "\u{903}"]), ("\u{378}\u{903}",
+        &["\u{378}\u{903}"], &["\u{378}", "\u{903}"]), ("\u{378}\u{308}\u{903}",
+        &["\u{378}\u{308}\u{903}"], &["\u{378}\u{308}", "\u{903}"]),
+    ];
+
+    for &(s, g) in &test_same[..] {
+        // test forward iterator
+        assert!(order::equals(s.graphemes(true), g.iter().cloned()));
+        assert!(order::equals(s.graphemes(false), g.iter().cloned()));
+
+        // test reverse iterator
+        assert!(order::equals(s.graphemes(true).rev(), g.iter().rev().cloned()));
+        assert!(order::equals(s.graphemes(false).rev(), g.iter().rev().cloned()));
+    }
+
+    for &(s, gt, gf) in &test_diff {
+        // test forward iterator
+        assert!(order::equals(s.graphemes(true), gt.iter().cloned()));
+        assert!(order::equals(s.graphemes(false), gf.iter().cloned()));
+
+        // test reverse iterator
+        assert!(order::equals(s.graphemes(true).rev(), gt.iter().rev().cloned()));
+        assert!(order::equals(s.graphemes(false).rev(), gf.iter().rev().cloned()));
+    }
+
+    // test the indices iterators
+    let s = "a̐éö̲\r\n";
+    let gr_inds = s.grapheme_indices(true).collect::<Vec<(usize, &str)>>();
+    let b: &[_] = &[(0, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
+    assert_eq!(gr_inds, b);
+    let gr_inds = s.grapheme_indices(true).rev().collect::<Vec<(usize, &str)>>();
+    let b: &[_] = &[(11, "\r\n"), (6, "ö̲"), (3, "é"), (0, "a̐")];
+    assert_eq!(gr_inds, b);
+    let mut gr_inds_iter = s.grapheme_indices(true);
+    {
+        let gr_inds = gr_inds_iter.by_ref();
+        let e1 = gr_inds.size_hint();
+        assert_eq!(e1, (1, Some(13)));
+        let c = gr_inds.count();
+        assert_eq!(c, 4);
+    }
+    let e2 = gr_inds_iter.size_hint();
+    assert_eq!(e2, (0, Some(0)));
+
+    // make sure the reverse iterator does the right thing with "\n" at beginning of string
+    let s = "\n\r\n\r";
+    let gr = s.graphemes(true).rev().collect::<Vec<&str>>();
+    let b: &[_] = &["\r", "\r\n", "\n"];
+    assert_eq!(gr, b);
+}
+
+#[test]
+fn test_split_strator() {
+    fn t(s: &str, sep: &str, u: &[&str]) {
+        let v: Vec<&str> = s.split_str(sep).collect();
+        assert_eq!(v, u);
+    }
+    t("--1233345--", "12345", &["--1233345--"]);
+    t("abc::hello::there", "::", &["abc", "hello", "there"]);
+    t("::hello::there", "::", &["", "hello", "there"]);
+    t("hello::there::", "::", &["hello", "there", ""]);
+    t("::hello::there::", "::", &["", "hello", "there", ""]);
+    t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
+    t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
+    t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
+    t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
+    t("", ".", &[""]);
+    t("zz", "zz", &["",""]);
+    t("ok", "z", &["ok"]);
+    t("zzz", "zz", &["","z"]);
+    t("zzzzz", "zz", &["","","z"]);
+}
+
+#[test]
+fn test_str_default() {
+    use std::default::Default;
+
+    fn t<S: Default + Str>() {
+        let s: S = Default::default();
+        assert_eq!(s.as_slice(), "");
+    }
+
+    t::<&str>();
+    t::<String>();
+}
+
+#[test]
+fn test_str_container() {
+    fn sum_len(v: &[&str]) -> usize {
+        v.iter().map(|x| x.len()).sum()
+    }
+
+    let s = String::from_str("01234");
+    assert_eq!(5, sum_len(&["012", "", "34"]));
+    assert_eq!(5, sum_len(&[&String::from_str("01"),
+                            &String::from_str("2"),
+                            &String::from_str("34"),
+                            &String::from_str("")]));
+    assert_eq!(5, sum_len(&[&s]));
+}
+
+#[test]
+fn test_str_from_utf8() {
+    let xs = b"hello";
+    assert_eq!(from_utf8(xs), Ok("hello"));
+
+    let xs = "ศไทย中华Việt Nam".as_bytes();
+    assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam"));
+
+    let xs = b"hello\xFF";
+    assert_eq!(from_utf8(xs), Err(Utf8Error::TooShort));
+}
+
+mod bench {
+    use test::{Bencher, black_box};
+
+    #[bench]
+    fn char_iterator(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+
+        b.iter(|| s.chars().count());
+    }
+
+    #[bench]
+    fn char_iterator_for(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+
+        b.iter(|| {
+            for ch in s.chars() { black_box(ch); }
+        });
+    }
+
+    #[bench]
+    fn char_iterator_ascii(b: &mut Bencher) {
+        let s = "Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb";
+
+        b.iter(|| s.chars().count());
+    }
+
+    #[bench]
+    fn char_iterator_rev(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+
+        b.iter(|| s.chars().rev().count());
+    }
+
+    #[bench]
+    fn char_iterator_rev_for(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+
+        b.iter(|| {
+            for ch in s.chars().rev() { black_box(ch); }
+        });
+    }
+
+    #[bench]
+    fn char_indicesator(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        let len = s.chars().count();
+
+        b.iter(|| assert_eq!(s.char_indices().count(), len));
+    }
+
+    #[bench]
+    fn char_indicesator_rev(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        let len = s.chars().count();
+
+        b.iter(|| assert_eq!(s.char_indices().rev().count(), len));
+    }
+
+    #[bench]
+    fn split_unicode_ascii(b: &mut Bencher) {
+        let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
+
+        b.iter(|| assert_eq!(s.split('V').count(), 3));
+    }
+
+    #[bench]
+    fn split_ascii(b: &mut Bencher) {
+        let s = "Mary had a little lamb, Little lamb, little-lamb.";
+        let len = s.split(' ').count();
+
+        b.iter(|| assert_eq!(s.split(' ').count(), len));
+    }
+
+    #[bench]
+    fn split_extern_fn(b: &mut Bencher) {
+        let s = "Mary had a little lamb, Little lamb, little-lamb.";
+        let len = s.split(' ').count();
+        fn pred(c: char) -> bool { c == ' ' }
+
+        b.iter(|| assert_eq!(s.split(pred).count(), len));
+    }
+
+    #[bench]
+    fn split_closure(b: &mut Bencher) {
+        let s = "Mary had a little lamb, Little lamb, little-lamb.";
+        let len = s.split(' ').count();
+
+        b.iter(|| assert_eq!(s.split(|c: char| c == ' ').count(), len));
+    }
+
+    #[bench]
+    fn split_slice(b: &mut Bencher) {
+        let s = "Mary had a little lamb, Little lamb, little-lamb.";
+        let len = s.split(' ').count();
+
+        let c: &[char] = &[' '];
+        b.iter(|| assert_eq!(s.split(c).count(), len));
+    }
+
+    #[bench]
+    fn bench_connect(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        let sep = "→";
+        let v = vec![s, s, s, s, s, s, s, s, s, s];
+        b.iter(|| {
+            assert_eq!(v.connect(sep).len(), s.len() * 10 + sep.len() * 9);
+        })
+    }
+
+    #[bench]
+    fn bench_contains_short_short(b: &mut Bencher) {
+        let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
+        let needle = "sit";
+
+        b.iter(|| {
+            assert!(haystack.contains(needle));
+        })
+    }
+
+    #[bench]
+    fn bench_contains_short_long(b: &mut Bencher) {
+        let haystack = "\
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
+ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
+eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
+sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
+tempus vel, gravida nec quam.
+
+In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
+sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
+diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
+lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
+eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
+interdum. Curabitur ut nisi justo.
+
+Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
+mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
+lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
+est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
+felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
+ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
+feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
+Aliquam sit amet placerat lorem.
+
+Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
+mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
+Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
+lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
+suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
+cursus accumsan.
+
+Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
+feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
+vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
+leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
+malesuada sollicitudin quam eu fermentum.";
+        let needle = "english";
+
+        b.iter(|| {
+            assert!(!haystack.contains(needle));
+        })
+    }
+
+    #[bench]
+    fn bench_contains_bad_naive(b: &mut Bencher) {
+        let haystack = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+        let needle = "aaaaaaaab";
+
+        b.iter(|| {
+            assert!(!haystack.contains(needle));
+        })
+    }
+
+    #[bench]
+    fn bench_contains_equal(b: &mut Bencher) {
+        let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
+        let needle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
+
+        b.iter(|| {
+            assert!(haystack.contains(needle));
+        })
+    }
+}
diff --git a/src/libcollectionstest/string.rs b/src/libcollectionstest/string.rs
new file mode 100644
index 00000000000..4768d5e92ac
--- /dev/null
+++ b/src/libcollectionstest/string.rs
@@ -0,0 +1,453 @@
+// 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.
+
+use std::borrow::IntoCow;
+use std::iter::repeat;
+use std::str::Utf8Error;
+use std::string::{CowString, as_string};
+
+use test::Bencher;
+
+#[test]
+fn test_as_string() {
+    let x = "foo";
+    assert_eq!(x, &**as_string(x));
+}
+
+#[test]
+fn test_from_str() {
+  let owned: Option<::std::string::String> = "string".parse().ok();
+  assert_eq!(owned.as_ref().map(|s| &**s), Some("string"));
+}
+
+#[test]
+fn test_unsized_to_string() {
+    let s: &str = "abc";
+    let _: String = (*s).to_string();
+}
+
+#[test]
+fn test_from_utf8() {
+    let xs = b"hello".to_vec();
+    assert_eq!(String::from_utf8(xs).unwrap(),
+               String::from_str("hello"));
+
+    let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
+    assert_eq!(String::from_utf8(xs).unwrap(),
+               String::from_str("ศไทย中华Việt Nam"));
+
+    let xs = b"hello\xFF".to_vec();
+    let err = String::from_utf8(xs).err().unwrap();
+    assert_eq!(err.utf8_error(), Utf8Error::TooShort);
+    assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
+}
+
+#[test]
+fn test_from_utf8_lossy() {
+    let xs = b"hello";
+    let ys: CowString = "hello".into_cow();
+    assert_eq!(String::from_utf8_lossy(xs), ys);
+
+    let xs = "ศไทย中华Việt Nam".as_bytes();
+    let ys: CowString = "ศไทย中华Việt Nam".into_cow();
+    assert_eq!(String::from_utf8_lossy(xs), ys);
+
+    let xs = b"Hello\xC2 There\xFF Goodbye";
+    assert_eq!(String::from_utf8_lossy(xs),
+               String::from_str("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow());
+
+    let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
+    assert_eq!(String::from_utf8_lossy(xs),
+               String::from_str("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow());
+
+    let xs = b"\xF5foo\xF5\x80bar";
+    assert_eq!(String::from_utf8_lossy(xs),
+               String::from_str("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow());
+
+    let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
+    assert_eq!(String::from_utf8_lossy(xs),
+               String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow());
+
+    let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
+    assert_eq!(String::from_utf8_lossy(xs),
+               String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow());
+
+    let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
+    assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}\
+                                           foo\u{10000}bar").into_cow());
+
+    // surrogates
+    let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
+    assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}foo\
+                                           \u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow());
+}
+
+#[test]
+fn test_from_utf16() {
+    let pairs =
+        [(String::from_str("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
+          vec![0xd800, 0xdf45, 0xd800, 0xdf3f,
+            0xd800, 0xdf3b, 0xd800, 0xdf46,
+            0xd800, 0xdf39, 0xd800, 0xdf3b,
+            0xd800, 0xdf30, 0x000a]),
+
+         (String::from_str("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
+          vec![0xd801, 0xdc12, 0xd801,
+            0xdc49, 0xd801, 0xdc2e, 0xd801,
+            0xdc40, 0xd801, 0xdc32, 0xd801,
+            0xdc4b, 0x0020, 0xd801, 0xdc0f,
+            0xd801, 0xdc32, 0xd801, 0xdc4d,
+            0x000a]),
+
+         (String::from_str("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
+          vec![0xd800, 0xdf00, 0xd800, 0xdf16,
+            0xd800, 0xdf0b, 0xd800, 0xdf04,
+            0xd800, 0xdf11, 0xd800, 0xdf09,
+            0x00b7, 0xd800, 0xdf0c, 0xd800,
+            0xdf04, 0xd800, 0xdf15, 0xd800,
+            0xdf04, 0xd800, 0xdf0b, 0xd800,
+            0xdf09, 0xd800, 0xdf11, 0x000a ]),
+
+         (String::from_str("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
+          vec![0xd801, 0xdc8b, 0xd801, 0xdc98,
+            0xd801, 0xdc88, 0xd801, 0xdc91,
+            0xd801, 0xdc9b, 0xd801, 0xdc92,
+            0x0020, 0xd801, 0xdc95, 0xd801,
+            0xdc93, 0x0020, 0xd801, 0xdc88,
+            0xd801, 0xdc9a, 0xd801, 0xdc8d,
+            0x0020, 0xd801, 0xdc8f, 0xd801,
+            0xdc9c, 0xd801, 0xdc92, 0xd801,
+            0xdc96, 0xd801, 0xdc86, 0x0020,
+            0xd801, 0xdc95, 0xd801, 0xdc86,
+            0x000a ]),
+         // Issue #12318, even-numbered non-BMP planes
+         (String::from_str("\u{20000}"),
+          vec![0xD840, 0xDC00])];
+
+    for p in &pairs {
+        let (s, u) = (*p).clone();
+        let s_as_utf16 = s.utf16_units().collect::<Vec<u16>>();
+        let u_as_string = String::from_utf16(&u).unwrap();
+
+        assert!(::unicode::str::is_utf16(&u));
+        assert_eq!(s_as_utf16, u);
+
+        assert_eq!(u_as_string, s);
+        assert_eq!(String::from_utf16_lossy(&u), s);
+
+        assert_eq!(String::from_utf16(&s_as_utf16).unwrap(), s);
+        assert_eq!(u_as_string.utf16_units().collect::<Vec<u16>>(), u);
+    }
+}
+
+#[test]
+fn test_utf16_invalid() {
+    // completely positive cases tested above.
+    // lead + eof
+    assert!(String::from_utf16(&[0xD800]).is_err());
+    // lead + lead
+    assert!(String::from_utf16(&[0xD800, 0xD800]).is_err());
+
+    // isolated trail
+    assert!(String::from_utf16(&[0x0061, 0xDC00]).is_err());
+
+    // general
+    assert!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]).is_err());
+}
+
+#[test]
+fn test_from_utf16_lossy() {
+    // completely positive cases tested above.
+    // lead + eof
+    assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from_str("\u{FFFD}"));
+    // lead + lead
+    assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]),
+               String::from_str("\u{FFFD}\u{FFFD}"));
+
+    // isolated trail
+    assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from_str("a\u{FFFD}"));
+
+    // general
+    assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
+               String::from_str("\u{FFFD}𐒋\u{FFFD}"));
+}
+
+#[test]
+fn test_push_bytes() {
+    let mut s = String::from_str("ABC");
+    unsafe {
+        let mv = s.as_mut_vec();
+        mv.push_all(&[b'D']);
+    }
+    assert_eq!(s, "ABCD");
+}
+
+#[test]
+fn test_push_str() {
+    let mut s = String::new();
+    s.push_str("");
+    assert_eq!(&s[0..], "");
+    s.push_str("abc");
+    assert_eq!(&s[0..], "abc");
+    s.push_str("ประเทศไทย中华Việt Nam");
+    assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam");
+}
+
+#[test]
+fn test_push() {
+    let mut data = String::from_str("ประเทศไทย中");
+    data.push('华');
+    data.push('b'); // 1 byte
+    data.push('¢'); // 2 byte
+    data.push('€'); // 3 byte
+    data.push('𤭢'); // 4 byte
+    assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
+}
+
+#[test]
+fn test_pop() {
+    let mut data = String::from_str("ประเทศไทย中华b¢€𤭢");
+    assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
+    assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
+    assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
+    assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
+    assert_eq!(data.pop().unwrap(), '华');
+    assert_eq!(data, "ประเทศไทย中");
+}
+
+#[test]
+fn test_str_truncate() {
+    let mut s = String::from_str("12345");
+    s.truncate(5);
+    assert_eq!(s, "12345");
+    s.truncate(3);
+    assert_eq!(s, "123");
+    s.truncate(0);
+    assert_eq!(s, "");
+
+    let mut s = String::from_str("12345");
+    let p = s.as_ptr();
+    s.truncate(3);
+    s.push_str("6");
+    let p_ = s.as_ptr();
+    assert_eq!(p_, p);
+}
+
+#[test]
+#[should_panic]
+fn test_str_truncate_invalid_len() {
+    let mut s = String::from_str("12345");
+    s.truncate(6);
+}
+
+#[test]
+#[should_panic]
+fn test_str_truncate_split_codepoint() {
+    let mut s = String::from_str("\u{FC}"); // ü
+    s.truncate(1);
+}
+
+#[test]
+fn test_str_clear() {
+    let mut s = String::from_str("12345");
+    s.clear();
+    assert_eq!(s.len(), 0);
+    assert_eq!(s, "");
+}
+
+#[test]
+fn test_str_add() {
+    let a = String::from_str("12345");
+    let b = a + "2";
+    let b = b + "2";
+    assert_eq!(b.len(), 7);
+    assert_eq!(b, "1234522");
+}
+
+#[test]
+fn remove() {
+    let mut s = "ศไทย中华Việt Nam; foobar".to_string();;
+    assert_eq!(s.remove(0), 'ศ');
+    assert_eq!(s.len(), 33);
+    assert_eq!(s, "ไทย中华Việt Nam; foobar");
+    assert_eq!(s.remove(17), 'ệ');
+    assert_eq!(s, "ไทย中华Vit Nam; foobar");
+}
+
+#[test] #[should_panic]
+fn remove_bad() {
+    "ศ".to_string().remove(1);
+}
+
+#[test]
+fn insert() {
+    let mut s = "foobar".to_string();
+    s.insert(0, 'ệ');
+    assert_eq!(s, "ệfoobar");
+    s.insert(6, 'ย');
+    assert_eq!(s, "ệfooยbar");
+}
+
+#[test] #[should_panic] fn insert_bad1() { "".to_string().insert(1, 't'); }
+#[test] #[should_panic] fn insert_bad2() { "ệ".to_string().insert(1, 't'); }
+
+#[test]
+fn test_slicing() {
+    let s = "foobar".to_string();
+    assert_eq!("foobar", &s[..]);
+    assert_eq!("foo", &s[..3]);
+    assert_eq!("bar", &s[3..]);
+    assert_eq!("oob", &s[1..4]);
+}
+
+#[test]
+fn test_simple_types() {
+    assert_eq!(1.to_string(), "1");
+    assert_eq!((-1).to_string(), "-1");
+    assert_eq!(200.to_string(), "200");
+    assert_eq!(2.to_string(), "2");
+    assert_eq!(true.to_string(), "true");
+    assert_eq!(false.to_string(), "false");
+    assert_eq!(("hi".to_string()).to_string(), "hi");
+}
+
+#[test]
+fn test_vectors() {
+    let x: Vec<i32> = vec![];
+    assert_eq!(format!("{:?}", x), "[]");
+    assert_eq!(format!("{:?}", vec![1]), "[1]");
+    assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
+    assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) ==
+           "[[], [1], [1, 1]]");
+}
+
+#[test]
+fn test_from_iterator() {
+    let s = "ศไทย中华Việt Nam".to_string();
+    let t = "ศไทย中华";
+    let u = "Việt Nam";
+
+    let a: String = s.chars().collect();
+    assert_eq!(s, a);
+
+    let mut b = t.to_string();
+    b.extend(u.chars());
+    assert_eq!(s, b);
+
+    let c: String = vec![t, u].into_iter().collect();
+    assert_eq!(s, c);
+
+    let mut d = t.to_string();
+    d.extend(vec![u].into_iter());
+    assert_eq!(s, d);
+}
+
+#[bench]
+fn bench_with_capacity(b: &mut Bencher) {
+    b.iter(|| {
+        String::with_capacity(100)
+    });
+}
+
+#[bench]
+fn bench_push_str(b: &mut Bencher) {
+    let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+    b.iter(|| {
+        let mut r = String::new();
+        r.push_str(s);
+    });
+}
+
+const REPETITIONS: u64 = 10_000;
+
+#[bench]
+fn bench_push_str_one_byte(b: &mut Bencher) {
+    b.bytes = REPETITIONS;
+    b.iter(|| {
+        let mut r = String::new();
+        for _ in 0..REPETITIONS {
+            r.push_str("a")
+        }
+    });
+}
+
+#[bench]
+fn bench_push_char_one_byte(b: &mut Bencher) {
+    b.bytes = REPETITIONS;
+    b.iter(|| {
+        let mut r = String::new();
+        for _ in 0..REPETITIONS {
+            r.push('a')
+        }
+    });
+}
+
+#[bench]
+fn bench_push_char_two_bytes(b: &mut Bencher) {
+    b.bytes = REPETITIONS * 2;
+    b.iter(|| {
+        let mut r = String::new();
+        for _ in 0..REPETITIONS {
+            r.push('â')
+        }
+    });
+}
+
+#[bench]
+fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
+    let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
+              Lorem ipsum dolor sit amet, consectetur. ";
+
+    assert_eq!(100, s.len());
+    b.iter(|| {
+        let _ = String::from_utf8_lossy(s);
+    });
+}
+
+#[bench]
+fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
+    let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
+    assert_eq!(100, s.len());
+    b.iter(|| {
+        let _ = String::from_utf8_lossy(s);
+    });
+}
+
+#[bench]
+fn from_utf8_lossy_invalid(b: &mut Bencher) {
+    let s = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
+    b.iter(|| {
+        let _ = String::from_utf8_lossy(s);
+    });
+}
+
+#[bench]
+fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
+    let s = repeat(0xf5).take(100).collect::<Vec<_>>();
+    b.iter(|| {
+        let _ = String::from_utf8_lossy(&s);
+    });
+}
+
+#[bench]
+fn bench_exact_size_shrink_to_fit(b: &mut Bencher) {
+    let s = "Hello there, the quick brown fox jumped over the lazy dog! \
+             Lorem ipsum dolor sit amet, consectetur. ";
+    // ensure our operation produces an exact-size string before we benchmark it
+    let mut r = String::with_capacity(s.len());
+    r.push_str(s);
+    assert_eq!(r.len(), r.capacity());
+    b.iter(|| {
+        let mut r = String::with_capacity(s.len());
+        r.push_str(s);
+        r.shrink_to_fit();
+        r
+    });
+}
diff --git a/src/libcollectionstest/vec.rs b/src/libcollectionstest/vec.rs
new file mode 100644
index 00000000000..2923bea9828
--- /dev/null
+++ b/src/libcollectionstest/vec.rs
@@ -0,0 +1,994 @@
+// 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.
+
+use std::iter::{FromIterator, repeat};
+use std::mem::size_of;
+use std::vec::as_vec;
+
+use test::Bencher;
+
+struct DropCounter<'a> {
+    count: &'a mut u32
+}
+
+#[unsafe_destructor]
+impl<'a> Drop for DropCounter<'a> {
+    fn drop(&mut self) {
+        *self.count += 1;
+    }
+}
+
+#[test]
+fn test_as_vec() {
+    let xs = [1u8, 2u8, 3u8];
+    assert_eq!(&**as_vec(&xs), xs);
+}
+
+#[test]
+fn test_as_vec_dtor() {
+    let (mut count_x, mut count_y) = (0, 0);
+    {
+        let xs = &[DropCounter { count: &mut count_x }, DropCounter { count: &mut count_y }];
+        assert_eq!(as_vec(xs).len(), 2);
+    }
+    assert_eq!(count_x, 1);
+    assert_eq!(count_y, 1);
+}
+
+#[test]
+fn test_small_vec_struct() {
+    assert!(size_of::<Vec<u8>>() == size_of::<usize>() * 3);
+}
+
+#[test]
+fn test_double_drop() {
+    struct TwoVec<T> {
+        x: Vec<T>,
+        y: Vec<T>
+    }
+
+    let (mut count_x, mut count_y) = (0, 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() {
+    let mut v = Vec::new();
+    assert_eq!(v.capacity(), 0);
+
+    v.reserve(2);
+    assert!(v.capacity() >= 2);
+
+    for i in 0..16 {
+        v.push(i);
+    }
+
+    assert!(v.capacity() >= 16);
+    v.reserve(16);
+    assert!(v.capacity() >= 32);
+
+    v.push(16);
+
+    v.reserve(16);
+    assert!(v.capacity() >= 33)
+}
+
+#[test]
+fn test_extend() {
+    let mut v = Vec::new();
+    let mut w = Vec::new();
+
+    v.extend(0..3);
+    for i in 0..3 { w.push(i) }
+
+    assert_eq!(v, w);
+
+    v.extend(3..10);
+    for i in 3..10 { w.push(i) }
+
+    assert_eq!(v, w);
+}
+
+#[test]
+fn test_slice_from_mut() {
+    let mut values = vec![1, 2, 3, 4, 5];
+    {
+        let slice = &mut values[2 ..];
+        assert!(slice == [3, 4, 5]);
+        for p in slice {
+            *p += 2;
+        }
+    }
+
+    assert!(values == [1, 2, 5, 6, 7]);
+}
+
+#[test]
+fn test_slice_to_mut() {
+    let mut values = vec![1, 2, 3, 4, 5];
+    {
+        let slice = &mut values[.. 2];
+        assert!(slice == [1, 2]);
+        for p in slice {
+            *p += 1;
+        }
+    }
+
+    assert!(values == [2, 3, 3, 4, 5]);
+}
+
+#[test]
+fn test_split_at_mut() {
+    let mut values = vec![1, 2, 3, 4, 5];
+    {
+        let (left, right) = values.split_at_mut(2);
+        {
+            let left: &[_] = left;
+            assert!(&left[..left.len()] == &[1, 2]);
+        }
+        for p in left {
+            *p += 1;
+        }
+
+        {
+            let right: &[_] = right;
+            assert!(&right[..right.len()] == &[3, 4, 5]);
+        }
+        for p in right {
+            *p += 2;
+        }
+    }
+
+    assert_eq!(values, [2, 3, 5, 6, 7]);
+}
+
+#[test]
+fn test_clone() {
+    let v: Vec<i32> = vec![];
+    let w = vec!(1, 2, 3);
+
+    assert_eq!(v, v.clone());
+
+    let z = w.clone();
+    assert_eq!(w, z);
+    // they should be disjoint in memory.
+    assert!(w.as_ptr() != z.as_ptr())
+}
+
+#[test]
+fn test_clone_from() {
+    let mut v = vec!();
+    let three: Vec<Box<_>> = vec!(box 1, box 2, box 3);
+    let two: Vec<Box<_>> = vec!(box 4, box 5);
+    // zero, long
+    v.clone_from(&three);
+    assert_eq!(v, three);
+
+    // equal
+    v.clone_from(&three);
+    assert_eq!(v, three);
+
+    // long, short
+    v.clone_from(&two);
+    assert_eq!(v, two);
+
+    // short, long
+    v.clone_from(&three);
+    assert_eq!(v, three)
+}
+
+#[test]
+fn test_retain() {
+    let mut vec = vec![1, 2, 3, 4];
+    vec.retain(|&x| x % 2 == 0);
+    assert_eq!(vec, [2, 4]);
+}
+
+#[test]
+fn zero_sized_values() {
+    let mut v = Vec::new();
+    assert_eq!(v.len(), 0);
+    v.push(());
+    assert_eq!(v.len(), 1);
+    v.push(());
+    assert_eq!(v.len(), 2);
+    assert_eq!(v.pop(), Some(()));
+    assert_eq!(v.pop(), Some(()));
+    assert_eq!(v.pop(), None);
+
+    assert_eq!(v.iter().count(), 0);
+    v.push(());
+    assert_eq!(v.iter().count(), 1);
+    v.push(());
+    assert_eq!(v.iter().count(), 2);
+
+    for &() in &v {}
+
+    assert_eq!(v.iter_mut().count(), 2);
+    v.push(());
+    assert_eq!(v.iter_mut().count(), 3);
+    v.push(());
+    assert_eq!(v.iter_mut().count(), 4);
+
+    for &mut () in &mut v {}
+    unsafe { v.set_len(0); }
+    assert_eq!(v.iter_mut().count(), 0);
+}
+
+#[test]
+fn test_partition() {
+    assert_eq!(vec![].into_iter().partition(|x: &i32| *x < 3), (vec![], vec![]));
+    assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 4), (vec![1, 2, 3], vec![]));
+    assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 2), (vec![1], vec![2, 3]));
+    assert_eq!(vec![1, 2, 3].into_iter().partition(|x| *x < 0), (vec![], vec![1, 2, 3]));
+}
+
+#[test]
+fn test_zip_unzip() {
+    let z1 = vec![(1, 4), (2, 5), (3, 6)];
+
+    let (left, right): (Vec<_>, Vec<_>) = z1.iter().cloned().unzip();
+
+    assert_eq!((1, 4), (left[0], right[0]));
+    assert_eq!((2, 5), (left[1], right[1]));
+    assert_eq!((3, 6), (left[2], right[2]));
+}
+
+#[test]
+fn test_unsafe_ptrs() {
+    unsafe {
+        // Test on-stack copy-from-buf.
+        let a = [1, 2, 3];
+        let ptr = a.as_ptr();
+        let b = Vec::from_raw_buf(ptr, 3);
+        assert_eq!(b, [1, 2, 3]);
+
+        // Test on-heap copy-from-buf.
+        let c = vec![1, 2, 3, 4, 5];
+        let ptr = c.as_ptr();
+        let d = Vec::from_raw_buf(ptr, 5);
+        assert_eq!(d, [1, 2, 3, 4, 5]);
+    }
+}
+
+#[test]
+fn test_vec_truncate_drop() {
+    static mut drops: u32 = 0;
+    struct Elem(i32);
+    impl Drop for Elem {
+        fn drop(&mut self) {
+            unsafe { drops += 1; }
+        }
+    }
+
+    let mut v = vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
+    assert_eq!(unsafe { drops }, 0);
+    v.truncate(3);
+    assert_eq!(unsafe { drops }, 2);
+    v.truncate(0);
+    assert_eq!(unsafe { drops }, 5);
+}
+
+#[test]
+#[should_panic]
+fn test_vec_truncate_fail() {
+    struct BadElem(i32);
+    impl Drop for BadElem {
+        fn drop(&mut self) {
+            let BadElem(ref mut x) = *self;
+            if *x == 0xbadbeef {
+                panic!("BadElem panic: 0xbadbeef")
+            }
+        }
+    }
+
+    let mut v = vec![BadElem(1), BadElem(2), BadElem(0xbadbeef), BadElem(4)];
+    v.truncate(0);
+}
+
+#[test]
+fn test_index() {
+    let vec = vec![1, 2, 3];
+    assert!(vec[1] == 2);
+}
+
+#[test]
+#[should_panic]
+fn test_index_out_of_bounds() {
+    let vec = vec![1, 2, 3];
+    let _ = vec[3];
+}
+
+#[test]
+#[should_panic]
+fn test_slice_out_of_bounds_1() {
+    let x = vec![1, 2, 3, 4, 5];
+    &x[-1..];
+}
+
+#[test]
+#[should_panic]
+fn test_slice_out_of_bounds_2() {
+    let x = vec![1, 2, 3, 4, 5];
+    &x[..6];
+}
+
+#[test]
+#[should_panic]
+fn test_slice_out_of_bounds_3() {
+    let x = vec![1, 2, 3, 4, 5];
+    &x[-1..4];
+}
+
+#[test]
+#[should_panic]
+fn test_slice_out_of_bounds_4() {
+    let x = vec![1, 2, 3, 4, 5];
+    &x[1..6];
+}
+
+#[test]
+#[should_panic]
+fn test_slice_out_of_bounds_5() {
+    let x = vec![1, 2, 3, 4, 5];
+    &x[3..2];
+}
+
+#[test]
+#[should_panic]
+fn test_swap_remove_empty() {
+    let mut vec= Vec::<i32>::new();
+    vec.swap_remove(0);
+}
+
+#[test]
+fn test_move_iter_unwrap() {
+    let mut vec = Vec::with_capacity(7);
+    vec.push(1);
+    vec.push(2);
+    let ptr = vec.as_ptr();
+    vec = vec.into_iter().into_inner();
+    assert_eq!(vec.as_ptr(), ptr);
+    assert_eq!(vec.capacity(), 7);
+    assert_eq!(vec.len(), 0);
+}
+
+#[test]
+#[should_panic]
+fn test_map_in_place_incompatible_types_fail() {
+    let v = vec![0, 1, 2];
+    v.map_in_place(|_| ());
+}
+
+#[test]
+fn test_map_in_place() {
+    let v = vec![0, 1, 2];
+    assert_eq!(v.map_in_place(|i: u32| i as i32 - 1), [-1, 0, 1]);
+}
+
+#[test]
+fn test_map_in_place_zero_sized() {
+    let v = vec![(), ()];
+    #[derive(PartialEq, Debug)]
+    struct ZeroSized;
+    assert_eq!(v.map_in_place(|_| ZeroSized), [ZeroSized, ZeroSized]);
+}
+
+#[test]
+fn test_map_in_place_zero_drop_count() {
+    use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
+
+    #[derive(Clone, PartialEq, Debug)]
+    struct Nothing;
+    impl Drop for Nothing { fn drop(&mut self) { } }
+
+    #[derive(Clone, PartialEq, Debug)]
+    struct ZeroSized;
+    impl Drop for ZeroSized {
+        fn drop(&mut self) {
+            DROP_COUNTER.fetch_add(1, Ordering::Relaxed);
+        }
+    }
+    const NUM_ELEMENTS: usize = 2;
+    static DROP_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
+
+    let v = repeat(Nothing).take(NUM_ELEMENTS).collect::<Vec<_>>();
+
+    DROP_COUNTER.store(0, Ordering::Relaxed);
+
+    let v = v.map_in_place(|_| ZeroSized);
+    assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), 0);
+    drop(v);
+    assert_eq!(DROP_COUNTER.load(Ordering::Relaxed), NUM_ELEMENTS);
+}
+
+#[test]
+fn test_move_items() {
+    let vec = vec![1, 2, 3];
+    let mut vec2 = vec![];
+    for i in vec {
+        vec2.push(i);
+    }
+    assert_eq!(vec2, [1, 2, 3]);
+}
+
+#[test]
+fn test_move_items_reverse() {
+    let vec = vec![1, 2, 3];
+    let mut vec2 = vec![];
+    for i in vec.into_iter().rev() {
+        vec2.push(i);
+    }
+    assert_eq!(vec2, [3, 2, 1]);
+}
+
+#[test]
+fn test_move_items_zero_sized() {
+    let vec = vec![(), (), ()];
+    let mut vec2 = vec![];
+    for i in vec {
+        vec2.push(i);
+    }
+    assert_eq!(vec2, [(), (), ()]);
+}
+
+#[test]
+fn test_drain_items() {
+    let mut vec = vec![1, 2, 3];
+    let mut vec2 = vec![];
+    for i in vec.drain() {
+        vec2.push(i);
+    }
+    assert_eq!(vec, []);
+    assert_eq!(vec2, [ 1, 2, 3 ]);
+}
+
+#[test]
+fn test_drain_items_reverse() {
+    let mut vec = vec![1, 2, 3];
+    let mut vec2 = vec![];
+    for i in vec.drain().rev() {
+        vec2.push(i);
+    }
+    assert_eq!(vec, []);
+    assert_eq!(vec2, [3, 2, 1]);
+}
+
+#[test]
+fn test_drain_items_zero_sized() {
+    let mut vec = vec![(), (), ()];
+    let mut vec2 = vec![];
+    for i in vec.drain() {
+        vec2.push(i);
+    }
+    assert_eq!(vec, []);
+    assert_eq!(vec2, [(), (), ()]);
+}
+
+#[test]
+fn test_into_boxed_slice() {
+    let xs = vec![1, 2, 3];
+    let ys = xs.into_boxed_slice();
+    assert_eq!(&*ys, [1, 2, 3]);
+}
+
+#[test]
+fn test_append() {
+    let mut vec = vec![1, 2, 3];
+    let mut vec2 = vec![4, 5, 6];
+    vec.append(&mut vec2);
+    assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(vec2, []);
+}
+
+#[test]
+fn test_split_off() {
+    let mut vec = vec![1, 2, 3, 4, 5, 6];
+    let vec2 = vec.split_off(4);
+    assert_eq!(vec, [1, 2, 3, 4]);
+    assert_eq!(vec2, [5, 6]);
+}
+
+#[bench]
+fn bench_new(b: &mut Bencher) {
+    b.iter(|| {
+        let v: Vec<u32> = Vec::new();
+        assert_eq!(v.len(), 0);
+        assert_eq!(v.capacity(), 0);
+    })
+}
+
+fn do_bench_with_capacity(b: &mut Bencher, src_len: usize) {
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let v: Vec<u32> = Vec::with_capacity(src_len);
+        assert_eq!(v.len(), 0);
+        assert_eq!(v.capacity(), src_len);
+    })
+}
+
+#[bench]
+fn bench_with_capacity_0000(b: &mut Bencher) {
+    do_bench_with_capacity(b, 0)
+}
+
+#[bench]
+fn bench_with_capacity_0010(b: &mut Bencher) {
+    do_bench_with_capacity(b, 10)
+}
+
+#[bench]
+fn bench_with_capacity_0100(b: &mut Bencher) {
+    do_bench_with_capacity(b, 100)
+}
+
+#[bench]
+fn bench_with_capacity_1000(b: &mut Bencher) {
+    do_bench_with_capacity(b, 1000)
+}
+
+fn do_bench_from_fn(b: &mut Bencher, src_len: usize) {
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let dst = (0..src_len).collect::<Vec<_>>();
+        assert_eq!(dst.len(), src_len);
+        assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+    })
+}
+
+#[bench]
+fn bench_from_fn_0000(b: &mut Bencher) {
+    do_bench_from_fn(b, 0)
+}
+
+#[bench]
+fn bench_from_fn_0010(b: &mut Bencher) {
+    do_bench_from_fn(b, 10)
+}
+
+#[bench]
+fn bench_from_fn_0100(b: &mut Bencher) {
+    do_bench_from_fn(b, 100)
+}
+
+#[bench]
+fn bench_from_fn_1000(b: &mut Bencher) {
+    do_bench_from_fn(b, 1000)
+}
+
+fn do_bench_from_elem(b: &mut Bencher, src_len: usize) {
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let dst: Vec<usize> = repeat(5).take(src_len).collect();
+        assert_eq!(dst.len(), src_len);
+        assert!(dst.iter().all(|x| *x == 5));
+    })
+}
+
+#[bench]
+fn bench_from_elem_0000(b: &mut Bencher) {
+    do_bench_from_elem(b, 0)
+}
+
+#[bench]
+fn bench_from_elem_0010(b: &mut Bencher) {
+    do_bench_from_elem(b, 10)
+}
+
+#[bench]
+fn bench_from_elem_0100(b: &mut Bencher) {
+    do_bench_from_elem(b, 100)
+}
+
+#[bench]
+fn bench_from_elem_1000(b: &mut Bencher) {
+    do_bench_from_elem(b, 1000)
+}
+
+fn do_bench_from_slice(b: &mut Bencher, src_len: usize) {
+    let src: Vec<_> = FromIterator::from_iter(0..src_len);
+
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let dst = src.clone()[..].to_vec();
+        assert_eq!(dst.len(), src_len);
+        assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+    });
+}
+
+#[bench]
+fn bench_from_slice_0000(b: &mut Bencher) {
+    do_bench_from_slice(b, 0)
+}
+
+#[bench]
+fn bench_from_slice_0010(b: &mut Bencher) {
+    do_bench_from_slice(b, 10)
+}
+
+#[bench]
+fn bench_from_slice_0100(b: &mut Bencher) {
+    do_bench_from_slice(b, 100)
+}
+
+#[bench]
+fn bench_from_slice_1000(b: &mut Bencher) {
+    do_bench_from_slice(b, 1000)
+}
+
+fn do_bench_from_iter(b: &mut Bencher, src_len: usize) {
+    let src: Vec<_> = FromIterator::from_iter(0..src_len);
+
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let dst: Vec<_> = FromIterator::from_iter(src.clone().into_iter());
+        assert_eq!(dst.len(), src_len);
+        assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+    });
+}
+
+#[bench]
+fn bench_from_iter_0000(b: &mut Bencher) {
+    do_bench_from_iter(b, 0)
+}
+
+#[bench]
+fn bench_from_iter_0010(b: &mut Bencher) {
+    do_bench_from_iter(b, 10)
+}
+
+#[bench]
+fn bench_from_iter_0100(b: &mut Bencher) {
+    do_bench_from_iter(b, 100)
+}
+
+#[bench]
+fn bench_from_iter_1000(b: &mut Bencher) {
+    do_bench_from_iter(b, 1000)
+}
+
+fn do_bench_extend(b: &mut Bencher, dst_len: usize, src_len: usize) {
+    let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
+    let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
+
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let mut dst = dst.clone();
+        dst.extend(src.clone().into_iter());
+        assert_eq!(dst.len(), dst_len + src_len);
+        assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+    });
+}
+
+#[bench]
+fn bench_extend_0000_0000(b: &mut Bencher) {
+    do_bench_extend(b, 0, 0)
+}
+
+#[bench]
+fn bench_extend_0000_0010(b: &mut Bencher) {
+    do_bench_extend(b, 0, 10)
+}
+
+#[bench]
+fn bench_extend_0000_0100(b: &mut Bencher) {
+    do_bench_extend(b, 0, 100)
+}
+
+#[bench]
+fn bench_extend_0000_1000(b: &mut Bencher) {
+    do_bench_extend(b, 0, 1000)
+}
+
+#[bench]
+fn bench_extend_0010_0010(b: &mut Bencher) {
+    do_bench_extend(b, 10, 10)
+}
+
+#[bench]
+fn bench_extend_0100_0100(b: &mut Bencher) {
+    do_bench_extend(b, 100, 100)
+}
+
+#[bench]
+fn bench_extend_1000_1000(b: &mut Bencher) {
+    do_bench_extend(b, 1000, 1000)
+}
+
+fn do_bench_push_all(b: &mut Bencher, dst_len: usize, src_len: usize) {
+    let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
+    let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
+
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let mut dst = dst.clone();
+        dst.push_all(&src);
+        assert_eq!(dst.len(), dst_len + src_len);
+        assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+    });
+}
+
+#[bench]
+fn bench_push_all_0000_0000(b: &mut Bencher) {
+    do_bench_push_all(b, 0, 0)
+}
+
+#[bench]
+fn bench_push_all_0000_0010(b: &mut Bencher) {
+    do_bench_push_all(b, 0, 10)
+}
+
+#[bench]
+fn bench_push_all_0000_0100(b: &mut Bencher) {
+    do_bench_push_all(b, 0, 100)
+}
+
+#[bench]
+fn bench_push_all_0000_1000(b: &mut Bencher) {
+    do_bench_push_all(b, 0, 1000)
+}
+
+#[bench]
+fn bench_push_all_0010_0010(b: &mut Bencher) {
+    do_bench_push_all(b, 10, 10)
+}
+
+#[bench]
+fn bench_push_all_0100_0100(b: &mut Bencher) {
+    do_bench_push_all(b, 100, 100)
+}
+
+#[bench]
+fn bench_push_all_1000_1000(b: &mut Bencher) {
+    do_bench_push_all(b, 1000, 1000)
+}
+
+fn do_bench_push_all_move(b: &mut Bencher, dst_len: usize, src_len: usize) {
+    let dst: Vec<_> = FromIterator::from_iter(0..dst_len);
+    let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
+
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let mut dst = dst.clone();
+        dst.extend(src.clone().into_iter());
+        assert_eq!(dst.len(), dst_len + src_len);
+        assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+    });
+}
+
+#[bench]
+fn bench_push_all_move_0000_0000(b: &mut Bencher) {
+    do_bench_push_all_move(b, 0, 0)
+}
+
+#[bench]
+fn bench_push_all_move_0000_0010(b: &mut Bencher) {
+    do_bench_push_all_move(b, 0, 10)
+}
+
+#[bench]
+fn bench_push_all_move_0000_0100(b: &mut Bencher) {
+    do_bench_push_all_move(b, 0, 100)
+}
+
+#[bench]
+fn bench_push_all_move_0000_1000(b: &mut Bencher) {
+    do_bench_push_all_move(b, 0, 1000)
+}
+
+#[bench]
+fn bench_push_all_move_0010_0010(b: &mut Bencher) {
+    do_bench_push_all_move(b, 10, 10)
+}
+
+#[bench]
+fn bench_push_all_move_0100_0100(b: &mut Bencher) {
+    do_bench_push_all_move(b, 100, 100)
+}
+
+#[bench]
+fn bench_push_all_move_1000_1000(b: &mut Bencher) {
+    do_bench_push_all_move(b, 1000, 1000)
+}
+
+fn do_bench_clone(b: &mut Bencher, src_len: usize) {
+    let src: Vec<usize> = FromIterator::from_iter(0..src_len);
+
+    b.bytes = src_len as u64;
+
+    b.iter(|| {
+        let dst = src.clone();
+        assert_eq!(dst.len(), src_len);
+        assert!(dst.iter().enumerate().all(|(i, x)| i == *x));
+    });
+}
+
+#[bench]
+fn bench_clone_0000(b: &mut Bencher) {
+    do_bench_clone(b, 0)
+}
+
+#[bench]
+fn bench_clone_0010(b: &mut Bencher) {
+    do_bench_clone(b, 10)
+}
+
+#[bench]
+fn bench_clone_0100(b: &mut Bencher) {
+    do_bench_clone(b, 100)
+}
+
+#[bench]
+fn bench_clone_1000(b: &mut Bencher) {
+    do_bench_clone(b, 1000)
+}
+
+fn do_bench_clone_from(b: &mut Bencher, times: usize, dst_len: usize, src_len: usize) {
+    let dst: Vec<_> = FromIterator::from_iter(0..src_len);
+    let src: Vec<_> = FromIterator::from_iter(dst_len..dst_len + src_len);
+
+    b.bytes = (times * src_len) as u64;
+
+    b.iter(|| {
+        let mut dst = dst.clone();
+
+        for _ in 0..times {
+            dst.clone_from(&src);
+
+            assert_eq!(dst.len(), src_len);
+            assert!(dst.iter().enumerate().all(|(i, x)| dst_len + i == *x));
+        }
+    });
+}
+
+#[bench]
+fn bench_clone_from_01_0000_0000(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 0, 0)
+}
+
+#[bench]
+fn bench_clone_from_01_0000_0010(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 0, 10)
+}
+
+#[bench]
+fn bench_clone_from_01_0000_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 0, 100)
+}
+
+#[bench]
+fn bench_clone_from_01_0000_1000(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 0, 1000)
+}
+
+#[bench]
+fn bench_clone_from_01_0010_0010(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 10, 10)
+}
+
+#[bench]
+fn bench_clone_from_01_0100_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 100, 100)
+}
+
+#[bench]
+fn bench_clone_from_01_1000_1000(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 1000, 1000)
+}
+
+#[bench]
+fn bench_clone_from_01_0010_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 10, 100)
+}
+
+#[bench]
+fn bench_clone_from_01_0100_1000(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 100, 1000)
+}
+
+#[bench]
+fn bench_clone_from_01_0010_0000(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 10, 0)
+}
+
+#[bench]
+fn bench_clone_from_01_0100_0010(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 100, 10)
+}
+
+#[bench]
+fn bench_clone_from_01_1000_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 1, 1000, 100)
+}
+
+#[bench]
+fn bench_clone_from_10_0000_0000(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 0, 0)
+}
+
+#[bench]
+fn bench_clone_from_10_0000_0010(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 0, 10)
+}
+
+#[bench]
+fn bench_clone_from_10_0000_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 0, 100)
+}
+
+#[bench]
+fn bench_clone_from_10_0000_1000(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 0, 1000)
+}
+
+#[bench]
+fn bench_clone_from_10_0010_0010(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 10, 10)
+}
+
+#[bench]
+fn bench_clone_from_10_0100_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 100, 100)
+}
+
+#[bench]
+fn bench_clone_from_10_1000_1000(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 1000, 1000)
+}
+
+#[bench]
+fn bench_clone_from_10_0010_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 10, 100)
+}
+
+#[bench]
+fn bench_clone_from_10_0100_1000(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 100, 1000)
+}
+
+#[bench]
+fn bench_clone_from_10_0010_0000(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 10, 0)
+}
+
+#[bench]
+fn bench_clone_from_10_0100_0010(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 100, 10)
+}
+
+#[bench]
+fn bench_clone_from_10_1000_0100(b: &mut Bencher) {
+    do_bench_clone_from(b, 10, 1000, 100)
+}
diff --git a/src/libcollectionstest/vec_deque.rs b/src/libcollectionstest/vec_deque.rs
new file mode 100644
index 00000000000..38f358c1505
--- /dev/null
+++ b/src/libcollectionstest/vec_deque.rs
@@ -0,0 +1,888 @@
+// 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.
+
+use std::collections::VecDeque;
+use std::fmt::Debug;
+use std::hash::{SipHasher, self};
+
+use test;
+
+use self::Taggy::*;
+use self::Taggypar::*;
+
+#[test]
+#[allow(deprecated)]
+fn test_simple() {
+    let mut d = VecDeque::new();
+    assert_eq!(d.len(), 0);
+    d.push_front(17);
+    d.push_front(42);
+    d.push_back(137);
+    assert_eq!(d.len(), 3);
+    d.push_back(137);
+    assert_eq!(d.len(), 4);
+    assert_eq!(*d.front().unwrap(), 42);
+    assert_eq!(*d.back().unwrap(), 137);
+    let mut i = d.pop_front();
+    assert_eq!(i, Some(42));
+    i = d.pop_back();
+    assert_eq!(i, Some(137));
+    i = d.pop_back();
+    assert_eq!(i, Some(137));
+    i = d.pop_back();
+    assert_eq!(i, Some(17));
+    assert_eq!(d.len(), 0);
+    d.push_back(3);
+    assert_eq!(d.len(), 1);
+    d.push_front(2);
+    assert_eq!(d.len(), 2);
+    d.push_back(4);
+    assert_eq!(d.len(), 3);
+    d.push_front(1);
+    assert_eq!(d.len(), 4);
+    debug!("{}", d[0]);
+    debug!("{}", d[1]);
+    debug!("{}", d[2]);
+    debug!("{}", d[3]);
+    assert_eq!(d[0], 1);
+    assert_eq!(d[1], 2);
+    assert_eq!(d[2], 3);
+    assert_eq!(d[3], 4);
+}
+
+#[cfg(test)]
+fn test_parameterized<T:Clone + PartialEq + Debug>(a: T, b: T, c: T, d: T) {
+    let mut deq = VecDeque::new();
+    assert_eq!(deq.len(), 0);
+    deq.push_front(a.clone());
+    deq.push_front(b.clone());
+    deq.push_back(c.clone());
+    assert_eq!(deq.len(), 3);
+    deq.push_back(d.clone());
+    assert_eq!(deq.len(), 4);
+    assert_eq!((*deq.front().unwrap()).clone(), b.clone());
+    assert_eq!((*deq.back().unwrap()).clone(), d.clone());
+    assert_eq!(deq.pop_front().unwrap(), b.clone());
+    assert_eq!(deq.pop_back().unwrap(), d.clone());
+    assert_eq!(deq.pop_back().unwrap(), c.clone());
+    assert_eq!(deq.pop_back().unwrap(), a.clone());
+    assert_eq!(deq.len(), 0);
+    deq.push_back(c.clone());
+    assert_eq!(deq.len(), 1);
+    deq.push_front(b.clone());
+    assert_eq!(deq.len(), 2);
+    deq.push_back(d.clone());
+    assert_eq!(deq.len(), 3);
+    deq.push_front(a.clone());
+    assert_eq!(deq.len(), 4);
+    assert_eq!(deq[0].clone(), a.clone());
+    assert_eq!(deq[1].clone(), b.clone());
+    assert_eq!(deq[2].clone(), c.clone());
+    assert_eq!(deq[3].clone(), d.clone());
+}
+
+#[test]
+fn test_push_front_grow() {
+    let mut deq = VecDeque::new();
+    for i in 0..66 {
+        deq.push_front(i);
+    }
+    assert_eq!(deq.len(), 66);
+
+    for i in 0..66 {
+        assert_eq!(deq[i], 65 - i);
+    }
+
+    let mut deq = VecDeque::new();
+    for i in 0..66 {
+        deq.push_back(i);
+    }
+
+    for i in 0..66 {
+        assert_eq!(deq[i], i);
+    }
+}
+
+#[test]
+fn test_index() {
+    let mut deq = VecDeque::new();
+    for i in 1..4 {
+        deq.push_front(i);
+    }
+    assert_eq!(deq[1], 2);
+}
+
+#[test]
+#[should_panic]
+fn test_index_out_of_bounds() {
+    let mut deq = VecDeque::new();
+    for i in 1..4 {
+        deq.push_front(i);
+    }
+    deq[3];
+}
+
+#[bench]
+fn bench_new(b: &mut test::Bencher) {
+    b.iter(|| {
+        let ring: VecDeque<i32> = VecDeque::new();
+        test::black_box(ring);
+    })
+}
+
+#[bench]
+fn bench_grow_1025(b: &mut test::Bencher) {
+    b.iter(|| {
+        let mut deq = VecDeque::new();
+        for i in 0..1025 {
+            deq.push_front(i);
+        }
+        test::black_box(deq);
+    })
+}
+
+#[bench]
+fn bench_iter_1000(b: &mut test::Bencher) {
+    let ring: VecDeque<_> = (0..1000).collect();
+
+    b.iter(|| {
+        let mut sum = 0;
+        for &i in &ring {
+            sum += i;
+        }
+        test::black_box(sum);
+    })
+}
+
+#[bench]
+fn bench_mut_iter_1000(b: &mut test::Bencher) {
+    let mut ring: VecDeque<_> = (0..1000).collect();
+
+    b.iter(|| {
+        let mut sum = 0;
+        for i in &mut ring {
+            sum += *i;
+        }
+        test::black_box(sum);
+    })
+}
+
+#[derive(Clone, PartialEq, Debug)]
+enum Taggy {
+    One(i32),
+    Two(i32, i32),
+    Three(i32, i32, i32),
+}
+
+#[derive(Clone, PartialEq, Debug)]
+enum Taggypar<T> {
+    Onepar(T),
+    Twopar(T, T),
+    Threepar(T, T, T),
+}
+
+#[derive(Clone, PartialEq, Debug)]
+struct RecCy {
+    x: i32,
+    y: i32,
+    t: Taggy
+}
+
+#[test]
+fn test_param_int() {
+    test_parameterized::<i32>(5, 72, 64, 175);
+}
+
+#[test]
+fn test_param_taggy() {
+    test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42));
+}
+
+#[test]
+fn test_param_taggypar() {
+    test_parameterized::<Taggypar<i32>>(Onepar::<i32>(1),
+                                        Twopar::<i32>(1, 2),
+                                        Threepar::<i32>(1, 2, 3),
+                                        Twopar::<i32>(17, 42));
+}
+
+#[test]
+fn test_param_reccy() {
+    let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
+    let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
+    let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
+    let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
+    test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
+}
+
+#[test]
+fn test_with_capacity() {
+    let mut d = VecDeque::with_capacity(0);
+    d.push_back(1);
+    assert_eq!(d.len(), 1);
+    let mut d = VecDeque::with_capacity(50);
+    d.push_back(1);
+    assert_eq!(d.len(), 1);
+}
+
+#[test]
+fn test_with_capacity_non_power_two() {
+    let mut d3 = VecDeque::with_capacity(3);
+    d3.push_back(1);
+
+    // X = None, | = lo
+    // [|1, X, X]
+    assert_eq!(d3.pop_front(), Some(1));
+    // [X, |X, X]
+    assert_eq!(d3.front(), None);
+
+    // [X, |3, X]
+    d3.push_back(3);
+    // [X, |3, 6]
+    d3.push_back(6);
+    // [X, X, |6]
+    assert_eq!(d3.pop_front(), Some(3));
+
+    // Pushing the lo past half way point to trigger
+    // the 'B' scenario for growth
+    // [9, X, |6]
+    d3.push_back(9);
+    // [9, 12, |6]
+    d3.push_back(12);
+
+    d3.push_back(15);
+    // There used to be a bug here about how the
+    // VecDeque made growth assumptions about the
+    // underlying Vec which didn't hold and lead
+    // to corruption.
+    // (Vec grows to next power of two)
+    //good- [9, 12, 15, X, X, X, X, |6]
+    //bug-  [15, 12, X, X, X, |6, X, X]
+    assert_eq!(d3.pop_front(), Some(6));
+
+    // Which leads us to the following state which
+    // would be a failure case.
+    //bug-  [15, 12, X, X, X, X, |X, X]
+    assert_eq!(d3.front(), Some(&9));
+}
+
+#[test]
+fn test_reserve_exact() {
+    let mut d = VecDeque::new();
+    d.push_back(0);
+    d.reserve_exact(50);
+    assert!(d.capacity() >= 51);
+}
+
+#[test]
+fn test_reserve() {
+    let mut d = VecDeque::new();
+    d.push_back(0);
+    d.reserve(50);
+    assert!(d.capacity() >= 51);
+}
+
+#[test]
+fn test_swap() {
+    let mut d: VecDeque<_> = (0..5).collect();
+    d.pop_front();
+    d.swap(0, 3);
+    assert_eq!(d.iter().cloned().collect::<Vec<_>>(), [4, 2, 3, 1]);
+}
+
+#[test]
+fn test_iter() {
+    let mut d = VecDeque::new();
+    assert_eq!(d.iter().next(), None);
+    assert_eq!(d.iter().size_hint(), (0, Some(0)));
+
+    for i in 0..5 {
+        d.push_back(i);
+    }
+    {
+        let b: &[_] = &[&0,&1,&2,&3,&4];
+        assert_eq!(d.iter().collect::<Vec<_>>(), b);
+    }
+
+    for i in 6..9 {
+        d.push_front(i);
+    }
+    {
+        let b: &[_] = &[&8,&7,&6,&0,&1,&2,&3,&4];
+        assert_eq!(d.iter().collect::<Vec<_>>(), b);
+    }
+
+    let mut it = d.iter();
+    let mut len = d.len();
+    loop {
+        match it.next() {
+            None => break,
+            _ => { len -= 1; assert_eq!(it.size_hint(), (len, Some(len))) }
+        }
+    }
+}
+
+#[test]
+fn test_rev_iter() {
+    let mut d = VecDeque::new();
+    assert_eq!(d.iter().rev().next(), None);
+
+    for i in 0..5 {
+        d.push_back(i);
+    }
+    {
+        let b: &[_] = &[&4,&3,&2,&1,&0];
+        assert_eq!(d.iter().rev().collect::<Vec<_>>(), b);
+    }
+
+    for i in 6..9 {
+        d.push_front(i);
+    }
+    let b: &[_] = &[&4,&3,&2,&1,&0,&6,&7,&8];
+    assert_eq!(d.iter().rev().collect::<Vec<_>>(), b);
+}
+
+#[test]
+fn test_mut_rev_iter_wrap() {
+    let mut d = VecDeque::with_capacity(3);
+    assert!(d.iter_mut().rev().next().is_none());
+
+    d.push_back(1);
+    d.push_back(2);
+    d.push_back(3);
+    assert_eq!(d.pop_front(), Some(1));
+    d.push_back(4);
+
+    assert_eq!(d.iter_mut().rev().cloned().collect::<Vec<_>>(),
+               vec![4, 3, 2]);
+}
+
+#[test]
+fn test_mut_iter() {
+    let mut d = VecDeque::new();
+    assert!(d.iter_mut().next().is_none());
+
+    for i in 0..3 {
+        d.push_front(i);
+    }
+
+    for (i, elt) in d.iter_mut().enumerate() {
+        assert_eq!(*elt, 2 - i);
+        *elt = i;
+    }
+
+    {
+        let mut it = d.iter_mut();
+        assert_eq!(*it.next().unwrap(), 0);
+        assert_eq!(*it.next().unwrap(), 1);
+        assert_eq!(*it.next().unwrap(), 2);
+        assert!(it.next().is_none());
+    }
+}
+
+#[test]
+fn test_mut_rev_iter() {
+    let mut d = VecDeque::new();
+    assert!(d.iter_mut().rev().next().is_none());
+
+    for i in 0..3 {
+        d.push_front(i);
+    }
+
+    for (i, elt) in d.iter_mut().rev().enumerate() {
+        assert_eq!(*elt, i);
+        *elt = i;
+    }
+
+    {
+        let mut it = d.iter_mut().rev();
+        assert_eq!(*it.next().unwrap(), 0);
+        assert_eq!(*it.next().unwrap(), 1);
+        assert_eq!(*it.next().unwrap(), 2);
+        assert!(it.next().is_none());
+    }
+}
+
+#[test]
+fn test_into_iter() {
+
+    // Empty iter
+    {
+        let d: VecDeque<i32> = VecDeque::new();
+        let mut iter = d.into_iter();
+
+        assert_eq!(iter.size_hint(), (0, Some(0)));
+        assert_eq!(iter.next(), None);
+        assert_eq!(iter.size_hint(), (0, Some(0)));
+    }
+
+    // simple iter
+    {
+        let mut d = VecDeque::new();
+        for i in 0..5 {
+            d.push_back(i);
+        }
+
+        let b = vec![0,1,2,3,4];
+        assert_eq!(d.into_iter().collect::<Vec<_>>(), b);
+    }
+
+    // wrapped iter
+    {
+        let mut d = VecDeque::new();
+        for i in 0..5 {
+            d.push_back(i);
+        }
+        for i in 6..9 {
+            d.push_front(i);
+        }
+
+        let b = vec![8,7,6,0,1,2,3,4];
+        assert_eq!(d.into_iter().collect::<Vec<_>>(), b);
+    }
+
+    // partially used
+    {
+        let mut d = VecDeque::new();
+        for i in 0..5 {
+            d.push_back(i);
+        }
+        for i in 6..9 {
+            d.push_front(i);
+        }
+
+        let mut it = d.into_iter();
+        assert_eq!(it.size_hint(), (8, Some(8)));
+        assert_eq!(it.next(), Some(8));
+        assert_eq!(it.size_hint(), (7, Some(7)));
+        assert_eq!(it.next_back(), Some(4));
+        assert_eq!(it.size_hint(), (6, Some(6)));
+        assert_eq!(it.next(), Some(7));
+        assert_eq!(it.size_hint(), (5, Some(5)));
+    }
+}
+
+#[test]
+fn test_drain() {
+
+    // Empty iter
+    {
+        let mut d: VecDeque<i32> = VecDeque::new();
+
+        {
+            let mut iter = d.drain();
+
+            assert_eq!(iter.size_hint(), (0, Some(0)));
+            assert_eq!(iter.next(), None);
+            assert_eq!(iter.size_hint(), (0, Some(0)));
+        }
+
+        assert!(d.is_empty());
+    }
+
+    // simple iter
+    {
+        let mut d = VecDeque::new();
+        for i in 0..5 {
+            d.push_back(i);
+        }
+
+        assert_eq!(d.drain().collect::<Vec<_>>(), [0, 1, 2, 3, 4]);
+        assert!(d.is_empty());
+    }
+
+    // wrapped iter
+    {
+        let mut d = VecDeque::new();
+        for i in 0..5 {
+            d.push_back(i);
+        }
+        for i in 6..9 {
+            d.push_front(i);
+        }
+
+        assert_eq!(d.drain().collect::<Vec<_>>(), [8,7,6,0,1,2,3,4]);
+        assert!(d.is_empty());
+    }
+
+    // partially used
+    {
+        let mut d: VecDeque<_> = VecDeque::new();
+        for i in 0..5 {
+            d.push_back(i);
+        }
+        for i in 6..9 {
+            d.push_front(i);
+        }
+
+        {
+            let mut it = d.drain();
+            assert_eq!(it.size_hint(), (8, Some(8)));
+            assert_eq!(it.next(), Some(8));
+            assert_eq!(it.size_hint(), (7, Some(7)));
+            assert_eq!(it.next_back(), Some(4));
+            assert_eq!(it.size_hint(), (6, Some(6)));
+            assert_eq!(it.next(), Some(7));
+            assert_eq!(it.size_hint(), (5, Some(5)));
+        }
+        assert!(d.is_empty());
+    }
+}
+
+#[test]
+fn test_from_iter() {
+    use std::iter;
+
+    let v = vec!(1,2,3,4,5,6,7);
+    let deq: VecDeque<_> = v.iter().cloned().collect();
+    let u: Vec<_> = deq.iter().cloned().collect();
+    assert_eq!(u, v);
+
+    let seq = iter::count(0, 2).take(256);
+    let deq: VecDeque<_> = seq.collect();
+    for (i, &x) in deq.iter().enumerate() {
+        assert_eq!(2*i, x);
+    }
+    assert_eq!(deq.len(), 256);
+}
+
+#[test]
+fn test_clone() {
+    let mut d = VecDeque::new();
+    d.push_front(17);
+    d.push_front(42);
+    d.push_back(137);
+    d.push_back(137);
+    assert_eq!(d.len(), 4);
+    let mut e = d.clone();
+    assert_eq!(e.len(), 4);
+    while !d.is_empty() {
+        assert_eq!(d.pop_back(), e.pop_back());
+    }
+    assert_eq!(d.len(), 0);
+    assert_eq!(e.len(), 0);
+}
+
+#[test]
+fn test_eq() {
+    let mut d = VecDeque::new();
+    assert!(d == VecDeque::with_capacity(0));
+    d.push_front(137);
+    d.push_front(17);
+    d.push_front(42);
+    d.push_back(137);
+    let mut e = VecDeque::with_capacity(0);
+    e.push_back(42);
+    e.push_back(17);
+    e.push_back(137);
+    e.push_back(137);
+    assert!(&e == &d);
+    e.pop_back();
+    e.push_back(0);
+    assert!(e != d);
+    e.clear();
+    assert!(e == VecDeque::new());
+}
+
+#[test]
+fn test_hash() {
+  let mut x = VecDeque::new();
+  let mut y = VecDeque::new();
+
+  x.push_back(1);
+  x.push_back(2);
+  x.push_back(3);
+
+  y.push_back(0);
+  y.push_back(1);
+  y.pop_front();
+  y.push_back(2);
+  y.push_back(3);
+
+  assert!(hash::hash::<_, SipHasher>(&x) == hash::hash::<_, SipHasher>(&y));
+}
+
+#[test]
+fn test_ord() {
+    let x = VecDeque::new();
+    let mut y = VecDeque::new();
+    y.push_back(1);
+    y.push_back(2);
+    y.push_back(3);
+    assert!(x < y);
+    assert!(y > x);
+    assert!(x <= x);
+    assert!(x >= x);
+}
+
+#[test]
+fn test_show() {
+    let ringbuf: VecDeque<_> = (0..10).collect();
+    assert_eq!(format!("{:?}", ringbuf), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
+
+    let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"].iter()
+                                                                    .cloned()
+                                                                    .collect();
+    assert_eq!(format!("{:?}", ringbuf), "[\"just\", \"one\", \"test\", \"more\"]");
+}
+
+#[test]
+fn test_drop() {
+    static mut drops: i32 = 0;
+    struct Elem;
+    impl Drop for Elem {
+        fn drop(&mut self) {
+            unsafe { drops += 1; }
+        }
+    }
+
+    let mut ring = VecDeque::new();
+    ring.push_back(Elem);
+    ring.push_front(Elem);
+    ring.push_back(Elem);
+    ring.push_front(Elem);
+    drop(ring);
+
+    assert_eq!(unsafe {drops}, 4);
+}
+
+#[test]
+fn test_drop_with_pop() {
+    static mut drops: i32 = 0;
+    struct Elem;
+    impl Drop for Elem {
+        fn drop(&mut self) {
+            unsafe { drops += 1; }
+        }
+    }
+
+    let mut ring = VecDeque::new();
+    ring.push_back(Elem);
+    ring.push_front(Elem);
+    ring.push_back(Elem);
+    ring.push_front(Elem);
+
+    drop(ring.pop_back());
+    drop(ring.pop_front());
+    assert_eq!(unsafe {drops}, 2);
+
+    drop(ring);
+    assert_eq!(unsafe {drops}, 4);
+}
+
+#[test]
+fn test_drop_clear() {
+    static mut drops: i32 = 0;
+    struct Elem;
+    impl Drop for Elem {
+        fn drop(&mut self) {
+            unsafe { drops += 1; }
+        }
+    }
+
+    let mut ring = VecDeque::new();
+    ring.push_back(Elem);
+    ring.push_front(Elem);
+    ring.push_back(Elem);
+    ring.push_front(Elem);
+    ring.clear();
+    assert_eq!(unsafe {drops}, 4);
+
+    drop(ring);
+    assert_eq!(unsafe {drops}, 4);
+}
+
+#[test]
+fn test_reserve_grow() {
+    // test growth path A
+    // [T o o H] -> [T o o H . . . . ]
+    let mut ring = VecDeque::with_capacity(4);
+    for i in 0..3 {
+        ring.push_back(i);
+    }
+    ring.reserve(7);
+    for i in 0..3 {
+        assert_eq!(ring.pop_front(), Some(i));
+    }
+
+    // test growth path B
+    // [H T o o] -> [. T o o H . . . ]
+    let mut ring = VecDeque::with_capacity(4);
+    for i in 0..1 {
+        ring.push_back(i);
+        assert_eq!(ring.pop_front(), Some(i));
+    }
+    for i in 0..3 {
+        ring.push_back(i);
+    }
+    ring.reserve(7);
+    for i in 0..3 {
+        assert_eq!(ring.pop_front(), Some(i));
+    }
+
+    // test growth path C
+    // [o o H T] -> [o o H . . . . T ]
+    let mut ring = VecDeque::with_capacity(4);
+    for i in 0..3 {
+        ring.push_back(i);
+        assert_eq!(ring.pop_front(), Some(i));
+    }
+    for i in 0..3 {
+        ring.push_back(i);
+    }
+    ring.reserve(7);
+    for i in 0..3 {
+        assert_eq!(ring.pop_front(), Some(i));
+    }
+}
+
+#[test]
+fn test_get() {
+    let mut ring = VecDeque::new();
+    ring.push_back(0);
+    assert_eq!(ring.get(0), Some(&0));
+    assert_eq!(ring.get(1), None);
+
+    ring.push_back(1);
+    assert_eq!(ring.get(0), Some(&0));
+    assert_eq!(ring.get(1), Some(&1));
+    assert_eq!(ring.get(2), None);
+
+    ring.push_back(2);
+    assert_eq!(ring.get(0), Some(&0));
+    assert_eq!(ring.get(1), Some(&1));
+    assert_eq!(ring.get(2), Some(&2));
+    assert_eq!(ring.get(3), None);
+
+    assert_eq!(ring.pop_front(), Some(0));
+    assert_eq!(ring.get(0), Some(&1));
+    assert_eq!(ring.get(1), Some(&2));
+    assert_eq!(ring.get(2), None);
+
+    assert_eq!(ring.pop_front(), Some(1));
+    assert_eq!(ring.get(0), Some(&2));
+    assert_eq!(ring.get(1), None);
+
+    assert_eq!(ring.pop_front(), Some(2));
+    assert_eq!(ring.get(0), None);
+    assert_eq!(ring.get(1), None);
+}
+
+#[test]
+fn test_get_mut() {
+    let mut ring = VecDeque::new();
+    for i in 0..3 {
+        ring.push_back(i);
+    }
+
+    match ring.get_mut(1) {
+        Some(x) => *x = -1,
+        None => ()
+    };
+
+    assert_eq!(ring.get_mut(0), Some(&mut 0));
+    assert_eq!(ring.get_mut(1), Some(&mut -1));
+    assert_eq!(ring.get_mut(2), Some(&mut 2));
+    assert_eq!(ring.get_mut(3), None);
+
+    assert_eq!(ring.pop_front(), Some(0));
+    assert_eq!(ring.get_mut(0), Some(&mut -1));
+    assert_eq!(ring.get_mut(1), Some(&mut 2));
+    assert_eq!(ring.get_mut(2), None);
+}
+
+#[test]
+fn test_front() {
+    let mut ring = VecDeque::new();
+    ring.push_back(10);
+    ring.push_back(20);
+    assert_eq!(ring.front(), Some(&10));
+    ring.pop_front();
+    assert_eq!(ring.front(), Some(&20));
+    ring.pop_front();
+    assert_eq!(ring.front(), None);
+}
+
+#[test]
+fn test_as_slices() {
+    let mut ring: VecDeque<i32> = VecDeque::with_capacity(127);
+    let cap = ring.capacity() as i32;
+    let first = cap/2;
+    let last  = cap - first;
+    for i in 0..first {
+        ring.push_back(i);
+
+        let (left, right) = ring.as_slices();
+        let expected: Vec<_> = (0..i+1).collect();
+        assert_eq!(left, expected);
+        assert_eq!(right, []);
+    }
+
+    for j in -last..0 {
+        ring.push_front(j);
+        let (left, right) = ring.as_slices();
+        let expected_left: Vec<_> = (-last..j+1).rev().collect();
+        let expected_right: Vec<_> = (0..first).collect();
+        assert_eq!(left, expected_left);
+        assert_eq!(right, expected_right);
+    }
+
+    assert_eq!(ring.len() as i32, cap);
+    assert_eq!(ring.capacity() as i32, cap);
+}
+
+#[test]
+fn test_as_mut_slices() {
+    let mut ring: VecDeque<i32> = VecDeque::with_capacity(127);
+    let cap = ring.capacity() as i32;
+    let first = cap/2;
+    let last  = cap - first;
+    for i in 0..first {
+        ring.push_back(i);
+
+        let (left, right) = ring.as_mut_slices();
+        let expected: Vec<_> = (0..i+1).collect();
+        assert_eq!(left, expected);
+        assert_eq!(right, []);
+    }
+
+    for j in -last..0 {
+        ring.push_front(j);
+        let (left, right) = ring.as_mut_slices();
+        let expected_left: Vec<_> = (-last..j+1).rev().collect();
+        let expected_right: Vec<_> = (0..first).collect();
+        assert_eq!(left, expected_left);
+        assert_eq!(right, expected_right);
+    }
+
+    assert_eq!(ring.len() as i32, cap);
+    assert_eq!(ring.capacity() as i32, cap);
+}
+
+#[test]
+fn test_append() {
+    let mut a: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
+    let mut b: VecDeque<_> = vec![4, 5, 6].into_iter().collect();
+
+    // normal append
+    a.append(&mut b);
+    assert_eq!(a.iter().cloned().collect::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
+    assert_eq!(b.iter().cloned().collect::<Vec<_>>(), []);
+
+    // append nothing to something
+    a.append(&mut b);
+    assert_eq!(a.iter().cloned().collect::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
+    assert_eq!(b.iter().cloned().collect::<Vec<_>>(), []);
+
+    // append something to nothing
+    b.append(&mut a);
+    assert_eq!(b.iter().cloned().collect::<Vec<_>>(), [1, 2, 3, 4, 5, 6]);
+    assert_eq!(a.iter().cloned().collect::<Vec<_>>(), []);
+}
diff --git a/src/libcollectionstest/vec_map.rs b/src/libcollectionstest/vec_map.rs
new file mode 100644
index 00000000000..112b4c03e20
--- /dev/null
+++ b/src/libcollectionstest/vec_map.rs
@@ -0,0 +1,510 @@
+// 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.
+
+use std::collections::VecMap;
+use std::collections::vec_map::Entry::{Occupied, Vacant};
+use std::hash::{SipHasher, hash};
+
+#[test]
+fn test_get_mut() {
+    let mut m = VecMap::new();
+    assert!(m.insert(1, 12).is_none());
+    assert!(m.insert(2, 8).is_none());
+    assert!(m.insert(5, 14).is_none());
+    let new = 100;
+    match m.get_mut(&5) {
+        None => panic!(), Some(x) => *x = new
+    }
+    assert_eq!(m.get(&5), Some(&new));
+}
+
+#[test]
+fn test_len() {
+    let mut map = VecMap::new();
+    assert_eq!(map.len(), 0);
+    assert!(map.is_empty());
+    assert!(map.insert(5, 20).is_none());
+    assert_eq!(map.len(), 1);
+    assert!(!map.is_empty());
+    assert!(map.insert(11, 12).is_none());
+    assert_eq!(map.len(), 2);
+    assert!(!map.is_empty());
+    assert!(map.insert(14, 22).is_none());
+    assert_eq!(map.len(), 3);
+    assert!(!map.is_empty());
+}
+
+#[test]
+fn test_clear() {
+    let mut map = VecMap::new();
+    assert!(map.insert(5, 20).is_none());
+    assert!(map.insert(11, 12).is_none());
+    assert!(map.insert(14, 22).is_none());
+    map.clear();
+    assert!(map.is_empty());
+    assert!(map.get(&5).is_none());
+    assert!(map.get(&11).is_none());
+    assert!(map.get(&14).is_none());
+}
+
+#[test]
+fn test_insert() {
+    let mut m = VecMap::new();
+    assert_eq!(m.insert(1, 2), None);
+    assert_eq!(m.insert(1, 3), Some(2));
+    assert_eq!(m.insert(1, 4), Some(3));
+}
+
+#[test]
+fn test_remove() {
+    let mut m = VecMap::new();
+    m.insert(1, 2);
+    assert_eq!(m.remove(&1), Some(2));
+    assert_eq!(m.remove(&1), None);
+}
+
+#[test]
+fn test_keys() {
+    let mut map = VecMap::new();
+    map.insert(1, 'a');
+    map.insert(2, 'b');
+    map.insert(3, 'c');
+    let keys: Vec<_> = map.keys().collect();
+    assert_eq!(keys.len(), 3);
+    assert!(keys.contains(&1));
+    assert!(keys.contains(&2));
+    assert!(keys.contains(&3));
+}
+
+#[test]
+fn test_values() {
+    let mut map = VecMap::new();
+    map.insert(1, 'a');
+    map.insert(2, 'b');
+    map.insert(3, 'c');
+    let values: Vec<_> = map.values().cloned().collect();
+    assert_eq!(values.len(), 3);
+    assert!(values.contains(&'a'));
+    assert!(values.contains(&'b'));
+    assert!(values.contains(&'c'));
+}
+
+#[test]
+fn test_iterator() {
+    let mut m = VecMap::new();
+
+    assert!(m.insert(0, 1).is_none());
+    assert!(m.insert(1, 2).is_none());
+    assert!(m.insert(3, 5).is_none());
+    assert!(m.insert(6, 10).is_none());
+    assert!(m.insert(10, 11).is_none());
+
+    let mut it = m.iter();
+    assert_eq!(it.size_hint(), (0, Some(11)));
+    assert_eq!(it.next().unwrap(), (0, &1));
+    assert_eq!(it.size_hint(), (0, Some(10)));
+    assert_eq!(it.next().unwrap(), (1, &2));
+    assert_eq!(it.size_hint(), (0, Some(9)));
+    assert_eq!(it.next().unwrap(), (3, &5));
+    assert_eq!(it.size_hint(), (0, Some(7)));
+    assert_eq!(it.next().unwrap(), (6, &10));
+    assert_eq!(it.size_hint(), (0, Some(4)));
+    assert_eq!(it.next().unwrap(), (10, &11));
+    assert_eq!(it.size_hint(), (0, Some(0)));
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_iterator_size_hints() {
+    let mut m = VecMap::new();
+
+    assert!(m.insert(0, 1).is_none());
+    assert!(m.insert(1, 2).is_none());
+    assert!(m.insert(3, 5).is_none());
+    assert!(m.insert(6, 10).is_none());
+    assert!(m.insert(10, 11).is_none());
+
+    assert_eq!(m.iter().size_hint(), (0, Some(11)));
+    assert_eq!(m.iter().rev().size_hint(), (0, Some(11)));
+    assert_eq!(m.iter_mut().size_hint(), (0, Some(11)));
+    assert_eq!(m.iter_mut().rev().size_hint(), (0, Some(11)));
+}
+
+#[test]
+fn test_mut_iterator() {
+    let mut m = VecMap::new();
+
+    assert!(m.insert(0, 1).is_none());
+    assert!(m.insert(1, 2).is_none());
+    assert!(m.insert(3, 5).is_none());
+    assert!(m.insert(6, 10).is_none());
+    assert!(m.insert(10, 11).is_none());
+
+    for (k, v) in &mut m {
+        *v += k as isize;
+    }
+
+    let mut it = m.iter();
+    assert_eq!(it.next().unwrap(), (0, &1));
+    assert_eq!(it.next().unwrap(), (1, &3));
+    assert_eq!(it.next().unwrap(), (3, &8));
+    assert_eq!(it.next().unwrap(), (6, &16));
+    assert_eq!(it.next().unwrap(), (10, &21));
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_rev_iterator() {
+    let mut m = VecMap::new();
+
+    assert!(m.insert(0, 1).is_none());
+    assert!(m.insert(1, 2).is_none());
+    assert!(m.insert(3, 5).is_none());
+    assert!(m.insert(6, 10).is_none());
+    assert!(m.insert(10, 11).is_none());
+
+    let mut it = m.iter().rev();
+    assert_eq!(it.next().unwrap(), (10, &11));
+    assert_eq!(it.next().unwrap(), (6, &10));
+    assert_eq!(it.next().unwrap(), (3, &5));
+    assert_eq!(it.next().unwrap(), (1, &2));
+    assert_eq!(it.next().unwrap(), (0, &1));
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_mut_rev_iterator() {
+    let mut m = VecMap::new();
+
+    assert!(m.insert(0, 1).is_none());
+    assert!(m.insert(1, 2).is_none());
+    assert!(m.insert(3, 5).is_none());
+    assert!(m.insert(6, 10).is_none());
+    assert!(m.insert(10, 11).is_none());
+
+    for (k, v) in m.iter_mut().rev() {
+        *v += k as isize;
+    }
+
+    let mut it = m.iter();
+    assert_eq!(it.next().unwrap(), (0, &1));
+    assert_eq!(it.next().unwrap(), (1, &3));
+    assert_eq!(it.next().unwrap(), (3, &8));
+    assert_eq!(it.next().unwrap(), (6, &16));
+    assert_eq!(it.next().unwrap(), (10, &21));
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_move_iter() {
+    let mut m: VecMap<Box<_>> = VecMap::new();
+    m.insert(1, box 2);
+    let mut called = false;
+    for (k, v) in m {
+        assert!(!called);
+        called = true;
+        assert_eq!(k, 1);
+        assert_eq!(v, box 2);
+    }
+    assert!(called);
+}
+
+#[test]
+fn test_drain_iterator() {
+    let mut map = VecMap::new();
+    map.insert(1, "a");
+    map.insert(3, "c");
+    map.insert(2, "b");
+
+    let vec: Vec<_> = map.drain().collect();
+
+    assert_eq!(vec, [(1, "a"), (2, "b"), (3, "c")]);
+    assert_eq!(map.len(), 0);
+}
+
+#[test]
+fn test_append() {
+    let mut a = VecMap::new();
+    a.insert(1, "a");
+    a.insert(2, "b");
+    a.insert(3, "c");
+
+    let mut b = VecMap::new();
+    b.insert(3, "d");  // Overwrite element from a
+    b.insert(4, "e");
+    b.insert(5, "f");
+
+    a.append(&mut b);
+
+    assert_eq!(a.len(), 5);
+    assert_eq!(b.len(), 0);
+    // Capacity shouldn't change for possible reuse
+    assert!(b.capacity() >= 4);
+
+    assert_eq!(a[1], "a");
+    assert_eq!(a[2], "b");
+    assert_eq!(a[3], "d");
+    assert_eq!(a[4], "e");
+    assert_eq!(a[5], "f");
+}
+
+#[test]
+fn test_split_off() {
+    // Split within the key range
+    let mut a = VecMap::new();
+    a.insert(1, "a");
+    a.insert(2, "b");
+    a.insert(3, "c");
+    a.insert(4, "d");
+
+    let b = a.split_off(3);
+
+    assert_eq!(a.len(), 2);
+    assert_eq!(b.len(), 2);
+
+    assert_eq!(a[1], "a");
+    assert_eq!(a[2], "b");
+
+    assert_eq!(b[3], "c");
+    assert_eq!(b[4], "d");
+
+    // Split at 0
+    a.clear();
+    a.insert(1, "a");
+    a.insert(2, "b");
+    a.insert(3, "c");
+    a.insert(4, "d");
+
+    let b = a.split_off(0);
+
+    assert_eq!(a.len(), 0);
+    assert_eq!(b.len(), 4);
+    assert_eq!(b[1], "a");
+    assert_eq!(b[2], "b");
+    assert_eq!(b[3], "c");
+    assert_eq!(b[4], "d");
+
+    // Split behind max_key
+    a.clear();
+    a.insert(1, "a");
+    a.insert(2, "b");
+    a.insert(3, "c");
+    a.insert(4, "d");
+
+    let b = a.split_off(5);
+
+    assert_eq!(a.len(), 4);
+    assert_eq!(b.len(), 0);
+    assert_eq!(a[1], "a");
+    assert_eq!(a[2], "b");
+    assert_eq!(a[3], "c");
+    assert_eq!(a[4], "d");
+}
+
+#[test]
+fn test_show() {
+    let mut map = VecMap::new();
+    let empty = VecMap::<i32>::new();
+
+    map.insert(1, 2);
+    map.insert(3, 4);
+
+    let map_str = format!("{:?}", map);
+    assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}");
+    assert_eq!(format!("{:?}", empty), "{}");
+}
+
+#[test]
+fn test_clone() {
+    let mut a = VecMap::new();
+
+    a.insert(1, 'x');
+    a.insert(4, 'y');
+    a.insert(6, 'z');
+
+    assert!(a.clone() == a);
+}
+
+#[test]
+fn test_eq() {
+    let mut a = VecMap::new();
+    let mut b = VecMap::new();
+
+    assert!(a == b);
+    assert!(a.insert(0, 5).is_none());
+    assert!(a != b);
+    assert!(b.insert(0, 4).is_none());
+    assert!(a != b);
+    assert!(a.insert(5, 19).is_none());
+    assert!(a != b);
+    assert!(!b.insert(0, 5).is_none());
+    assert!(a != b);
+    assert!(b.insert(5, 19).is_none());
+    assert!(a == b);
+
+    a = VecMap::new();
+    b = VecMap::with_capacity(1);
+    assert!(a == b);
+}
+
+#[test]
+fn test_lt() {
+    let mut a = VecMap::new();
+    let mut b = VecMap::new();
+
+    assert!(!(a < b) && !(b < a));
+    assert!(b.insert(2, 5).is_none());
+    assert!(a < b);
+    assert!(a.insert(2, 7).is_none());
+    assert!(!(a < b) && b < a);
+    assert!(b.insert(1, 0).is_none());
+    assert!(b < a);
+    assert!(a.insert(0, 6).is_none());
+    assert!(a < b);
+    assert!(a.insert(6, 2).is_none());
+    assert!(a < b && !(b < a));
+}
+
+#[test]
+fn test_ord() {
+    let mut a = VecMap::new();
+    let mut b = VecMap::new();
+
+    assert!(a <= b && a >= b);
+    assert!(a.insert(1, 1).is_none());
+    assert!(a > b && a >= b);
+    assert!(b < a && b <= a);
+    assert!(b.insert(2, 2).is_none());
+    assert!(b > a && b >= a);
+    assert!(a < b && a <= b);
+}
+
+#[test]
+fn test_hash() {
+    let mut x = VecMap::new();
+    let mut y = VecMap::new();
+
+    assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
+    x.insert(1, 'a');
+    x.insert(2, 'b');
+    x.insert(3, 'c');
+
+    y.insert(3, 'c');
+    y.insert(2, 'b');
+    y.insert(1, 'a');
+
+    assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
+
+    x.insert(1000, 'd');
+    x.remove(&1000);
+
+    assert!(hash::<_, SipHasher>(&x) == hash::<_, SipHasher>(&y));
+}
+
+#[test]
+fn test_from_iter() {
+    let xs = vec![(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e')];
+
+    let map: VecMap<_> = xs.iter().cloned().collect();
+
+    for &(k, v) in &xs {
+        assert_eq!(map.get(&k), Some(&v));
+    }
+}
+
+#[test]
+fn test_index() {
+    let mut map = VecMap::new();
+
+    map.insert(1, 2);
+    map.insert(2, 1);
+    map.insert(3, 4);
+
+    assert_eq!(map[3], 4);
+}
+
+#[test]
+#[should_panic]
+fn test_index_nonexistent() {
+    let mut map = VecMap::new();
+
+    map.insert(1, 2);
+    map.insert(2, 1);
+    map.insert(3, 4);
+
+    map[4];
+}
+
+#[test]
+fn test_entry(){
+    let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)];
+
+    let mut map: VecMap<_> = xs.iter().cloned().collect();
+
+    // Existing key (insert)
+    match map.entry(1) {
+        Vacant(_) => unreachable!(),
+        Occupied(mut view) => {
+            assert_eq!(view.get(), &10);
+            assert_eq!(view.insert(100), 10);
+        }
+    }
+    assert_eq!(map.get(&1).unwrap(), &100);
+    assert_eq!(map.len(), 6);
+
+
+    // Existing key (update)
+    match map.entry(2) {
+        Vacant(_) => unreachable!(),
+        Occupied(mut view) => {
+            let v = view.get_mut();
+            *v *= 10;
+        }
+    }
+    assert_eq!(map.get(&2).unwrap(), &200);
+    assert_eq!(map.len(), 6);
+
+    // Existing key (take)
+    match map.entry(3) {
+        Vacant(_) => unreachable!(),
+        Occupied(view) => {
+            assert_eq!(view.remove(), 30);
+        }
+    }
+    assert_eq!(map.get(&3), None);
+    assert_eq!(map.len(), 5);
+
+
+    // Inexistent key (insert)
+    match map.entry(10) {
+        Occupied(_) => unreachable!(),
+        Vacant(view) => {
+            assert_eq!(*view.insert(1000), 1000);
+        }
+    }
+    assert_eq!(map.get(&10).unwrap(), &1000);
+    assert_eq!(map.len(), 6);
+}
+
+mod bench {
+    use std::collections::VecMap;
+
+    map_insert_rand_bench!{insert_rand_100,    100,    VecMap}
+    map_insert_rand_bench!{insert_rand_10_000, 10_000, VecMap}
+
+    map_insert_seq_bench!{insert_seq_100,    100,    VecMap}
+    map_insert_seq_bench!{insert_seq_10_000, 10_000, VecMap}
+
+    map_find_rand_bench!{find_rand_100,    100,    VecMap}
+    map_find_rand_bench!{find_rand_10_000, 10_000, VecMap}
+
+    map_find_seq_bench!{find_seq_100,    100,    VecMap}
+    map_find_seq_bench!{find_seq_10_000, 10_000, VecMap}
+}
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 237dbe492ba..8ebedb66851 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -65,7 +65,7 @@ use default::Default;
 use marker;
 use mem;
 use num::{ToPrimitive, Int};
-use ops::{Add, Deref, FnMut};
+use ops::{Add, Deref, FnMut, RangeFrom};
 use option::Option;
 use option::Option::{Some, None};
 use marker::Sized;
@@ -2366,34 +2366,101 @@ impl<A, St, F> Iterator for Unfold<St, F> where F: FnMut(&mut St) -> Option<A> {
     }
 }
 
+/// An adapter for stepping range iterators by a custom amount.
+///
+/// The resulting iterator handles overflow by stopping. The `A`
+/// parameter is the type being iterated over, while `R` is the range
+/// type (usually one of `std::ops::{Range, RangeFrom}`.
+#[derive(Clone)]
+#[unstable(feature = "step_by", reason = "recent addition")]
+pub struct StepBy<A, R> {
+    step_by: A,
+    range: R,
+}
+
+impl<A: Add> RangeFrom<A> {
+    /// Creates an iterator starting at the same point, but stepping by
+    /// the given amount at each iteration.
+    ///
+    /// # Examples
+    ///
+    /// ```ignore
+    /// for i in (0u8..).step_by(2) {
+    ///     println!("{}", i);
+    /// }
+    /// ```
+    ///
+    /// This prints all even `u8` values.
+    #[unstable(feature = "step_by", reason = "recent addition")]
+    pub fn step_by(self, by: A) -> StepBy<A, Self> {
+        StepBy {
+            step_by: by,
+            range: self
+        }
+    }
+}
+
+impl<A: Int> ::ops::Range<A> {
+    /// Creates an iterator with the same range, but stepping by the
+    /// given amount at each iteration.
+    ///
+    /// The resulting iterator handles overflow by stopping.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(step_by, core)]
+    /// for i in (0..10).step_by(2) {
+    ///     println!("{}", i);
+    /// }
+    /// ```
+    ///
+    /// This prints:
+    ///
+    /// ```text
+    /// 0
+    /// 2
+    /// 4
+    /// 6
+    /// 8
+    /// ```
+    #[unstable(feature = "step_by", reason = "recent addition")]
+    pub fn step_by(self, by: A) -> StepBy<A, Self> {
+        StepBy {
+            step_by: by,
+            range: self
+        }
+    }
+}
+
 /// An infinite iterator starting at `start` and advancing by `step` with each
 /// iteration
-#[derive(Clone)]
 #[unstable(feature = "core",
            reason = "may be renamed or replaced by range notation adapters")]
-pub struct Counter<A> {
-    /// The current state the counter is at (next value to be yielded)
-    state: A,
-    /// The amount that this iterator is stepping by
-    step: A,
-}
+#[deprecated(since = "1.0.0-beta", reason = "use range notation and step_by")]
+pub type Counter<A> = StepBy<A, RangeFrom<A>>;
 
-/// Creates a new counter with the specified start/step
+/// Deprecated: use `(start..).step_by(step)` instead.
 #[inline]
 #[unstable(feature = "core",
            reason = "may be renamed or replaced by range notation adapters")]
+#[deprecated(since = "1.0.0-beta", reason = "use (start..).step_by(step) instead")]
+#[allow(deprecated)]
 pub fn count<A>(start: A, step: A) -> Counter<A> {
-    Counter{state: start, step: step}
+    StepBy {
+        range: RangeFrom { start: start },
+        step_by: step,
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<A: Add<Output=A> + Clone> Iterator for Counter<A> {
+impl<A: Add<Output=A> + Clone> Iterator for StepBy<A, RangeFrom<A>> {
     type Item = A;
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        let result = self.state.clone();
-        self.state = self.state.clone() + self.step.clone();
+        let result = self.range.start.clone();
+        self.range.start = result.clone() + self.step_by.clone();
         Some(result)
     }
 
@@ -2404,31 +2471,22 @@ impl<A: Add<Output=A> + Clone> Iterator for Counter<A> {
 }
 
 /// An iterator over the range [start, stop)
+#[allow(deprecated)]
 #[derive(Clone)]
 #[unstable(feature = "core",
            reason = "will be replaced by range notation")]
+#[deprecated(since = "1.0.0-beta", reason = "use range notation")]
 pub struct Range<A> {
     state: A,
     stop: A,
     one: A,
 }
 
-/// Returns an iterator over the given range [start, stop) (that is, starting
-/// at start (inclusive), and ending at stop (exclusive)).
-///
-/// # Examples
-///
-/// ```
-/// let array = [0, 1, 2, 3, 4];
-///
-/// for i in range(0, 5) {
-///     println!("{}", i);
-///     assert_eq!(i,  array[i]);
-/// }
-/// ```
+/// Deprecated: use `(start..stop)` instead.
 #[inline]
-#[unstable(feature = "core",
-           reason = "will be replaced by range notation")]
+#[unstable(feature = "core", reason = "will be replaced by range notation")]
+#[deprecated(since = "1.0.0-beta", reason = "use (start..stop) instead")]
+#[allow(deprecated)]
 pub fn range<A: Int>(start: A, stop: A) -> Range<A> {
     Range {
         state: start,
@@ -2440,6 +2498,8 @@ pub fn range<A: Int>(start: A, stop: A) -> Range<A> {
 // FIXME: #10414: Unfortunate type bound
 #[unstable(feature = "core",
            reason = "will be replaced by range notation")]
+#[deprecated(since = "1.0.0-beta", reason = "use range notation")]
+#[allow(deprecated)]
 impl<A: Int + ToPrimitive> Iterator for Range<A> {
     type Item = A;
 
@@ -2491,6 +2551,8 @@ impl<A: Int + ToPrimitive> Iterator for Range<A> {
 /// the direction it is consumed.
 #[unstable(feature = "core",
            reason = "will be replaced by range notation")]
+#[deprecated(since = "1.0.0-beta", reason = "use range notation")]
+#[allow(deprecated)]
 impl<A: Int + ToPrimitive> DoubleEndedIterator for Range<A> {
     #[inline]
     fn next_back(&mut self) -> Option<A> {
@@ -2507,6 +2569,7 @@ impl<A: Int + ToPrimitive> DoubleEndedIterator for Range<A> {
 #[derive(Clone)]
 #[unstable(feature = "core",
            reason = "likely to be replaced by range notation and adapters")]
+#[allow(deprecated)]
 pub struct RangeInclusive<A> {
     range: Range<A>,
     done: bool,
@@ -2516,6 +2579,7 @@ pub struct RangeInclusive<A> {
 #[inline]
 #[unstable(feature = "core",
            reason = "likely to be replaced by range notation and adapters")]
+#[allow(deprecated)]
 pub fn range_inclusive<A: Int>(start: A, stop: A) -> RangeInclusive<A> {
     RangeInclusive {
         range: range(start, stop),
@@ -2525,6 +2589,7 @@ pub fn range_inclusive<A: Int>(start: A, stop: A) -> RangeInclusive<A> {
 
 #[unstable(feature = "core",
            reason = "likely to be replaced by range notation and adapters")]
+#[allow(deprecated)]
 impl<A: Int + ToPrimitive> Iterator for RangeInclusive<A> {
     type Item = A;
 
@@ -2561,6 +2626,7 @@ impl<A: Int + ToPrimitive> Iterator for RangeInclusive<A> {
 
 #[unstable(feature = "core",
            reason = "likely to be replaced by range notation and adapters")]
+#[allow(deprecated)]
 impl<A: Int + ToPrimitive> DoubleEndedIterator for RangeInclusive<A> {
     #[inline]
     fn next_back(&mut self) -> Option<A> {
@@ -2578,61 +2644,39 @@ impl<A: Int + ToPrimitive> DoubleEndedIterator for RangeInclusive<A> {
 }
 
 /// An iterator over the range [start, stop) by `step`. It handles overflow by stopping.
-#[derive(Clone)]
 #[unstable(feature = "core",
            reason = "likely to be replaced by range notation and adapters")]
-pub struct RangeStep<A> {
-    state: A,
-    stop: A,
-    step: A,
-    rev: bool,
-}
+#[deprecated(since = "1.0.0-beta", reason = "use range notation and step_by")]
+pub type RangeStep<A> = StepBy<A, ::ops::Range<A>>;
 
-/// Return an iterator over the range [start, stop) by `step`.
-///
-/// It handles overflow by stopping.
-///
-/// # Examples
-///
-/// ```
-/// use std::iter::range_step;
-///
-/// for i in range_step(0, 10, 2) {
-///     println!("{}", i);
-/// }
-/// ```
-///
-/// This prints:
-///
-/// ```text
-/// 0
-/// 2
-/// 4
-/// 6
-/// 8
-/// ```
+/// Deprecated: use `(start..stop).step_by(step)` instead.
 #[inline]
 #[unstable(feature = "core",
            reason = "likely to be replaced by range notation and adapters")]
+#[deprecated(since = "1.0.0-beta",
+             reason = "use `(start..stop).step_by(step)` instead")]
+#[allow(deprecated)]
 pub fn range_step<A: Int>(start: A, stop: A, step: A) -> RangeStep<A> {
-    let rev = step < Int::zero();
-    RangeStep{state: start, stop: stop, step: step, rev: rev}
+    StepBy {
+        step_by: step,
+        range: ::ops::Range { start: start, end: stop },
+    }
 }
 
-#[unstable(feature = "core",
-           reason = "likely to be replaced by range notation and adapters")]
-impl<A: Int> Iterator for RangeStep<A> {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<A: Int> Iterator for StepBy<A, ::ops::Range<A>> {
     type Item = A;
 
     #[inline]
     fn next(&mut self) -> Option<A> {
-        if (self.rev && self.state > self.stop) || (!self.rev && self.state < self.stop) {
-            let result = self.state;
-            match self.state.checked_add(self.step) {
-                Some(x) => self.state = x,
-                None => self.state = self.stop.clone()
+        let rev = self.step_by < Int::zero();
+        let start = self.range.start;
+        if (rev && start > self.range.end) || (!rev && start < self.range.end) {
+            match start.checked_add(self.step_by) {
+                Some(x) => self.range.start = x,
+                None => self.range.start = self.range.end.clone()
             }
-            Some(result)
+            Some(start)
         } else {
             None
         }
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 18e20c02a1b..a77f9709600 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -708,6 +708,7 @@ signed_int_impl! { i32 }
 signed_int_impl! { i64 }
 signed_int_impl! { int }
 
+#[cfg(stage0)]
 /// A built-in unsigned integer.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait UnsignedInt: Int + WrappingOps {
@@ -742,21 +743,1010 @@ pub trait UnsignedInt: Int + WrappingOps {
     }
 }
 
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl UnsignedInt for uint {}
 
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl UnsignedInt for u8 {}
 
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl UnsignedInt for u16 {}
 
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl UnsignedInt for u32 {}
 
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl UnsignedInt for u64 {}
 
+// NB(japaric) I added this module to avoid adding several `cfg(not(stage0))`, and avoid name
+// clashes between macros. We should move all the items inside this module into the outer scope
+// once the `Int` trait is removed
+#[cfg(not(stage0))]
+mod inherent {
+    use intrinsics;
+    use mem::size_of;
+    use option::Option::{self, Some, None};
+
+    use super::wrapping::{OverflowingOps, WrappingOps};
+
+    // `Int` + `SignedInt` implemented for signed integers
+    macro_rules! int_impl {
+        ($T:ty = $ActualT:ty, $UnsignedT:ty, $BITS:expr,
+         $add_with_overflow:path,
+         $sub_with_overflow:path,
+         $mul_with_overflow:path) => {
+            /// Returns the `0` value of this integer type.
+            // FIXME (#5527): Should be an associated constant
+            #[unstable(feature = "core",
+                       reason = "unsure about its place in the world")]
+            #[inline]
+            pub fn zero() -> $T { 0 }
+
+            /// Returns the `1` value of this integer type.
+            // FIXME (#5527): Should be an associated constant
+            #[unstable(feature = "core",
+                       reason = "unsure about its place in the world")]
+            #[inline]
+            pub fn one() -> $T { 1 }
+
+            /// Returns the smallest value that can be represented by this integer type.
+            // FIXME (#5527): Should be and associated constant
+            #[unstable(feature = "core",
+                       reason = "unsure about its place in the world")]
+            #[inline]
+            pub fn min_value() -> $T { (-1 as $T) << ($BITS - 1) }
+
+            /// Returns the largest value that can be represented by this integer type.
+            // FIXME (#5527): Should be and associated constant
+            #[unstable(feature = "core",
+                       reason = "unsure about its place in the world")]
+            #[inline]
+            pub fn max_value() -> $T { let min: $T = <$T>::min_value(); !min }
+
+            /// Returns the number of ones in the binary representation of `self`.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0b01001100u8;
+            ///
+            /// assert_eq!(n.count_ones(), 3);
+            /// ```
+            #[unstable(feature = "core",
+                       reason = "pending integer conventions")]
+            #[inline]
+            pub fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
+
+            /// Returns the number of zeros in the binary representation of `self`.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0b01001100u8;
+            ///
+            /// assert_eq!(n.count_zeros(), 5);
+            /// ```
+            #[unstable(feature = "core",
+                       reason = "pending integer conventions")]
+            #[inline]
+            pub fn count_zeros(self) -> u32 {
+                (!self).count_ones()
+            }
+
+            /// Returns the number of leading zeros in the binary representation
+            /// of `self`.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0b0101000u16;
+            ///
+            /// assert_eq!(n.leading_zeros(), 10);
+            /// ```
+            #[unstable(feature = "core",
+                       reason = "pending integer conventions")]
+            #[inline]
+            pub fn leading_zeros(self) -> u32 { (self as $UnsignedT).leading_zeros() }
+
+            /// Returns the number of trailing zeros in the binary representation
+            /// of `self`.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0b0101000u16;
+            ///
+            /// assert_eq!(n.trailing_zeros(), 3);
+            /// ```
+            #[unstable(feature = "core",
+                       reason = "pending integer conventions")]
+            #[inline]
+            pub fn trailing_zeros(self) -> u32 { (self as $UnsignedT).trailing_zeros() }
+
+            /// Shifts the bits to the left by a specified amount amount, `n`, wrapping
+            /// the truncated bits to the end of the resulting integer.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0x0123456789ABCDEFu64;
+            /// let m = 0x3456789ABCDEF012u64;
+            ///
+            /// assert_eq!(n.rotate_left(12), m);
+            /// ```
+            #[unstable(feature = "core",
+                       reason = "pending integer conventions")]
+            #[inline]
+            pub fn rotate_left(self, n: u32) -> $T { (self as $UnsignedT).rotate_left(n) as $T }
+
+            /// Shifts the bits to the right by a specified amount amount, `n`, wrapping
+            /// the truncated bits to the beginning of the resulting integer.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0x0123456789ABCDEFu64;
+            /// let m = 0xDEF0123456789ABCu64;
+            ///
+            /// assert_eq!(n.rotate_right(12), m);
+            /// ```
+            #[unstable(feature = "core",
+                       reason = "pending integer conventions")]
+            #[inline]
+            pub fn rotate_right(self, n: u32) -> $T { (self as $UnsignedT).rotate_right(n) as $T }
+
+            /// Reverses the byte order of the integer.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0x0123456789ABCDEFu64;
+            /// let m = 0xEFCDAB8967452301u64;
+            ///
+            /// assert_eq!(n.swap_bytes(), m);
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn swap_bytes(self) -> $T { (self as $UnsignedT).swap_bytes() as $T }
+
+            /// Convert an integer from big endian to the target's endianness.
+            ///
+            /// On big endian this is a no-op. On little endian the bytes are swapped.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0x0123456789ABCDEFu64;
+            ///
+            /// if cfg!(target_endian = "big") {
+            ///     assert_eq!(Int::from_be(n), n)
+            /// } else {
+            ///     assert_eq!(Int::from_be(n), n.swap_bytes())
+            /// }
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn from_be(x: $T) -> $T {
+                if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
+            }
+
+            /// Convert an integer from little endian to the target's endianness.
+            ///
+            /// On little endian this is a no-op. On big endian the bytes are swapped.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0x0123456789ABCDEFu64;
+            ///
+            /// if cfg!(target_endian = "little") {
+            ///     assert_eq!(Int::from_le(n), n)
+            /// } else {
+            ///     assert_eq!(Int::from_le(n), n.swap_bytes())
+            /// }
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn from_le(x: $T) -> $T {
+                if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
+            }
+
+            /// Convert `self` to big endian from the target's endianness.
+            ///
+            /// On big endian this is a no-op. On little endian the bytes are swapped.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0x0123456789ABCDEFu64;
+            ///
+            /// if cfg!(target_endian = "big") {
+            ///     assert_eq!(n.to_be(), n)
+            /// } else {
+            ///     assert_eq!(n.to_be(), n.swap_bytes())
+            /// }
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn to_be(self) -> $T { // or not to be?
+                if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
+            }
+
+            /// Convert `self` to little endian from the target's endianness.
+            ///
+            /// On little endian this is a no-op. On big endian the bytes are swapped.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0x0123456789ABCDEFu64;
+            ///
+            /// if cfg!(target_endian = "little") {
+            ///     assert_eq!(n.to_le(), n)
+            /// } else {
+            ///     assert_eq!(n.to_le(), n.swap_bytes())
+            /// }
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn to_le(self) -> $T {
+                if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
+            }
+
+            /// Checked integer addition. Computes `self + other`, returning `None` if
+            /// overflow occurred.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// assert_eq!(5u16.checked_add(65530), Some(65535));
+            /// assert_eq!(6u16.checked_add(65530), None);
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn checked_add(self, other: $T) -> Option<$T> {
+                checked_op!($T, $ActualT, $add_with_overflow, self, other)
+            }
+
+            /// Checked integer subtraction. Computes `self - other`, returning `None`
+            /// if underflow occurred.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// assert_eq!((-127i8).checked_sub(1), Some(-128));
+            /// assert_eq!((-128i8).checked_sub(1), None);
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn checked_sub(self, other: $T) -> Option<$T> {
+                checked_op!($T, $ActualT, $sub_with_overflow, self, other)
+            }
+
+            /// Checked integer multiplication. Computes `self * other`, returning
+            /// `None` if underflow or overflow occurred.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// assert_eq!(5u8.checked_mul(51), Some(255));
+            /// assert_eq!(5u8.checked_mul(52), None);
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn checked_mul(self, other: $T) -> Option<$T> {
+                checked_op!($T, $ActualT, $mul_with_overflow, self, other)
+            }
+
+            /// Checked integer division. Computes `self / other`, returning `None` if
+            /// `other == 0` or the operation results in underflow or overflow.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// assert_eq!((-127i8).checked_div(-1), Some(127));
+            /// assert_eq!((-128i8).checked_div(-1), None);
+            /// assert_eq!((1i8).checked_div(0), None);
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn checked_div(self, v: $T) -> Option<$T> {
+                match v {
+                    0   => None,
+                   -1 if self == <$T>::min_value()
+                        => None,
+                    v   => Some(self / v),
+                }
+            }
+
+            /// Saturating integer addition. Computes `self + other`, saturating at
+            /// the numeric bounds instead of overflowing.
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn saturating_add(self, other: $T) -> $T {
+                match self.checked_add(other) {
+                    Some(x)                       => x,
+                    None if other >= <$T>::zero() => <$T>::max_value(),
+                    None                          => <$T>::min_value(),
+                }
+            }
+
+            /// Saturating integer subtraction. Computes `self - other`, saturating at
+            /// the numeric bounds instead of overflowing.
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn saturating_sub(self, other: $T) -> $T {
+                match self.checked_sub(other) {
+                    Some(x)                      => x,
+                    None if other >= <$T>::zero() => <$T>::min_value(),
+                    None                          => <$T>::max_value(),
+                }
+            }
+
+            /// Raises self to the power of `exp`, using exponentiation by squaring.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// assert_eq!(2.pow(4), 16);
+            /// ```
+            #[unstable(feature = "core",
+                       reason = "pending integer conventions")]
+            #[inline]
+            pub fn pow(self, mut exp: u32) -> $T {
+                let mut base = self;
+                let mut acc = <$T>::one();
+
+                let mut prev_base = self;
+                let mut base_oflo = false;
+                while exp > 0 {
+                    if (exp & 1) == 1 {
+                        if base_oflo {
+                            // ensure overflow occurs in the same manner it
+                            // would have otherwise (i.e. signal any exception
+                            // it would have otherwise).
+                            acc = acc * (prev_base * prev_base);
+                        } else {
+                            acc = acc * base;
+                        }
+                    }
+                    prev_base = base;
+                    let (new_base, new_base_oflo) = base.overflowing_mul(base);
+                    base = new_base;
+                    base_oflo = new_base_oflo;
+                    exp /= 2;
+                }
+                acc
+            }
+
+            /// Computes the absolute value of `self`. `Int::min_value()` will be
+            /// returned if the number is `Int::min_value()`.
+            #[unstable(feature = "core", reason = "overflow in debug builds?")]
+            #[inline]
+            pub fn abs(self) -> $T {
+                if self.is_negative() { -self } else { self }
+            }
+
+            /// Returns a number representing sign of `self`.
+            ///
+            /// - `0` if the number is zero
+            /// - `1` if the number is positive
+            /// - `-1` if the number is negative
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn signum(self) -> $T {
+                match self {
+                    n if n > 0 =>  1,
+                    0          =>  0,
+                    _          => -1,
+                }
+            }
+
+            /// Returns `true` if `self` is positive and `false` if the number
+            /// is zero or negative.
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn is_positive(self) -> bool { self > 0 }
+
+            /// Returns `true` if `self` is negative and `false` if the number
+            /// is zero or positive.
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn is_negative(self) -> bool { self < 0 }
+        }
+    }
+
+    #[lang = "i8"]
+    impl i8 {
+        int_impl! { i8 = i8, u8, 8,
+            intrinsics::i8_add_with_overflow,
+            intrinsics::i8_sub_with_overflow,
+            intrinsics::i8_mul_with_overflow }
+    }
+
+    #[lang = "i16"]
+    impl i16 {
+        int_impl! { i16 = i16, u16, 16,
+            intrinsics::i16_add_with_overflow,
+            intrinsics::i16_sub_with_overflow,
+            intrinsics::i16_mul_with_overflow }
+    }
+
+    #[lang = "i32"]
+    impl i32 {
+        int_impl! { i32 = i32, u32, 32,
+            intrinsics::i32_add_with_overflow,
+            intrinsics::i32_sub_with_overflow,
+            intrinsics::i32_mul_with_overflow }
+    }
+
+    #[lang = "i64"]
+    impl i64 {
+        int_impl! { i64 = i64, u64, 64,
+            intrinsics::i64_add_with_overflow,
+            intrinsics::i64_sub_with_overflow,
+            intrinsics::i64_mul_with_overflow }
+    }
+
+    #[cfg(target_pointer_width = "32")]
+    #[lang = "isize"]
+    impl isize {
+        int_impl! { int = i32, u32, 32,
+            intrinsics::i32_add_with_overflow,
+            intrinsics::i32_sub_with_overflow,
+            intrinsics::i32_mul_with_overflow }
+    }
+
+    #[cfg(target_pointer_width = "64")]
+    #[lang = "isize"]
+    impl isize {
+        int_impl! { int = i64, u64, 64,
+            intrinsics::i64_add_with_overflow,
+            intrinsics::i64_sub_with_overflow,
+            intrinsics::i64_mul_with_overflow }
+    }
+
+    // `Int` + `UnsignedInt` implemented for signed integers
+    macro_rules! uint_impl {
+        ($T:ty = $ActualT:ty, $BITS:expr,
+         $ctpop:path,
+         $ctlz:path,
+         $cttz:path,
+         $bswap:path,
+         $add_with_overflow:path,
+         $sub_with_overflow:path,
+         $mul_with_overflow:path) => {
+            /// Returns the `0` value of this integer type.
+            // FIXME (#5527): Should be an associated constant
+            #[unstable(feature = "core",
+                       reason = "unsure about its place in the world")]
+            #[inline]
+            pub fn zero() -> $T { 0 }
+
+            /// Returns the `1` value of this integer type.
+            // FIXME (#5527): Should be an associated constant
+            #[unstable(feature = "core",
+                       reason = "unsure about its place in the world")]
+            #[inline]
+            pub fn one() -> $T { 1 }
+
+            /// Returns the smallest value that can be represented by this integer type.
+            // FIXME (#5527): Should be and associated constant
+            #[unstable(feature = "core",
+                       reason = "unsure about its place in the world")]
+            #[inline]
+            pub fn min_value() -> $T { 0 }
+
+            /// Returns the largest value that can be represented by this integer type.
+            // FIXME (#5527): Should be and associated constant
+            #[unstable(feature = "core",
+                       reason = "unsure about its place in the world")]
+            #[inline]
+            pub fn max_value() -> $T { -1 }
+
+            /// Returns the number of ones in the binary representation of `self`.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0b01001100u8;
+            ///
+            /// assert_eq!(n.count_ones(), 3);
+            /// ```
+            #[unstable(feature = "core",
+                       reason = "pending integer conventions")]
+            #[inline]
+            pub fn count_ones(self) -> u32 { unsafe { $ctpop(self as $ActualT) as u32 } }
+
+            /// Returns the number of zeros in the binary representation of `self`.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0b01001100u8;
+            ///
+            /// assert_eq!(n.count_zeros(), 5);
+            /// ```
+            #[unstable(feature = "core",
+                       reason = "pending integer conventions")]
+            #[inline]
+            pub fn count_zeros(self) -> u32 {
+                (!self).count_ones()
+            }
+
+            /// Returns the number of leading zeros in the binary representation
+            /// of `self`.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0b0101000u16;
+            ///
+            /// assert_eq!(n.leading_zeros(), 10);
+            /// ```
+            #[unstable(feature = "core",
+                       reason = "pending integer conventions")]
+            #[inline]
+            pub fn leading_zeros(self) -> u32 { unsafe { $ctlz(self as $ActualT) as u32 } }
+
+            /// Returns the number of trailing zeros in the binary representation
+            /// of `self`.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0b0101000u16;
+            ///
+            /// assert_eq!(n.trailing_zeros(), 3);
+            /// ```
+            #[unstable(feature = "core",
+                       reason = "pending integer conventions")]
+            #[inline]
+            pub fn trailing_zeros(self) -> u32 { unsafe { $cttz(self as $ActualT) as u32 } }
+
+            /// Shifts the bits to the left by a specified amount amount, `n`, wrapping
+            /// the truncated bits to the end of the resulting integer.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0x0123456789ABCDEFu64;
+            /// let m = 0x3456789ABCDEF012u64;
+            ///
+            /// assert_eq!(n.rotate_left(12), m);
+            /// ```
+            #[unstable(feature = "core",
+                       reason = "pending integer conventions")]
+            #[inline]
+            pub fn rotate_left(self, n: u32) -> $T {
+                // Protect against undefined behaviour for over-long bit shifts
+                let n = n % $BITS;
+                (self << n) | (self >> (($BITS - n) % $BITS))
+            }
+
+            /// Shifts the bits to the right by a specified amount amount, `n`, wrapping
+            /// the truncated bits to the beginning of the resulting integer.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0x0123456789ABCDEFu64;
+            /// let m = 0xDEF0123456789ABCu64;
+            ///
+            /// assert_eq!(n.rotate_right(12), m);
+            /// ```
+            #[unstable(feature = "core",
+                       reason = "pending integer conventions")]
+            #[inline]
+            pub fn rotate_right(self, n: u32) -> $T {
+                // Protect against undefined behaviour for over-long bit shifts
+                let n = n % $BITS;
+                (self >> n) | (self << (($BITS - n) % $BITS))
+            }
+
+            /// Reverses the byte order of the integer.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0x0123456789ABCDEFu64;
+            /// let m = 0xEFCDAB8967452301u64;
+            ///
+            /// assert_eq!(n.swap_bytes(), m);
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn swap_bytes(self) -> $T { unsafe { $bswap(self as $ActualT) as $T } }
+
+            /// Convert an integer from big endian to the target's endianness.
+            ///
+            /// On big endian this is a no-op. On little endian the bytes are swapped.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0x0123456789ABCDEFu64;
+            ///
+            /// if cfg!(target_endian = "big") {
+            ///     assert_eq!(Int::from_be(n), n)
+            /// } else {
+            ///     assert_eq!(Int::from_be(n), n.swap_bytes())
+            /// }
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn from_be(x: $T) -> $T {
+                if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
+            }
+
+            /// Convert an integer from little endian to the target's endianness.
+            ///
+            /// On little endian this is a no-op. On big endian the bytes are swapped.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0x0123456789ABCDEFu64;
+            ///
+            /// if cfg!(target_endian = "little") {
+            ///     assert_eq!(Int::from_le(n), n)
+            /// } else {
+            ///     assert_eq!(Int::from_le(n), n.swap_bytes())
+            /// }
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn from_le(x: $T) -> $T {
+                if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
+            }
+
+            /// Convert `self` to big endian from the target's endianness.
+            ///
+            /// On big endian this is a no-op. On little endian the bytes are swapped.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0x0123456789ABCDEFu64;
+            ///
+            /// if cfg!(target_endian = "big") {
+            ///     assert_eq!(n.to_be(), n)
+            /// } else {
+            ///     assert_eq!(n.to_be(), n.swap_bytes())
+            /// }
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn to_be(self) -> $T { // or not to be?
+                if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
+            }
+
+            /// Convert `self` to little endian from the target's endianness.
+            ///
+            /// On little endian this is a no-op. On big endian the bytes are swapped.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// let n = 0x0123456789ABCDEFu64;
+            ///
+            /// if cfg!(target_endian = "little") {
+            ///     assert_eq!(n.to_le(), n)
+            /// } else {
+            ///     assert_eq!(n.to_le(), n.swap_bytes())
+            /// }
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn to_le(self) -> $T {
+                if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
+            }
+
+            /// Checked integer addition. Computes `self + other`, returning `None` if
+            /// overflow occurred.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// assert_eq!(5u16.checked_add(65530), Some(65535));
+            /// assert_eq!(6u16.checked_add(65530), None);
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn checked_add(self, other: $T) -> Option<$T> {
+                checked_op!($T, $ActualT, $add_with_overflow, self, other)
+            }
+
+            /// Checked integer subtraction. Computes `self - other`, returning `None`
+            /// if underflow occurred.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// assert_eq!((-127i8).checked_sub(1), Some(-128));
+            /// assert_eq!((-128i8).checked_sub(1), None);
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn checked_sub(self, other: $T) -> Option<$T> {
+                checked_op!($T, $ActualT, $sub_with_overflow, self, other)
+            }
+
+            /// Checked integer multiplication. Computes `self * other`, returning
+            /// `None` if underflow or overflow occurred.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// assert_eq!(5u8.checked_mul(51), Some(255));
+            /// assert_eq!(5u8.checked_mul(52), None);
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn checked_mul(self, other: $T) -> Option<$T> {
+                checked_op!($T, $ActualT, $mul_with_overflow, self, other)
+            }
+
+            /// Checked integer division. Computes `self / other`, returning `None` if
+            /// `other == 0` or the operation results in underflow or overflow.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// assert_eq!((-127i8).checked_div(-1), Some(127));
+            /// assert_eq!((-128i8).checked_div(-1), None);
+            /// assert_eq!((1i8).checked_div(0), None);
+            /// ```
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn checked_div(self, v: $T) -> Option<$T> {
+                match v {
+                    0 => None,
+                    v => Some(self / v),
+                }
+            }
+
+            /// Saturating integer addition. Computes `self + other`, saturating at
+            /// the numeric bounds instead of overflowing.
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn saturating_add(self, other: $T) -> $T {
+                match self.checked_add(other) {
+                    Some(x)                       => x,
+                    None if other >= <$T>::zero() => <$T>::max_value(),
+                    None                          => <$T>::min_value(),
+                }
+            }
+
+            /// Saturating integer subtraction. Computes `self - other`, saturating at
+            /// the numeric bounds instead of overflowing.
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn saturating_sub(self, other: $T) -> $T {
+                match self.checked_sub(other) {
+                    Some(x)                       => x,
+                    None if other >= <$T>::zero() => <$T>::min_value(),
+                    None                          => <$T>::max_value(),
+                }
+            }
+
+            /// Raises self to the power of `exp`, using exponentiation by squaring.
+            ///
+            /// # Examples
+            ///
+            /// ```rust
+            /// use std::num::Int;
+            ///
+            /// assert_eq!(2.pow(4), 16);
+            /// ```
+            #[unstable(feature = "core",
+                       reason = "pending integer conventions")]
+            #[inline]
+            pub fn pow(self, mut exp: u32) -> $T {
+                let mut base = self;
+                let mut acc = <$T>::one();
+
+                let mut prev_base = self;
+                let mut base_oflo = false;
+                while exp > 0 {
+                    if (exp & 1) == 1 {
+                        if base_oflo {
+                            // ensure overflow occurs in the same manner it
+                            // would have otherwise (i.e. signal any exception
+                            // it would have otherwise).
+                            acc = acc * (prev_base * prev_base);
+                        } else {
+                            acc = acc * base;
+                        }
+                    }
+                    prev_base = base;
+                    let (new_base, new_base_oflo) = base.overflowing_mul(base);
+                    base = new_base;
+                    base_oflo = new_base_oflo;
+                    exp /= 2;
+                }
+                acc
+            }
+
+            /// Returns `true` iff `self == 2^k` for some `k`.
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn is_power_of_two(self) -> bool {
+                (self.wrapping_sub(<$T>::one())) & self == <$T>::zero() && !(self == <$T>::zero())
+            }
+
+            /// Returns the smallest power of two greater than or equal to `self`.
+            /// Unspecified behavior on overflow.
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[inline]
+            pub fn next_power_of_two(self) -> $T {
+                let bits = size_of::<$T>() * 8;
+                let one: $T = <$T>::one();
+                one << ((bits - self.wrapping_sub(one).leading_zeros() as usize) % bits)
+            }
+
+            /// Returns the smallest power of two greater than or equal to `n`. If the
+            /// next power of two is greater than the type's maximum value, `None` is
+            /// returned, otherwise the power of two is wrapped in `Some`.
+            #[stable(feature = "rust1", since = "1.0.0")]
+            pub fn checked_next_power_of_two(self) -> Option<$T> {
+                let npot = self.next_power_of_two();
+                if npot >= self {
+                    Some(npot)
+                } else {
+                    None
+                }
+            }
+        }
+    }
+
+    /// Swapping a single byte is a no-op. This is marked as `unsafe` for
+    /// consistency with the other `bswap` intrinsics.
+    unsafe fn bswap8(x: u8) -> u8 { x }
+
+    #[lang = "u8"]
+    impl u8 {
+        uint_impl! { u8 = u8, 8,
+            intrinsics::ctpop8,
+            intrinsics::ctlz8,
+            intrinsics::cttz8,
+            bswap8,
+            intrinsics::u8_add_with_overflow,
+            intrinsics::u8_sub_with_overflow,
+            intrinsics::u8_mul_with_overflow }
+    }
+
+    #[lang = "u16"]
+    impl u16 {
+        uint_impl! { u16 = u16, 16,
+            intrinsics::ctpop16,
+            intrinsics::ctlz16,
+            intrinsics::cttz16,
+            intrinsics::bswap16,
+            intrinsics::u16_add_with_overflow,
+            intrinsics::u16_sub_with_overflow,
+            intrinsics::u16_mul_with_overflow }
+    }
+
+    #[lang = "u32"]
+    impl u32 {
+        uint_impl! { u32 = u32, 32,
+            intrinsics::ctpop32,
+            intrinsics::ctlz32,
+            intrinsics::cttz32,
+            intrinsics::bswap32,
+            intrinsics::u32_add_with_overflow,
+            intrinsics::u32_sub_with_overflow,
+            intrinsics::u32_mul_with_overflow }
+    }
+
+
+    #[lang = "u64"]
+    impl u64 {
+        uint_impl! { u64 = u64, 64,
+            intrinsics::ctpop64,
+            intrinsics::ctlz64,
+            intrinsics::cttz64,
+            intrinsics::bswap64,
+            intrinsics::u64_add_with_overflow,
+            intrinsics::u64_sub_with_overflow,
+            intrinsics::u64_mul_with_overflow }
+    }
+
+    #[cfg(target_pointer_width = "32")]
+    #[lang = "usize"]
+    impl usize {
+        uint_impl! { uint = u32, 32,
+            intrinsics::ctpop32,
+            intrinsics::ctlz32,
+            intrinsics::cttz32,
+            intrinsics::bswap32,
+            intrinsics::u32_add_with_overflow,
+            intrinsics::u32_sub_with_overflow,
+            intrinsics::u32_mul_with_overflow }
+    }
+
+    #[cfg(target_pointer_width = "64")]
+    #[lang = "usize"]
+    impl usize {
+        uint_impl! { uint = u64, 64,
+            intrinsics::ctpop64,
+            intrinsics::ctlz64,
+            intrinsics::cttz64,
+            intrinsics::bswap64,
+            intrinsics::u64_add_with_overflow,
+            intrinsics::u64_sub_with_overflow,
+            intrinsics::u64_mul_with_overflow }
+    }
+}
+
 /// A generic trait for converting a value to a number.
 #[unstable(feature = "core", reason = "trait is likely to be removed")]
 pub trait ToPrimitive {
diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs
index c1c8ac9cc1f..377b5b57ae1 100644
--- a/src/libcore/panicking.rs
+++ b/src/libcore/panicking.rs
@@ -35,8 +35,14 @@ use fmt;
 #[cold] #[inline(never)] // this is the slow path, always
 #[lang="panic"]
 pub fn panic(expr_file_line: &(&'static str, &'static str, u32)) -> ! {
+    // Use Arguments::new_v1 instead of format_args!("{}", expr) to potentially
+    // reduce size overhead. The format_args! macro uses str's Display trait to
+    // write expr, which calls Formatter::pad, which must accommodate string
+    // truncation and padding (even though none is used here). Using
+    // Arguments::new_v1 may allow the compiler to omit Formatter::pad from the
+    // output binary, saving up to a few kilobytes.
     let (expr, file, line) = *expr_file_line;
-    panic_fmt(format_args!("{}", expr), &(file, line))
+    panic_fmt(fmt::Arguments::new_v1(&[expr], &[]), &(file, line))
 }
 
 #[cold] #[inline(never)]
diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs
index f4b1a0633de..fb793a62390 100644
--- a/src/libcore/prelude.rs
+++ b/src/libcore/prelude.rs
@@ -29,6 +29,7 @@ pub use marker::{Copy, Send, Sized, Sync};
 pub use ops::{Drop, Fn, FnMut, FnOnce};
 
 // Reexported functions
+#[allow(deprecated)]
 pub use iter::range;
 pub use mem::drop;
 
@@ -41,6 +42,7 @@ pub use iter::{Extend, IteratorExt};
 pub use iter::{Iterator, DoubleEndedIterator};
 pub use iter::{ExactSizeIterator};
 pub use option::Option::{self, Some, None};
+#[cfg(stage0)]
 pub use ptr::{PtrExt, MutPtrExt};
 pub use result::Result::{self, Ok, Err};
 pub use slice::{AsSlice, SliceExt};
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 32123a8271c..f28c26d1798 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -262,6 +262,7 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
     intrinsics::move_val_init(&mut *dst, src)
 }
 
+#[cfg(stage0)]
 /// Methods on raw pointers
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait PtrExt {
@@ -298,6 +299,7 @@ pub trait PtrExt {
     unsafe fn offset(self, count: isize) -> Self where Self::Target: Sized;
 }
 
+#[cfg(stage0)]
 /// Methods on mutable raw pointers
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait MutPtrExt {
@@ -317,6 +319,7 @@ pub trait MutPtrExt {
     unsafe fn as_mut<'a>(&self) -> Option<&'a mut Self::Target>;
 }
 
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> PtrExt for *const T {
     type Target = T;
@@ -344,6 +347,7 @@ impl<T: ?Sized> PtrExt for *const T {
     }
 }
 
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> PtrExt for *mut T {
     type Target = T;
@@ -371,6 +375,7 @@ impl<T: ?Sized> PtrExt for *mut T {
     }
 }
 
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> MutPtrExt for *mut T {
     type Target = T;
@@ -388,6 +393,119 @@ impl<T: ?Sized> MutPtrExt for *mut T {
     }
 }
 
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[lang = "const_ptr"]
+impl<T: ?Sized> *const T {
+    /// Returns true if the pointer is null.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_null(self) -> bool {
+        self == 0 as *const T
+    }
+
+    /// Returns `None` if the pointer is null, or else returns a reference to
+    /// the value wrapped in `Some`.
+    ///
+    /// # Safety
+    ///
+    /// While this method and its mutable counterpart are useful for
+    /// null-safety, it is important to note that this is still an unsafe
+    /// operation because the returned value could be pointing to invalid
+    /// memory.
+    #[unstable(feature = "core",
+               reason = "Option is not clearly the right return type, and we may want \
+                         to tie the return lifetime to a borrow of the raw pointer")]
+    #[inline]
+    pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
+        if self.is_null() {
+            None
+        } else {
+            Some(&**self)
+        }
+    }
+
+    /// Calculates the offset from a pointer. `count` is in units of T; e.g. a
+    /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
+    ///
+    /// # Safety
+    ///
+    /// The offset must be in-bounds of the object, or one-byte-past-the-end.
+    /// Otherwise `offset` invokes Undefined Behaviour, regardless of whether
+    /// the pointer is used.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub unsafe fn offset(self, count: isize) -> *const T where T: Sized {
+        intrinsics::offset(self, count)
+    }
+}
+
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[lang = "mut_ptr"]
+impl<T: ?Sized> *mut T {
+    /// Returns true if the pointer is null.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_null(self) -> bool {
+        self == 0 as *mut T
+    }
+
+    /// Returns `None` if the pointer is null, or else returns a reference to
+    /// the value wrapped in `Some`.
+    ///
+    /// # Safety
+    ///
+    /// While this method and its mutable counterpart are useful for
+    /// null-safety, it is important to note that this is still an unsafe
+    /// operation because the returned value could be pointing to invalid
+    /// memory.
+    #[unstable(feature = "core",
+               reason = "Option is not clearly the right return type, and we may want \
+                         to tie the return lifetime to a borrow of the raw pointer")]
+    #[inline]
+    pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
+        if self.is_null() {
+            None
+        } else {
+            Some(&**self)
+        }
+    }
+
+    /// Calculates the offset from a pointer. `count` is in units of T; e.g. a
+    /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
+    ///
+    /// # Safety
+    ///
+    /// The offset must be in-bounds of the object, or one-byte-past-the-end.
+    /// Otherwise `offset` invokes Undefined Behaviour, regardless of whether
+    /// the pointer is used.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub unsafe fn offset(self, count: isize) -> *mut T where T: Sized {
+        intrinsics::offset(self, count) as *mut T
+    }
+
+    /// Returns `None` if the pointer is null, or else returns a mutable
+    /// reference to the value wrapped in `Some`.
+    ///
+    /// # Safety
+    ///
+    /// As with `as_ref`, this is unsafe because it cannot verify the validity
+    /// of the returned pointer.
+    #[unstable(feature = "core",
+               reason = "return value does not necessarily convey all possible \
+                         information")]
+    #[inline]
+    pub unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> {
+        if self.is_null() {
+            None
+        } else {
+            Some(&mut **self)
+        }
+    }
+}
+
 // Equality for pointers
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> PartialEq for *const T {
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index c61c0f36979..b1576c0d377 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -49,6 +49,7 @@ use option::Option::{None, Some};
 use result::Result;
 use result::Result::{Ok, Err};
 use ptr;
+#[cfg(stage0)]
 use ptr::PtrExt;
 use mem;
 use mem::size_of;
@@ -520,10 +521,10 @@ impl<T> ops::Index<ops::Range<usize>> for [T] {
         assert!(index.start <= index.end);
         assert!(index.end <= self.len());
         unsafe {
-            transmute(RawSlice {
-                    data: self.as_ptr().offset(index.start as isize),
-                    len: index.end - index.start
-                })
+            from_raw_parts (
+                self.as_ptr().offset(index.start as isize),
+                index.end - index.start
+            )
         }
     }
 }
@@ -559,10 +560,10 @@ impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
         assert!(index.start <= index.end);
         assert!(index.end <= self.len());
         unsafe {
-            transmute(RawSlice {
-                    data: self.as_ptr().offset(index.start as isize),
-                    len: index.end - index.start
-                })
+            from_raw_parts_mut(
+                self.as_mut_ptr().offset(index.start as isize),
+                index.end - index.start
+            )
         }
     }
 }
@@ -731,7 +732,21 @@ macro_rules! make_slice {
             diff / mem::size_of::<$t>()
         };
         unsafe {
-            transmute::<_, $result>(RawSlice { data: $start, len: len })
+            from_raw_parts($start, len)
+        }
+    }}
+}
+
+macro_rules! make_mut_slice {
+    ($t: ty => $result: ty: $start: expr, $end: expr) => {{
+        let diff = $end as usize - $start as usize;
+        let len = if mem::size_of::<T>() == 0 {
+            diff
+        } else {
+            diff / mem::size_of::<$t>()
+        };
+        unsafe {
+            from_raw_parts_mut($start, len)
         }
     }}
 }
@@ -898,7 +913,7 @@ impl<'a, T> ops::IndexMut<ops::RangeFrom<usize>> for IterMut<'a, T> {
 impl<'a, T> ops::IndexMut<RangeFull> for IterMut<'a, T> {
     #[inline]
     fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] {
-        make_slice!(T => &mut [T]: self.ptr, self.end)
+        make_mut_slice!(T => &mut [T]: self.ptr, self.end)
     }
 }
 
@@ -912,7 +927,7 @@ impl<'a, T> IterMut<'a, T> {
     /// restricted lifetimes that do not consume the iterator.
     #[unstable(feature = "core")]
     pub fn into_slice(self) -> &'a mut [T] {
-        make_slice!(T => &'a mut [T]: self.ptr, self.end)
+        make_mut_slice!(T => &'a mut [T]: self.ptr, self.end)
     }
 }
 
@@ -1404,7 +1419,7 @@ impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {}
 #[unstable(feature = "core")]
 pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] {
     unsafe {
-        transmute(RawSlice { data: s, len: 1 })
+        from_raw_parts(s, 1)
     }
 }
 
@@ -1412,8 +1427,7 @@ pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] {
 #[unstable(feature = "core")]
 pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] {
     unsafe {
-        let ptr: *const A = transmute(s);
-        transmute(RawSlice { data: ptr, len: 1 })
+        from_raw_parts_mut(s, 1)
     }
 }
 
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 75e5657573e..bd46b093b76 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -30,6 +30,7 @@ use mem;
 use num::Int;
 use ops::{Fn, FnMut};
 use option::Option::{self, None, Some};
+#[cfg(stage0)]
 use ptr::PtrExt;
 use raw::{Repr, Slice};
 use result::Result::{self, Ok, Err};
diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs
index 72b2d5dc188..ba6a7c4a5fe 100644
--- a/src/libcore/tuple.rs
+++ b/src/libcore/tuple.rs
@@ -10,18 +10,12 @@
 
 //! Operations on tuples
 //!
-//! To access a single element of a tuple one can use the following
-//! methods:
+//! To access a single element of a tuple one can use the `.0`
+//! field access syntax.
 //!
-//! * `valN` - returns a value of _N_-th element
-//! * `refN` - returns a reference to _N_-th element
-//! * `mutN` - returns a mutable reference to _N_-th element
-//!
-//! Indexing starts from zero, so `val0` returns first value, `val1`
-//! returns second value, and so on. In general, a tuple with _S_
-//! elements provides aforementioned methods suffixed with numbers
-//! from `0` to `S-1`. Traits which contain these methods are
-//! implemented for tuples with up to 12 elements.
+//! Indexing starts from zero, so `.0` returns first value, `.1`
+//! returns second value, and so on. In general, a tuple with *N*
+//! elements has field accessors from 0 to *N* - 1.
 //!
 //! If every type inside a tuple implements one of the following
 //! traits, then a tuple itself also implements it.
@@ -52,7 +46,7 @@ macro_rules! e {
 macro_rules! tuple_impls {
     ($(
         $Tuple:ident {
-            $(($valN:ident, $refN:ident, $mutN:ident, $idx:tt) -> $T:ident)+
+            $(($idx:tt) -> $T:ident)+
         }
     )+) => {
         $(
@@ -156,105 +150,105 @@ macro_rules! lexical_cmp {
 
 tuple_impls! {
     Tuple1 {
-        (val0, ref0, mut0, 0) -> A
+        (0) -> A
     }
     Tuple2 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
+        (0) -> A
+        (1) -> B
     }
     Tuple3 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
+        (0) -> A
+        (1) -> B
+        (2) -> C
     }
     Tuple4 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
     }
     Tuple5 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
     }
     Tuple6 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
     }
     Tuple7 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
     }
     Tuple8 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-        (val7, ref7, mut7, 7) -> H
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+        (7) -> H
     }
     Tuple9 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-        (val7, ref7, mut7, 7) -> H
-        (val8, ref8, mut8, 8) -> I
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+        (7) -> H
+        (8) -> I
     }
     Tuple10 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-        (val7, ref7, mut7, 7) -> H
-        (val8, ref8, mut8, 8) -> I
-        (val9, ref9, mut9, 9) -> J
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+        (7) -> H
+        (8) -> I
+        (9) -> J
     }
     Tuple11 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-        (val7, ref7, mut7, 7) -> H
-        (val8, ref8, mut8, 8) -> I
-        (val9, ref9, mut9, 9) -> J
-        (val10, ref10, mut10, 10) -> K
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+        (7) -> H
+        (8) -> I
+        (9) -> J
+        (10) -> K
     }
     Tuple12 {
-        (val0, ref0, mut0, 0) -> A
-        (val1, ref1, mut1, 1) -> B
-        (val2, ref2, mut2, 2) -> C
-        (val3, ref3, mut3, 3) -> D
-        (val4, ref4, mut4, 4) -> E
-        (val5, ref5, mut5, 5) -> F
-        (val6, ref6, mut6, 6) -> G
-        (val7, ref7, mut7, 7) -> H
-        (val8, ref8, mut8, 8) -> I
-        (val9, ref9, mut9, 9) -> J
-        (val10, ref10, mut10, 10) -> K
-        (val11, ref11, mut11, 11) -> L
+        (0) -> A
+        (1) -> B
+        (2) -> C
+        (3) -> D
+        (4) -> E
+        (5) -> F
+        (6) -> G
+        (7) -> H
+        (8) -> I
+        (9) -> J
+        (10) -> K
+        (11) -> L
     }
 }
diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs
index 0f4e7fcdda5..52cc2519add 100644
--- a/src/libcoretest/iter.rs
+++ b/src/libcoretest/iter.rs
@@ -775,12 +775,12 @@ fn test_range_inclusive() {
 
 #[test]
 fn test_range_step() {
-    assert_eq!(range_step(0, 20, 5).collect::<Vec<int>>(), [0, 5, 10, 15]);
-    assert_eq!(range_step(20, 0, -5).collect::<Vec<int>>(), [20, 15, 10, 5]);
-    assert_eq!(range_step(20, 0, -6).collect::<Vec<int>>(), [20, 14, 8, 2]);
-    assert_eq!(range_step(200, 255, 50).collect::<Vec<u8>>(), [200, 250]);
-    assert_eq!(range_step(200, -5, 1).collect::<Vec<int>>(), []);
-    assert_eq!(range_step(200, 200, 1).collect::<Vec<int>>(), []);
+    assert_eq!((0..20).step_by(5).collect::<Vec<int>>(), [0, 5, 10, 15]);
+    assert_eq!((20..0).step_by(-5).collect::<Vec<int>>(), [20, 15, 10, 5]);
+    assert_eq!((20..0).step_by(-6).collect::<Vec<int>>(), [20, 14, 8, 2]);
+    assert_eq!((200..255).step_by(50).collect::<Vec<u8>>(), [200, 250]);
+    assert_eq!((200..-5).step_by(1).collect::<Vec<int>>(), []);
+    assert_eq!((200..200).step_by(1).collect::<Vec<int>>(), []);
 }
 
 #[test]
diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs
index 100a9e36e86..695c71c73ed 100644
--- a/src/libflate/lib.rs
+++ b/src/libflate/lib.rs
@@ -25,7 +25,6 @@
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 
-#![feature(int_uint)]
 #![feature(libc)]
 #![feature(staged_api)]
 #![feature(unique)]
@@ -35,13 +34,33 @@
 extern crate libc;
 
 use libc::{c_void, size_t, c_int};
+use std::fmt;
 use std::ops::Deref;
 use std::ptr::Unique;
 use std::slice;
 
+#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub struct Error {
+    _unused: (),
+}
+
+impl Error {
+    fn new() -> Error {
+        Error {
+            _unused: (),
+        }
+    }
+}
+
+impl fmt::Debug for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        "decompression error".fmt(f)
+    }
+}
+
 pub struct Bytes {
     ptr: Unique<u8>,
-    len: uint,
+    len: usize,
 }
 
 impl Deref for Bytes {
@@ -78,55 +97,56 @@ const LZ_NORM: c_int = 0x80;  // LZ with 128 probes, "normal"
 const TINFL_FLAG_PARSE_ZLIB_HEADER: c_int = 0x1; // parse zlib header and adler32 checksum
 const TDEFL_WRITE_ZLIB_HEADER: c_int = 0x01000; // write zlib header and adler32 checksum
 
-fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<Bytes> {
+fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Bytes {
     unsafe {
-        let mut outsz : size_t = 0;
+        let mut outsz: size_t = 0;
         let res = tdefl_compress_mem_to_heap(bytes.as_ptr() as *const _,
                                              bytes.len() as size_t,
                                              &mut outsz,
                                              flags);
-        if !res.is_null() {
-            let res = Unique::new(res as *mut u8);
-            Some(Bytes { ptr: res, len: outsz as uint })
-        } else {
-            None
+        assert!(!res.is_null());
+        Bytes {
+            ptr: Unique::new(res as *mut u8),
+            len: outsz as usize,
         }
     }
 }
 
 /// Compress a buffer, without writing any sort of header on the output.
-pub fn deflate_bytes(bytes: &[u8]) -> Option<Bytes> {
+pub fn deflate_bytes(bytes: &[u8]) -> Bytes {
     deflate_bytes_internal(bytes, LZ_NORM)
 }
 
 /// Compress a buffer, using a header that zlib can understand.
-pub fn deflate_bytes_zlib(bytes: &[u8]) -> Option<Bytes> {
+pub fn deflate_bytes_zlib(bytes: &[u8]) -> Bytes {
     deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER)
 }
 
-fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<Bytes> {
+fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Result<Bytes,Error> {
     unsafe {
-        let mut outsz : size_t = 0;
+        let mut outsz: size_t = 0;
         let res = tinfl_decompress_mem_to_heap(bytes.as_ptr() as *const _,
                                                bytes.len() as size_t,
                                                &mut outsz,
                                                flags);
         if !res.is_null() {
-            let res = Unique::new(res as *mut u8);
-            Some(Bytes { ptr: res, len: outsz as uint })
+            Ok(Bytes {
+                ptr: Unique::new(res as *mut u8),
+                len: outsz as usize,
+            })
         } else {
-            None
+            Err(Error::new())
         }
     }
 }
 
 /// Decompress a buffer, without parsing any sort of header on the input.
-pub fn inflate_bytes(bytes: &[u8]) -> Option<Bytes> {
+pub fn inflate_bytes(bytes: &[u8]) -> Result<Bytes,Error> {
     inflate_bytes_internal(bytes, 0)
 }
 
 /// Decompress a buffer that starts with a zlib header.
-pub fn inflate_bytes_zlib(bytes: &[u8]) -> Option<Bytes> {
+pub fn inflate_bytes_zlib(bytes: &[u8]) -> Result<Bytes,Error> {
     inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
 }
 
@@ -140,7 +160,7 @@ mod tests {
     #[test]
     fn test_flate_round_trip() {
         let mut r = rand::thread_rng();
-        let mut words = vec!();
+        let mut words = vec![];
         for _ in 0..20 {
             let range = r.gen_range(1, 10);
             let v = r.gen_iter::<u8>().take(range).collect::<Vec<u8>>();
@@ -153,8 +173,8 @@ mod tests {
             }
             debug!("de/inflate of {} bytes of random word-sequences",
                    input.len());
-            let cmp = deflate_bytes(&input).expect("deflation failed");
-            let out = inflate_bytes(&cmp).expect("inflation failed");
+            let cmp = deflate_bytes(&input);
+            let out = inflate_bytes(&cmp).unwrap();
             debug!("{} bytes deflated to {} ({:.1}% size)",
                    input.len(), cmp.len(),
                    100.0 * ((cmp.len() as f64) / (input.len() as f64)));
@@ -164,9 +184,9 @@ mod tests {
 
     #[test]
     fn test_zlib_flate() {
-        let bytes = vec!(1, 2, 3, 4, 5);
-        let deflated = deflate_bytes(&bytes).expect("deflation failed");
-        let inflated = inflate_bytes(&deflated).expect("inflation failed");
+        let bytes = vec![1, 2, 3, 4, 5];
+        let deflated = deflate_bytes(&bytes);
+        let inflated = inflate_bytes(&deflated).unwrap();
         assert_eq!(&*inflated, &*bytes);
     }
 }
diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs
index 11aba40afad..82c54004e99 100644
--- a/src/liblibc/lib.rs
+++ b/src/liblibc/lib.rs
@@ -3298,7 +3298,7 @@ pub mod consts {
             pub const MAP_DENYWRITE : c_int = 0x0800;
             pub const MAP_EXECUTABLE : c_int = 0x01000;
             pub const MAP_LOCKED : c_int = 0x02000;
-            pub const MAP_NONRESERVE : c_int = 0x04000;
+            pub const MAP_NORESERVE : c_int = 0x04000;
             pub const MAP_POPULATE : c_int = 0x08000;
             pub const MAP_NONBLOCK : c_int = 0x010000;
             pub const MAP_STACK : c_int = 0x020000;
@@ -3325,7 +3325,7 @@ pub mod consts {
             pub const MAP_DENYWRITE : c_int = 0x02000;
             pub const MAP_EXECUTABLE : c_int = 0x04000;
             pub const MAP_LOCKED : c_int = 0x08000;
-            pub const MAP_NONRESERVE : c_int = 0x0400;
+            pub const MAP_NORESERVE : c_int = 0x0400;
             pub const MAP_POPULATE : c_int = 0x010000;
             pub const MAP_NONBLOCK : c_int = 0x020000;
             pub const MAP_STACK : c_int = 0x040000;
diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs
index b03d77db4ec..c634a46888e 100644
--- a/src/liblog/lib.rs
+++ b/src/liblog/lib.rs
@@ -175,7 +175,6 @@
 #![feature(int_uint)]
 #![feature(core)]
 #![feature(std_misc)]
-#![feature(io)]
 
 use std::boxed;
 use std::cell::RefCell;
diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs
index 4a0807bf099..a46709932e2 100644
--- a/src/librand/distributions/mod.rs
+++ b/src/librand/distributions/mod.rs
@@ -17,8 +17,6 @@
 //! internally. The `IndependentSample` trait is for generating values
 //! that do not need to record state.
 
-#![unstable(feature = "rand")]
-
 use core::prelude::*;
 use core::num::{Float, Int};
 use core::marker::PhantomData;
@@ -125,7 +123,7 @@ impl<'a, T: Clone> WeightedChoice<'a, T> {
         // strictly speaking, this is subsumed by the total weight == 0 case
         assert!(!items.is_empty(), "WeightedChoice::new called with no items");
 
-        let mut running_total = 0;
+        let mut running_total = 0_usize;
 
         // we convert the list from individual weights to cumulative
         // weights so we can binary search. This *could* drop elements
diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs
index 8486bf782b0..e466dc8a3a0 100644
--- a/src/librustc/metadata/loader.rs
+++ b/src/librustc/metadata/loader.rs
@@ -784,8 +784,8 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
                        csz - vlen);
                 let bytes = slice::from_raw_parts(cvbuf1, csz - vlen);
                 match flate::inflate_bytes(bytes) {
-                    Some(inflated) => return Ok(MetadataVec(inflated)),
-                    None => {}
+                    Ok(inflated) => return Ok(MetadataVec(inflated)),
+                    Err(_) => {}
                 }
             }
             llvm::LLVMMoveToNextSection(si.llsi);
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index 40bba6fb0ac..313f034021f 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -27,6 +27,7 @@ use middle::ty;
 use std::cmp::Ordering;
 use std::fmt;
 use std::iter::{range_inclusive, AdditiveIterator, FromIterator, IntoIterator, repeat};
+#[cfg(stage0)]
 use std::num::Float;
 use std::slice;
 use syntax::ast::{self, DUMMY_NODE_ID, NodeId, Pat};
@@ -646,6 +647,7 @@ fn is_useful(cx: &MatchCheckCtxt,
     if rows[0].len() == 0 {
         return NotUseful;
     }
+    assert!(rows.iter().all(|r| r.len() == v.len()));
     let real_pat = match rows.iter().find(|r| (*r)[0].id != DUMMY_NODE_ID) {
         Some(r) => raw_pat(r[0]),
         None if v.len() == 0 => return NotUseful,
@@ -654,7 +656,12 @@ fn is_useful(cx: &MatchCheckCtxt,
     let left_ty = if real_pat.id == DUMMY_NODE_ID {
         ty::mk_nil(cx.tcx)
     } else {
-        ty::pat_ty(cx.tcx, &*real_pat)
+        let left_ty = ty::pat_ty(cx.tcx, &*real_pat);
+
+        match real_pat.node {
+            ast::PatIdent(ast::BindByRef(..), _, _) => ty::deref(left_ty, false).unwrap().ty,
+            _ => left_ty,
+        }
     };
 
     let max_slice_length = rows.iter().filter_map(|row| match row[0].node {
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 09378f2c973..5efea66ab0c 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -47,7 +47,6 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
     struct_has_extern_repr: bool,
     ignore_non_const_paths: bool,
     inherited_pub_visibility: bool,
-    ignore_variant_stack: Vec<ast::NodeId>,
 }
 
 impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
@@ -60,7 +59,6 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
             struct_has_extern_repr: false,
             ignore_non_const_paths: false,
             inherited_pub_visibility: false,
-            ignore_variant_stack: vec![],
         }
     }
 
@@ -81,9 +79,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
                 def::DefPrimTy(_) => (),
                 def::DefVariant(enum_id, variant_id, _) => {
                     self.check_def_id(enum_id);
-                    if !self.ignore_variant_stack.contains(&variant_id.node) {
-                        self.check_def_id(variant_id);
-                    }
+                    self.check_def_id(variant_id);
                 }
                 _ => {
                     self.check_def_id(def.def_id());
@@ -282,23 +278,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
         visit::walk_expr(self, expr);
     }
 
-    fn visit_arm(&mut self, arm: &ast::Arm) {
-        if arm.pats.len() == 1 {
-            let pat = &*arm.pats[0];
-            let variants = pat_util::necessary_variants(&self.tcx.def_map, pat);
-
-            // Inside the body, ignore constructions of variants
-            // necessary for the pattern to match. Those construction sites
-            // can't be reached unless the variant is constructed elsewhere.
-            let len = self.ignore_variant_stack.len();
-            self.ignore_variant_stack.push_all(&*variants);
-            visit::walk_arm(self, arm);
-            self.ignore_variant_stack.truncate(len);
-        } else {
-            visit::walk_arm(self, arm);
-        }
-    }
-
     fn visit_pat(&mut self, pat: &ast::Pat) {
         let def_map = &self.tcx.def_map;
         match pat.node {
@@ -418,11 +397,6 @@ fn create_and_seed_worklist(tcx: &ty::ctxt,
         worklist.push(*id);
     }
     for id in reachable_symbols {
-        // Reachable variants can be dead, because we warn about
-        // variants never constructed, not variants never used.
-        if let Some(ast_map::NodeVariant(..)) = tcx.map.find(*id) {
-            continue;
-        }
         worklist.push(*id);
     }
 
diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs
index be94a73df37..9add236d54b 100644
--- a/src/librustc/middle/infer/combine.rs
+++ b/src/librustc/middle/infer/combine.rs
@@ -154,7 +154,7 @@ pub trait Combine<'tcx> : Sized {
                                                                  b_tys.len())));
             }
 
-            range(0, a_tys.len()).map(|i| {
+            (0.. a_tys.len()).map(|i| {
                 let a_ty = a_tys[i];
                 let b_ty = b_tys[i];
                 let v = variances.map_or(ty::Invariant, |v| v[i]);
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 3525d46a1f2..1ad4611dc9e 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -239,6 +239,24 @@ pub fn collect_language_items(krate: &ast::Crate,
 
 lets_do_this! {
 //  Variant name,                    Name,                      Method name;
+    CharImplItem,                    "char",                    char_impl;
+    StrImplItem,                     "str",                     str_impl;
+    SliceImplItem,                   "slice",                   slice_impl;
+    ConstPtrImplItem,                "const_ptr",               const_ptr_impl;
+    MutPtrImplItem,                  "mut_ptr",                 mut_ptr_impl;
+    I8ImplItem,                      "i8",                      i8_impl;
+    I16ImplItem,                     "i16",                     i16_impl;
+    I32ImplItem,                     "i32",                     i32_impl;
+    I64ImplItem,                     "i64",                     i64_impl;
+    IsizeImplItem,                   "isize",                   isize_impl;
+    U8ImplItem,                      "u8",                      u8_impl;
+    U16ImplItem,                     "u16",                     u16_impl;
+    U32ImplItem,                     "u32",                     u32_impl;
+    U64ImplItem,                     "u64",                     u64_impl;
+    UsizeImplItem,                   "usize",                   usize_impl;
+    F32ImplItem,                     "f32",                     f32_impl;
+    F64ImplItem,                     "f64",                     f64_impl;
+
     SendTraitLangItem,               "send",                    send_trait;
     SizedTraitLangItem,              "sized",                   sized_trait;
     CopyTraitLangItem,               "copy",                    copy_trait;
diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs
index eca3296e65c..c5abff3b963 100644
--- a/src/librustc/middle/pat_util.rs
+++ b/src/librustc/middle/pat_util.rs
@@ -155,27 +155,3 @@ pub fn def_to_path(tcx: &ty::ctxt, id: ast::DefId) -> ast::Path {
         span: DUMMY_SP,
     })
 }
-
-/// Return variants that are necessary to exist for the pattern to match.
-pub fn necessary_variants(dm: &DefMap, pat: &ast::Pat) -> Vec<ast::NodeId> {
-    let mut variants = vec![];
-    walk_pat(pat, |p| {
-        match p.node {
-            ast::PatEnum(_, _) |
-            ast::PatIdent(_, _, None) |
-            ast::PatStruct(..) => {
-                match dm.borrow().get(&p.id) {
-                    Some(&PathResolution {base_def: DefVariant(_, id, _), ..}) => {
-                        variants.push(id.node);
-                    }
-                    _ => ()
-                }
-            }
-            _ => ()
-        }
-        true
-    });
-    variants.sort();
-    variants.dedup();
-    variants
-}
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 8705e56b094..c3e1879fca8 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -788,6 +788,9 @@ pub struct ctxt<'tcx> {
     /// is used for lazy resolution of traits.
     pub populated_external_traits: RefCell<DefIdSet>,
 
+    /// The set of external primitive inherent implementations that have been read.
+    pub populated_external_primitive_impls: RefCell<DefIdSet>,
+
     /// Borrows
     pub upvar_capture_map: RefCell<UpvarCaptureMap>,
 
@@ -2599,6 +2602,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
         used_mut_nodes: RefCell::new(NodeSet()),
         populated_external_types: RefCell::new(DefIdSet()),
         populated_external_traits: RefCell::new(DefIdSet()),
+        populated_external_primitive_impls: RefCell::new(DefIdSet()),
         upvar_capture_map: RefCell::new(FnvHashMap()),
         extern_const_statics: RefCell::new(DefIdMap()),
         extern_const_variants: RefCell::new(DefIdMap()),
@@ -5988,6 +5992,25 @@ pub fn record_trait_implementation(tcx: &ctxt,
     tcx.trait_impls.borrow_mut().insert(trait_def_id, Rc::new(RefCell::new(vec!(impl_def_id))));
 }
 
+/// Load primitive inherent implementations if necessary
+pub fn populate_implementations_for_primitive_if_necessary(tcx: &ctxt, lang_def_id: ast::DefId) {
+    if lang_def_id.krate == LOCAL_CRATE {
+        return
+    }
+    if tcx.populated_external_primitive_impls.borrow().contains(&lang_def_id) {
+        return
+    }
+
+    debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}", lang_def_id);
+
+    let impl_items = csearch::get_impl_items(&tcx.sess.cstore, lang_def_id);
+
+    // Store the implementation info.
+    tcx.impl_items.borrow_mut().insert(lang_def_id, impl_items);
+
+    tcx.populated_external_primitive_impls.borrow_mut().insert(lang_def_id);
+}
+
 /// Populates the type context with all the implementations for the given type
 /// if necessary.
 pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
diff --git a/src/librustc/session/search_paths.rs b/src/librustc/session/search_paths.rs
index f85fb303910..3c5d9744505 100644
--- a/src/librustc/session/search_paths.rs
+++ b/src/librustc/session/search_paths.rs
@@ -10,6 +10,7 @@
 
 use std::slice;
 use std::path::{Path, PathBuf};
+use session::early_error;
 
 #[derive(Clone, Debug)]
 pub struct SearchPaths {
@@ -50,6 +51,9 @@ impl SearchPaths {
         } else {
             (PathKind::All, path)
         };
+        if path.is_empty() {
+            early_error("empty search path given via `-L`");
+        }
         self.paths.push((kind, PathBuf::new(path)));
     }
 
diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs
index 77338dddefa..99d24a60130 100644
--- a/src/librustc_back/lib.rs
+++ b/src/librustc_back/lib.rs
@@ -48,6 +48,7 @@
 #![feature(path_ext)]
 #![feature(std_misc)]
 #![feature(path_relative_from)]
+#![feature(step_by)]
 
 extern crate syntax;
 extern crate serialize;
diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs
index 467b7c1ca38..5aae0e9dbdc 100644
--- a/src/librustc_back/svh.rs
+++ b/src/librustc_back/svh.rs
@@ -48,7 +48,6 @@
 
 use std::fmt;
 use std::hash::{Hash, SipHasher, Hasher};
-use std::iter::range_step;
 use syntax::ast;
 use syntax::visit;
 
@@ -103,7 +102,7 @@ impl Svh {
 
         let hash = state.finish();
         return Svh {
-            hash: range_step(0, 64, 4).map(|i| hex(hash >> i)).collect()
+            hash: (0..64).step_by(4).map(|i| hex(hash >> i)).collect()
         };
 
         fn hex(b: u64) -> char {
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index e0261606ef1..e132e9833c1 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -37,7 +37,7 @@
 #![feature(staged_api)]
 #![feature(exit_status)]
 #![feature(io)]
-#![feature(set_panic)]
+#![feature(set_stdio)]
 
 extern crate arena;
 extern crate flate;
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 074591fb927..f6f82c65374 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -811,7 +811,7 @@ impl NonCamelCaseTypes {
                 if i == 0 {
                     c.to_uppercase().collect::<String>()
                 } else {
-                    c.to_string()
+                    c.to_lowercase().collect()
                 }
             )).collect::<Vec<_>>().concat()
         }
diff --git a/src/librustc_llvm/archive_ro.rs b/src/librustc_llvm/archive_ro.rs
index f54480e3e52..0728d5b46e2 100644
--- a/src/librustc_llvm/archive_ro.rs
+++ b/src/librustc_llvm/archive_ro.rs
@@ -14,8 +14,7 @@ use libc;
 use ArchiveRef;
 
 use std::ffi::CString;
-use std::mem;
-use std::raw;
+use std::slice;
 use std::path::Path;
 
 pub struct ArchiveRO {
@@ -62,10 +61,7 @@ impl ArchiveRO {
             if ptr.is_null() {
                 None
             } else {
-                Some(mem::transmute(raw::Slice {
-                    data: ptr,
-                    len: size as uint,
-                }))
+                Some(slice::from_raw_parts(ptr as *const u8, size as uint))
             }
         }
     }
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index 71233ff5003..506bf4a058f 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -26,7 +26,6 @@
 
 #![feature(box_syntax)]
 #![feature(collections)]
-#![feature(core)]
 #![feature(int_uint)]
 #![feature(libc)]
 #![feature(link_args)]
@@ -58,7 +57,7 @@ pub use self::Linkage::*;
 
 use std::ffi::CString;
 use std::cell::RefCell;
-use std::{raw, mem};
+use std::{slice, mem};
 use libc::{c_uint, c_ushort, uint64_t, c_int, size_t, c_char};
 use libc::{c_longlong, c_ulonglong, c_void};
 use debuginfo::{DIBuilderRef, DIDescriptor,
@@ -2226,10 +2225,7 @@ type RustStringRepr = *mut RefCell<Vec<u8>>;
 pub unsafe extern "C" fn rust_llvm_string_write_impl(sr: RustStringRef,
                                                      ptr: *const c_char,
                                                      size: size_t) {
-    let slice: &[u8] = mem::transmute(raw::Slice {
-        data: ptr as *const u8,
-        len: size as uint,
-    });
+    let slice = slice::from_raw_parts(ptr as *const u8, size as uint);
 
     let sr: RustStringRepr = mem::transmute(sr);
     (*sr).borrow_mut().push_all(slice);
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 1cbbcad9550..e62300098f6 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -14,16 +14,17 @@
 //! any imports resolved.
 
 use {DefModifiers, PUBLIC, IMPORTABLE};
-use ImportDirective;
-use ImportDirectiveSubclass::{self, SingleImport, GlobImport};
-use ImportResolution;
+use resolve_imports::ImportDirective;
+use resolve_imports::ImportDirectiveSubclass::{self, SingleImport, GlobImport};
+use resolve_imports::ImportResolution;
 use Module;
 use ModuleKind::*;
 use Namespace::{TypeNS, ValueNS};
 use NameBindings;
+use {names_to_string, module_to_string};
 use ParentLink::{self, ModuleParentLink, BlockParentLink};
 use Resolver;
-use Shadowable;
+use resolve_imports::Shadowable;
 use TypeNsDef;
 
 use self::DuplicateCheckingMode::*;
@@ -371,8 +372,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
             ItemExternCrate(_) => {
                 // n.b. we don't need to look at the path option here, because cstore already did
-                for &crate_id in self.session.cstore
-                                     .find_extern_mod_stmt_cnum(item.id).iter() {
+                if let Some(crate_id) = self.session.cstore.find_extern_mod_stmt_cnum(item.id) {
                     let def_id = DefId { krate: crate_id, node: 0 };
                     self.external_exports.insert(def_id);
                     let parent_link = ModuleParentLink(parent.downgrade(), name);
@@ -382,7 +382,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                                               false,
                                                               true));
                     debug!("(build reduced graph for item) found extern `{}`",
-                            self.module_to_string(&*external_module));
+                            module_to_string(&*external_module));
                     self.check_for_conflicts_between_external_crates(&**parent, name, sp);
                     parent.external_module_children.borrow_mut()
                           .insert(name, external_module.clone());
@@ -400,7 +400,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                             Some(def_id),
                                             NormalModuleKind,
                                             false,
-                                            item.vis == ast::Public,
+                                            is_public,
                                             sp);
 
                 name_bindings.get_module()
@@ -432,8 +432,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
             // These items live in the type namespace.
             ItemTy(..) => {
                 let name_bindings =
-                    self.add_child(name, parent, ForbidDuplicateTypesAndModules,
-                                   sp);
+                    self.add_child(name, parent, ForbidDuplicateTypesAndModules, sp);
 
                 name_bindings.define_type(DefTy(local_def(item.id), false), sp,
                                           modifiers);
@@ -517,7 +516,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                             Some(local_def(item.id)),
                                             TraitModuleKind,
                                             false,
-                                            item.vis == ast::Public,
+                                            is_public,
                                             sp);
                 let module_parent = name_bindings.get_module();
 
@@ -636,8 +635,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                            name: Name,
                            new_parent: &Rc<Module>) {
         debug!("(building reduced graph for \
-                external crate) building external def, priv {:?}",
-               vis);
+                external crate) building external def {}, priv {:?}",
+               final_ident, vis);
         let is_public = vis == ast::Public;
         let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
         let is_exported = is_public && match new_parent.def_id.get() {
@@ -667,7 +666,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
               Some(_) | None => {
                 debug!("(building reduced graph for \
                         external crate) building module \
-                        {}", final_ident);
+                        {} {}", final_ident, is_public);
                 let parent_link = self.get_parent_link(new_parent, name);
 
                 child_name_bindings.define_module(parent_link,
@@ -838,7 +837,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
     /// Builds the reduced graph rooted at the given external module.
     fn populate_external_module(&mut self, module: &Rc<Module>) {
         debug!("(populating external module) attempting to populate {}",
-               self.module_to_string(&**module));
+               module_to_string(&**module));
 
         let def_id = match module.def_id.get() {
             None => {
@@ -904,18 +903,14 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
 
         match subclass {
             SingleImport(target, _) => {
-                debug!("(building import directive) building import \
-                        directive: {}::{}",
-                       self.names_to_string(&module_.imports.borrow().last().unwrap().
-                                                             module_path),
+                debug!("(building import directive) building import directive: {}::{}",
+                       names_to_string(&module_.imports.borrow().last().unwrap().module_path),
                        token::get_name(target));
 
-                let mut import_resolutions = module_.import_resolutions
-                                                    .borrow_mut();
+                let mut import_resolutions = module_.import_resolutions.borrow_mut();
                 match import_resolutions.get_mut(&target) {
                     Some(resolution) => {
-                        debug!("(building import directive) bumping \
-                                reference");
+                        debug!("(building import directive) bumping reference");
                         resolution.outstanding_references += 1;
 
                         // the source of this name is different now
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 124aa392435..c586faae6e8 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -24,7 +24,9 @@ register_diagnostics! {
     E0258, // import conflicts with existing submodule
     E0259, // an extern crate has already been imported into this module
     E0260, // name conflicts with an external crate that has been imported into this module
-    E0317 // user-defined types or type parameters cannot shadow the primitive types
+    E0317, // user-defined types or type parameters cannot shadow the primitive types
+    E0364, // item is private
+    E0365  // item is private
 }
 
 __build_diagnostic_array! { DIAGNOSTICS }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index e49fdc9c5d3..67e9f71551a 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -38,7 +38,6 @@ use self::PatternBindingMode::*;
 use self::Namespace::*;
 use self::NamespaceResult::*;
 use self::NameDefinition::*;
-use self::ImportDirectiveSubclass::*;
 use self::ResolveResult::*;
 use self::FallbackSuggestion::*;
 use self::TypeParameters::*;
@@ -98,6 +97,10 @@ use std::mem::replace;
 use std::rc::{Rc, Weak};
 use std::usize;
 
+use resolve_imports::{Target, ImportDirective, ImportResolution};
+use resolve_imports::Shadowable;
+
+
 // NB: This module needs to be declared first so diagnostics are
 // registered before they are used.
 pub mod diagnostics;
@@ -105,6 +108,7 @@ pub mod diagnostics;
 mod check_unused;
 mod record_exports;
 mod build_reduced_graph;
+mod resolve_imports;
 
 #[derive(Copy)]
 struct BindingInfo {
@@ -253,13 +257,6 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
     }
 }
 
-/// Contains data for specific types of import directives.
-#[derive(Copy,Debug)]
-enum ImportDirectiveSubclass {
-    SingleImport(Name /* target */, Name /* source */),
-    GlobImport
-}
-
 type ErrorMessage = Option<(Span, String)>;
 
 enum ResolveResult<T> {
@@ -366,144 +363,6 @@ impl Rib {
     }
 }
 
-/// Whether an import can be shadowed by another import.
-#[derive(Debug,PartialEq,Clone,Copy)]
-enum Shadowable {
-    Always,
-    Never
-}
-
-/// One import directive.
-#[derive(Debug)]
-struct ImportDirective {
-    module_path: Vec<Name>,
-    subclass: ImportDirectiveSubclass,
-    span: Span,
-    id: NodeId,
-    is_public: bool, // see note in ImportResolution about how to use this
-    shadowable: Shadowable,
-}
-
-impl ImportDirective {
-    fn new(module_path: Vec<Name> ,
-           subclass: ImportDirectiveSubclass,
-           span: Span,
-           id: NodeId,
-           is_public: bool,
-           shadowable: Shadowable)
-           -> ImportDirective {
-        ImportDirective {
-            module_path: module_path,
-            subclass: subclass,
-            span: span,
-            id: id,
-            is_public: is_public,
-            shadowable: shadowable,
-        }
-    }
-}
-
-/// The item that an import resolves to.
-#[derive(Clone,Debug)]
-struct Target {
-    target_module: Rc<Module>,
-    bindings: Rc<NameBindings>,
-    shadowable: Shadowable,
-}
-
-impl Target {
-    fn new(target_module: Rc<Module>,
-           bindings: Rc<NameBindings>,
-           shadowable: Shadowable)
-           -> Target {
-        Target {
-            target_module: target_module,
-            bindings: bindings,
-            shadowable: shadowable,
-        }
-    }
-}
-
-/// An ImportResolution represents a particular `use` directive.
-#[derive(Debug)]
-struct ImportResolution {
-    /// Whether this resolution came from a `use` or a `pub use`. Note that this
-    /// should *not* be used whenever resolution is being performed, this is
-    /// only looked at for glob imports statements currently. Privacy testing
-    /// occurs during a later phase of compilation.
-    is_public: bool,
-
-    // The number of outstanding references to this name. When this reaches
-    // zero, outside modules can count on the targets being correct. Before
-    // then, all bets are off; future imports could override this name.
-    outstanding_references: uint,
-
-    /// The value that this `use` directive names, if there is one.
-    value_target: Option<Target>,
-    /// The source node of the `use` directive leading to the value target
-    /// being non-none
-    value_id: NodeId,
-
-    /// The type that this `use` directive names, if there is one.
-    type_target: Option<Target>,
-    /// The source node of the `use` directive leading to the type target
-    /// being non-none
-    type_id: NodeId,
-}
-
-impl ImportResolution {
-    fn new(id: NodeId, is_public: bool) -> ImportResolution {
-        ImportResolution {
-            type_id: id,
-            value_id: id,
-            outstanding_references: 0,
-            value_target: None,
-            type_target: None,
-            is_public: is_public,
-        }
-    }
-
-    fn target_for_namespace(&self, namespace: Namespace)
-                                -> Option<Target> {
-        match namespace {
-            TypeNS  => self.type_target.clone(),
-            ValueNS => self.value_target.clone(),
-        }
-    }
-
-    fn id(&self, namespace: Namespace) -> NodeId {
-        match namespace {
-            TypeNS  => self.type_id,
-            ValueNS => self.value_id,
-        }
-    }
-
-    fn shadowable(&self, namespace: Namespace) -> Shadowable {
-        let target = self.target_for_namespace(namespace);
-        if target.is_none() {
-            return Shadowable::Always;
-        }
-
-        target.unwrap().shadowable
-    }
-
-    fn set_target_and_id(&mut self,
-                         namespace: Namespace,
-                         target: Option<Target>,
-                         id: NodeId) {
-        match namespace {
-            TypeNS  => {
-                self.type_target = target;
-                self.type_id = id;
-            }
-            ValueNS => {
-                self.value_target = target;
-                self.value_id = id;
-            }
-        }
-    }
-}
-
 /// The link from a module up to its nearest parent node.
 #[derive(Clone,Debug)]
 enum ParentLink {
@@ -855,6 +714,19 @@ impl NameBindings {
             None
         }
     }
+
+    fn is_public(&self, namespace: Namespace) -> bool {
+        match namespace {
+            TypeNS  => {
+                let type_def = self.type_def.borrow();
+                type_def.as_ref().unwrap().modifiers.contains(PUBLIC)
+            }
+            ValueNS => {
+                let value_def = self.value_def.borrow();
+                value_def.as_ref().unwrap().modifiers.contains(PUBLIC)
+            }
+        }
+    }
 }
 
 /// Interns the names of the primitive types.
@@ -963,7 +835,6 @@ enum FallbackChecks {
     OnlyTraitAndStatics
 }
 
-
 impl<'a, 'tcx> Resolver<'a, 'tcx> {
     fn new(session: &'a Session,
            ast_map: &'a ast_map::Map<'tcx>,
@@ -1023,151 +894,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
     }
 
-    // Import resolution
-    //
-    // This is a fixed-point algorithm. We resolve imports until our efforts
-    // are stymied by an unresolved import; then we bail out of the current
-    // module and continue. We terminate successfully once no more imports
-    // remain or unsuccessfully when no forward progress in resolving imports
-    // is made.
-
-    /// Resolves all imports for the crate. This method performs the fixed-
-    /// point iteration.
-    fn resolve_imports(&mut self) {
-        let mut i = 0;
-        let mut prev_unresolved_imports = 0;
-        loop {
-            debug!("(resolving imports) iteration {}, {} imports left",
-                   i, self.unresolved_imports);
-
-            let module_root = self.graph_root.get_module();
-            self.resolve_imports_for_module_subtree(module_root.clone());
-
-            if self.unresolved_imports == 0 {
-                debug!("(resolving imports) success");
-                break;
-            }
-
-            if self.unresolved_imports == prev_unresolved_imports {
-                self.report_unresolved_imports(module_root);
-                break;
-            }
-
-            i += 1;
-            prev_unresolved_imports = self.unresolved_imports;
-        }
-    }
-
-    /// Attempts to resolve imports for the given module and all of its
-    /// submodules.
-    fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
-        debug!("(resolving imports for module subtree) resolving {}",
-               self.module_to_string(&*module_));
-        let orig_module = replace(&mut self.current_module, module_.clone());
-        self.resolve_imports_for_module(module_.clone());
-        self.current_module = orig_module;
-
-        build_reduced_graph::populate_module_if_necessary(self, &module_);
-        for (_, child_node) in &*module_.children.borrow() {
-            match child_node.get_module_if_available() {
-                None => {
-                    // Nothing to do.
-                }
-                Some(child_module) => {
-                    self.resolve_imports_for_module_subtree(child_module);
-                }
-            }
-        }
-
-        for (_, child_module) in &*module_.anonymous_children.borrow() {
-            self.resolve_imports_for_module_subtree(child_module.clone());
-        }
-    }
-
-    /// Attempts to resolve imports for the given module only.
-    fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
-        if module.all_imports_resolved() {
-            debug!("(resolving imports for module) all imports resolved for \
-                   {}",
-                   self.module_to_string(&*module));
-            return;
-        }
-
-        let imports = module.imports.borrow();
-        let import_count = imports.len();
-        while module.resolved_import_count.get() < import_count {
-            let import_index = module.resolved_import_count.get();
-            let import_directive = &(*imports)[import_index];
-            match self.resolve_import_for_module(module.clone(),
-                                                 import_directive) {
-                Failed(err) => {
-                    let (span, help) = match err {
-                        Some((span, msg)) => (span, format!(". {}", msg)),
-                        None => (import_directive.span, String::new())
-                    };
-                    let msg = format!("unresolved import `{}`{}",
-                                      self.import_path_to_string(
-                                          &import_directive.module_path,
-                                          import_directive.subclass),
-                                      help);
-                    self.resolve_error(span, &msg[..]);
-                }
-                Indeterminate => break, // Bail out. We'll come around next time.
-                Success(()) => () // Good. Continue.
-            }
-
-            module.resolved_import_count
-                  .set(module.resolved_import_count.get() + 1);
-        }
-    }
-
-    fn names_to_string(&self, names: &[Name]) -> String {
-        let mut first = true;
-        let mut result = String::new();
-        for name in names {
-            if first {
-                first = false
-            } else {
-                result.push_str("::")
-            }
-            result.push_str(&token::get_name(*name));
-        };
-        result
-    }
-
-    fn path_names_to_string(&self, path: &Path, depth: usize) -> String {
-        let names: Vec<ast::Name> = path.segments[..path.segments.len()-depth]
-                                        .iter()
-                                        .map(|seg| seg.identifier.name)
-                                        .collect();
-        self.names_to_string(&names[..])
-    }
-
-    fn import_directive_subclass_to_string(&mut self,
-                                        subclass: ImportDirectiveSubclass)
-                                        -> String {
-        match subclass {
-            SingleImport(_, source) => {
-                token::get_name(source).to_string()
-            }
-            GlobImport => "*".to_string()
-        }
-    }
-
-    fn import_path_to_string(&mut self,
-                          names: &[Name],
-                          subclass: ImportDirectiveSubclass)
-                          -> String {
-        if names.is_empty() {
-            self.import_directive_subclass_to_string(subclass)
-        } else {
-            (format!("{}::{}",
-                     self.names_to_string(names),
-                     self.import_directive_subclass_to_string(
-                         subclass))).to_string()
-        }
-    }
-
     #[inline]
     fn record_import_use(&mut self, import_id: NodeId, name: Name) {
         if !self.make_glob_map {
@@ -1191,102 +917,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
     }
 
-    /// Attempts to resolve the given import. The return value indicates
-    /// failure if we're certain the name does not exist, indeterminate if we
-    /// don't know whether the name exists at the moment due to other
-    /// currently-unresolved imports, or success if we know the name exists.
-    /// If successful, the resolved bindings are written into the module.
-    fn resolve_import_for_module(&mut self,
-                                 module_: Rc<Module>,
-                                 import_directive: &ImportDirective)
-                                 -> ResolveResult<()> {
-        let mut resolution_result = Failed(None);
-        let module_path = &import_directive.module_path;
-
-        debug!("(resolving import for module) resolving import `{}::...` in `{}`",
-               self.names_to_string(&module_path[..]),
-               self.module_to_string(&*module_));
-
-        // First, resolve the module path for the directive, if necessary.
-        let container = if module_path.len() == 0 {
-            // Use the crate root.
-            Some((self.graph_root.get_module(), LastMod(AllPublic)))
-        } else {
-            match self.resolve_module_path(module_.clone(),
-                                           &module_path[..],
-                                           DontUseLexicalScope,
-                                           import_directive.span,
-                                           ImportSearch) {
-                Failed(err) => {
-                    resolution_result = Failed(err);
-                    None
-                },
-                Indeterminate => {
-                    resolution_result = Indeterminate;
-                    None
-                }
-                Success(container) => Some(container),
-            }
-        };
-
-        match container {
-            None => {}
-            Some((containing_module, lp)) => {
-                // We found the module that the target is contained
-                // within. Attempt to resolve the import within it.
-
-                match import_directive.subclass {
-                    SingleImport(target, source) => {
-                        resolution_result =
-                            self.resolve_single_import(&*module_,
-                                                       containing_module,
-                                                       target,
-                                                       source,
-                                                       import_directive,
-                                                       lp);
-                    }
-                    GlobImport => {
-                        resolution_result =
-                            self.resolve_glob_import(&*module_,
-                                                     containing_module,
-                                                     import_directive,
-                                                     lp);
-                    }
-                }
-            }
-        }
-
-        // Decrement the count of unresolved imports.
-        match resolution_result {
-            Success(()) => {
-                assert!(self.unresolved_imports >= 1);
-                self.unresolved_imports -= 1;
-            }
-            _ => {
-                // Nothing to do here; just return the error.
-            }
-        }
-
-        // Decrement the count of unresolved globs if necessary. But only if
-        // the resolution result is indeterminate -- otherwise we'll stop
-        // processing imports here. (See the loop in
-        // resolve_imports_for_module.)
-
-        if !resolution_result.indeterminate() {
-            match import_directive.subclass {
-                GlobImport => {
-                    assert!(module_.glob_count.get() >= 1);
-                    module_.glob_count.set(module_.glob_count.get() - 1);
-                }
-                SingleImport(..) => {
-                    // Ignore.
-                }
-            }
-        }
-
-        return resolution_result;
-    }
-
     fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
         NameBindings {
             type_def: RefCell::new(Some(TypeNsDef {
@@ -1299,604 +929,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
     }
 
-    fn resolve_single_import(&mut self,
-                             module_: &Module,
-                             containing_module: Rc<Module>,
-                             target: Name,
-                             source: Name,
-                             directive: &ImportDirective,
-                             lp: LastPrivate)
-                                 -> ResolveResult<()> {
-        debug!("(resolving single import) resolving `{}` = `{}::{}` from \
-                `{}` id {}, last private {:?}",
-               token::get_name(target),
-               self.module_to_string(&*containing_module),
-               token::get_name(source),
-               self.module_to_string(module_),
-               directive.id,
-               lp);
-
-        let lp = match lp {
-            LastMod(lp) => lp,
-            LastImport {..} => {
-                self.session
-                    .span_bug(directive.span,
-                              "not expecting Import here, must be LastMod")
-            }
-        };
-
-        // We need to resolve both namespaces for this to succeed.
-        //
-
-        let mut value_result = UnknownResult;
-        let mut type_result = UnknownResult;
-
-        // Search for direct children of the containing module.
-        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
-
-        match containing_module.children.borrow().get(&source) {
-            None => {
-                // Continue.
-            }
-            Some(ref child_name_bindings) => {
-                if child_name_bindings.defined_in_namespace(ValueNS) {
-                    debug!("(resolving single import) found value binding");
-                    value_result = BoundResult(containing_module.clone(),
-                                               (*child_name_bindings).clone());
-                }
-                if child_name_bindings.defined_in_namespace(TypeNS) {
-                    debug!("(resolving single import) found type binding");
-                    type_result = BoundResult(containing_module.clone(),
-                                              (*child_name_bindings).clone());
-                }
-            }
-        }
-
-        // Unless we managed to find a result in both namespaces (unlikely),
-        // search imports as well.
-        let mut value_used_reexport = false;
-        let mut type_used_reexport = false;
-        match (value_result.clone(), type_result.clone()) {
-            (BoundResult(..), BoundResult(..)) => {} // Continue.
-            _ => {
-                // If there is an unresolved glob at this point in the
-                // containing module, bail out. We don't know enough to be
-                // able to resolve this import.
-
-                if containing_module.glob_count.get() > 0 {
-                    debug!("(resolving single import) unresolved glob; \
-                            bailing out");
-                    return Indeterminate;
-                }
-
-                // Now search the exported imports within the containing module.
-                match containing_module.import_resolutions.borrow().get(&source) {
-                    None => {
-                        debug!("(resolving single import) no import");
-                        // The containing module definitely doesn't have an
-                        // exported import with the name in question. We can
-                        // therefore accurately report that the names are
-                        // unbound.
-
-                        if value_result.is_unknown() {
-                            value_result = UnboundResult;
-                        }
-                        if type_result.is_unknown() {
-                            type_result = UnboundResult;
-                        }
-                    }
-                    Some(import_resolution)
-                            if import_resolution.outstanding_references == 0 => {
-
-                        fn get_binding(this: &mut Resolver,
-                                       import_resolution: &ImportResolution,
-                                       namespace: Namespace,
-                                       source: &Name)
-                                    -> NamespaceResult {
-
-                            // Import resolutions must be declared with "pub"
-                            // in order to be exported.
-                            if !import_resolution.is_public {
-                                return UnboundResult;
-                            }
-
-                            match import_resolution.
-                                    target_for_namespace(namespace) {
-                                None => {
-                                    return UnboundResult;
-                                }
-                                Some(Target {
-                                    target_module,
-                                    bindings,
-                                    shadowable: _
-                                }) => {
-                                    debug!("(resolving single import) found \
-                                            import in ns {:?}", namespace);
-                                    let id = import_resolution.id(namespace);
-                                    // track used imports and extern crates as well
-                                    this.used_imports.insert((id, namespace));
-                                    this.record_import_use(id, *source);
-                                    match target_module.def_id.get() {
-                                        Some(DefId{krate: kid, ..}) => {
-                                            this.used_crates.insert(kid);
-                                        },
-                                        _ => {}
-                                    }
-                                    return BoundResult(target_module, bindings);
-                                }
-                            }
-                        }
-
-                        // The name is an import which has been fully
-                        // resolved. We can, therefore, just follow it.
-                        if value_result.is_unknown() {
-                            value_result = get_binding(self,
-                                                       import_resolution,
-                                                       ValueNS,
-                                                       &source);
-                            value_used_reexport = import_resolution.is_public;
-                        }
-                        if type_result.is_unknown() {
-                            type_result = get_binding(self,
-                                                      import_resolution,
-                                                      TypeNS,
-                                                      &source);
-                            type_used_reexport = import_resolution.is_public;
-                        }
-
-                    }
-                    Some(_) => {
-                        // If containing_module is the same module whose import we are resolving
-                        // and there it has an unresolved import with the same name as `source`,
-                        // then the user is actually trying to import an item that is declared
-                        // in the same scope
-                        //
-                        // e.g
-                        // use self::submodule;
-                        // pub mod submodule;
-                        //
-                        // In this case we continue as if we resolved the import and let the
-                        // check_for_conflicts_between_imports_and_items call below handle
-                        // the conflict
-                        match (module_.def_id.get(),  containing_module.def_id.get()) {
-                            (Some(id1), Some(id2)) if id1 == id2  => {
-                                if value_result.is_unknown() {
-                                    value_result = UnboundResult;
-                                }
-                                if type_result.is_unknown() {
-                                    type_result = UnboundResult;
-                                }
-                            }
-                            _ =>  {
-                                // The import is unresolved. Bail out.
-                                debug!("(resolving single import) unresolved import; \
-                                        bailing out");
-                                return Indeterminate;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        // If we didn't find a result in the type namespace, search the
-        // external modules.
-        let mut value_used_public = false;
-        let mut type_used_public = false;
-        match type_result {
-            BoundResult(..) => {}
-            _ => {
-                match containing_module.external_module_children.borrow_mut()
-                                       .get(&source).cloned() {
-                    None => {} // Continue.
-                    Some(module) => {
-                        debug!("(resolving single import) found external \
-                                module");
-                        // track the module as used.
-                        match module.def_id.get() {
-                            Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
-                            _ => {}
-                        }
-                        let name_bindings =
-                            Rc::new(Resolver::create_name_bindings_from_module(
-                                module));
-                        type_result = BoundResult(containing_module.clone(),
-                                                  name_bindings);
-                        type_used_public = true;
-                    }
-                }
-            }
-        }
-
-        // We've successfully resolved the import. Write the results in.
-        let mut import_resolutions = module_.import_resolutions.borrow_mut();
-        let import_resolution = &mut (*import_resolutions)[target];
-        {
-            let mut check_and_write_import = |namespace, result: &_, used_public: &mut bool| {
-                let namespace_name = match namespace {
-                    TypeNS => "type",
-                    ValueNS => "value",
-                };
-
-                match *result {
-                    BoundResult(ref target_module, ref name_bindings) => {
-                        debug!("(resolving single import) found {:?} target: {:?}",
-                               namespace_name,
-                               name_bindings.def_for_namespace(namespace));
-                        self.check_for_conflicting_import(
-                            &import_resolution.target_for_namespace(namespace),
-                            directive.span,
-                            target,
-                            namespace);
-
-                        self.check_that_import_is_importable(
-                            &**name_bindings,
-                            directive.span,
-                            target,
-                            namespace);
-
-                        let target = Some(Target::new(target_module.clone(),
-                                                      name_bindings.clone(),
-                                                      directive.shadowable));
-                        import_resolution.set_target_and_id(namespace, target, directive.id);
-                        import_resolution.is_public = directive.is_public;
-                        *used_public = name_bindings.defined_in_public_namespace(namespace);
-                    }
-                    UnboundResult => { /* Continue. */ }
-                    UnknownResult => {
-                        panic!("{:?} result should be known at this point", namespace_name);
-                    }
-                }
-            };
-            check_and_write_import(ValueNS, &value_result, &mut value_used_public);
-            check_and_write_import(TypeNS, &type_result, &mut type_used_public);
-        }
-
-        self.check_for_conflicts_between_imports_and_items(
-            module_,
-            import_resolution,
-            directive.span,
-            target);
-
-        if value_result.is_unbound() && type_result.is_unbound() {
-            let msg = format!("There is no `{}` in `{}`",
-                              token::get_name(source),
-                              self.module_to_string(&*containing_module));
-            return Failed(Some((directive.span, msg)));
-        }
-        let value_used_public = value_used_reexport || value_used_public;
-        let type_used_public = type_used_reexport || type_used_public;
-
-        assert!(import_resolution.outstanding_references >= 1);
-        import_resolution.outstanding_references -= 1;
-
-        // record what this import resolves to for later uses in documentation,
-        // this may resolve to either a value or a type, but for documentation
-        // purposes it's good enough to just favor one over the other.
-        let value_def_and_priv = import_resolution.value_target.as_ref().map(|target| {
-            let def = target.bindings.def_for_namespace(ValueNS).unwrap();
-            (def, if value_used_public { lp } else { DependsOn(def.def_id()) })
-        });
-        let type_def_and_priv = import_resolution.type_target.as_ref().map(|target| {
-            let def = target.bindings.def_for_namespace(TypeNS).unwrap();
-            (def, if type_used_public { lp } else { DependsOn(def.def_id()) })
-        });
-
-        let import_lp = LastImport {
-            value_priv: value_def_and_priv.map(|(_, p)| p),
-            value_used: Used,
-            type_priv: type_def_and_priv.map(|(_, p)| p),
-            type_used: Used
-        };
-
-        if let Some((def, _)) = value_def_and_priv {
-            self.def_map.borrow_mut().insert(directive.id, PathResolution {
-                base_def: def,
-                last_private: import_lp,
-                depth: 0
-            });
-        }
-        if let Some((def, _)) = type_def_and_priv {
-            self.def_map.borrow_mut().insert(directive.id, PathResolution {
-                base_def: def,
-                last_private: import_lp,
-                depth: 0
-            });
-        }
-
-        debug!("(resolving single import) successfully resolved import");
-        return Success(());
-    }
-
-    // Resolves a glob import. Note that this function cannot fail; it either
-    // succeeds or bails out (as importing * from an empty module or a module
-    // that exports nothing is valid). containing_module is the module we are
-    // actually importing, i.e., `foo` in `use foo::*`.
-    fn resolve_glob_import(&mut self,
-                           module_: &Module,
-                           containing_module: Rc<Module>,
-                           import_directive: &ImportDirective,
-                           lp: LastPrivate)
-                           -> ResolveResult<()> {
-        let id = import_directive.id;
-        let is_public = import_directive.is_public;
-
-        // This function works in a highly imperative manner; it eagerly adds
-        // everything it can to the list of import resolutions of the module
-        // node.
-        debug!("(resolving glob import) resolving glob import {}", id);
-
-        // We must bail out if the node has unresolved imports of any kind
-        // (including globs).
-        if !(*containing_module).all_imports_resolved() {
-            debug!("(resolving glob import) target module has unresolved \
-                    imports; bailing out");
-            return Indeterminate;
-        }
-
-        assert_eq!(containing_module.glob_count.get(), 0);
-
-        // Add all resolved imports from the containing module.
-        let import_resolutions = containing_module.import_resolutions.borrow();
-        for (ident, target_import_resolution) in &*import_resolutions {
-            debug!("(resolving glob import) writing module resolution \
-                    {} into `{}`",
-                   token::get_name(*ident),
-                   self.module_to_string(module_));
-
-            if !target_import_resolution.is_public {
-                debug!("(resolving glob import) nevermind, just kidding");
-                continue
-            }
-
-            // Here we merge two import resolutions.
-            let mut import_resolutions = module_.import_resolutions.borrow_mut();
-            match import_resolutions.get_mut(ident) {
-                Some(dest_import_resolution) => {
-                    // Merge the two import resolutions at a finer-grained
-                    // level.
-
-                    match target_import_resolution.value_target {
-                        None => {
-                            // Continue.
-                        }
-                        Some(ref value_target) => {
-                            self.check_for_conflicting_import(&dest_import_resolution.value_target,
-                                                              import_directive.span,
-                                                              *ident,
-                                                              ValueNS);
-                            dest_import_resolution.value_target = Some(value_target.clone());
-                        }
-                    }
-                    match target_import_resolution.type_target {
-                        None => {
-                            // Continue.
-                        }
-                        Some(ref type_target) => {
-                            self.check_for_conflicting_import(&dest_import_resolution.type_target,
-                                                              import_directive.span,
-                                                              *ident,
-                                                              TypeNS);
-                            dest_import_resolution.type_target = Some(type_target.clone());
-                        }
-                    }
-                    dest_import_resolution.is_public = is_public;
-                    continue;
-                }
-                None => {}
-            }
-
-            // Simple: just copy the old import resolution.
-            let mut new_import_resolution = ImportResolution::new(id, is_public);
-            new_import_resolution.value_target =
-                target_import_resolution.value_target.clone();
-            new_import_resolution.type_target =
-                target_import_resolution.type_target.clone();
-
-            import_resolutions.insert(*ident, new_import_resolution);
-        }
-
-        // Add all children from the containing module.
-        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
-
-        for (&name, name_bindings) in &*containing_module.children.borrow() {
-            self.merge_import_resolution(module_,
-                                         containing_module.clone(),
-                                         import_directive,
-                                         name,
-                                         name_bindings.clone());
-
-        }
-
-        // Add external module children from the containing module.
-        for (&name, module) in &*containing_module.external_module_children.borrow() {
-            let name_bindings =
-                Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
-            self.merge_import_resolution(module_,
-                                         containing_module.clone(),
-                                         import_directive,
-                                         name,
-                                         name_bindings);
-        }
-
-        // Record the destination of this import
-        if let Some(did) = containing_module.def_id.get() {
-            self.def_map.borrow_mut().insert(id, PathResolution {
-                base_def: DefMod(did),
-                last_private: lp,
-                depth: 0
-            });
-        }
-
-        debug!("(resolving glob import) successfully resolved import");
-        return Success(());
-    }
-
-    fn merge_import_resolution(&mut self,
-                               module_: &Module,
-                               containing_module: Rc<Module>,
-                               import_directive: &ImportDirective,
-                               name: Name,
-                               name_bindings: Rc<NameBindings>) {
-        let id = import_directive.id;
-        let is_public = import_directive.is_public;
-
-        let mut import_resolutions = module_.import_resolutions.borrow_mut();
-        let dest_import_resolution = import_resolutions.entry(name).get().unwrap_or_else(
-            |vacant_entry| {
-                // Create a new import resolution from this child.
-                vacant_entry.insert(ImportResolution::new(id, is_public))
-            });
-
-        debug!("(resolving glob import) writing resolution `{}` in `{}` \
-               to `{}`",
-               &token::get_name(name),
-               self.module_to_string(&*containing_module),
-               self.module_to_string(module_));
-
-        // Merge the child item into the import resolution.
-        {
-            let mut merge_child_item = |namespace| {
-                if name_bindings.defined_in_namespace_with(namespace, IMPORTABLE | PUBLIC) {
-                    let namespace_name = match namespace {
-                        TypeNS => "type",
-                        ValueNS => "value",
-                    };
-                    debug!("(resolving glob import) ... for {} target", namespace_name);
-                    if dest_import_resolution.shadowable(namespace) == Shadowable::Never {
-                        let msg = format!("a {} named `{}` has already been imported \
-                                           in this module",
-                                          namespace_name,
-                                          &token::get_name(name));
-                        span_err!(self.session, import_directive.span, E0251, "{}", msg);
-                    } else {
-                        let target = Target::new(containing_module.clone(),
-                                                 name_bindings.clone(),
-                                                 import_directive.shadowable);
-                        dest_import_resolution.set_target_and_id(namespace,
-                                                                 Some(target),
-                                                                 id);
-                    }
-                }
-            };
-            merge_child_item(ValueNS);
-            merge_child_item(TypeNS);
-        }
-
-        dest_import_resolution.is_public = is_public;
-
-        self.check_for_conflicts_between_imports_and_items(
-            module_,
-            dest_import_resolution,
-            import_directive.span,
-            name);
-    }
-
-    /// Checks that imported names and items don't have the same name.
-    fn check_for_conflicting_import(&mut self,
-                                    target: &Option<Target>,
-                                    import_span: Span,
-                                    name: Name,
-                                    namespace: Namespace) {
-        debug!("check_for_conflicting_import: {}; target exists: {}",
-               &token::get_name(name),
-               target.is_some());
-
-        match *target {
-            Some(ref target) if target.shadowable != Shadowable::Always => {
-                let msg = format!("a {} named `{}` has already been imported \
-                                   in this module",
-                                  match namespace {
-                                    TypeNS => "type",
-                                    ValueNS => "value",
-                                  },
-                                  &token::get_name(name));
-                span_err!(self.session, import_span, E0252, "{}", &msg[..]);
-            }
-            Some(_) | None => {}
-        }
-    }
-
-    /// Checks that an import is actually importable
-    fn check_that_import_is_importable(&mut self,
-                                       name_bindings: &NameBindings,
-                                       import_span: Span,
-                                       name: Name,
-                                       namespace: Namespace) {
-        if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
-            let msg = format!("`{}` is not directly importable",
-                              token::get_name(name));
-            span_err!(self.session, import_span, E0253, "{}", &msg[..]);
-        }
-    }
-
-    /// Checks that imported names and items don't have the same name.
-    fn check_for_conflicts_between_imports_and_items(&mut self,
-                                                     module: &Module,
-                                                     import_resolution:
-                                                     &ImportResolution,
-                                                     import_span: Span,
-                                                     name: Name) {
-        // First, check for conflicts between imports and `extern crate`s.
-        if module.external_module_children
-                 .borrow()
-                 .contains_key(&name) {
-            match import_resolution.type_target {
-                Some(ref target) if target.shadowable != Shadowable::Always => {
-                    let msg = format!("import `{0}` conflicts with imported \
-                                       crate in this module \
-                                       (maybe you meant `use {0}::*`?)",
-                                      &token::get_name(name));
-                    span_err!(self.session, import_span, E0254, "{}", &msg[..]);
-                }
-                Some(_) | None => {}
-            }
-        }
-
-        // Check for item conflicts.
-        let children = module.children.borrow();
-        let name_bindings = match children.get(&name) {
-            None => {
-                // There can't be any conflicts.
-                return
-            }
-            Some(ref name_bindings) => (*name_bindings).clone(),
-        };
-
-        match import_resolution.value_target {
-            Some(ref target) if target.shadowable != Shadowable::Always => {
-                if let Some(ref value) = *name_bindings.value_def.borrow() {
-                    span_err!(self.session, import_span, E0255,
-                              "import `{}` conflicts with value in this module",
-                              &token::get_name(name));
-                    if let Some(span) = value.value_span {
-                        self.session.span_note(span, "conflicting value here");
-                    }
-                }
-            }
-            Some(_) | None => {}
-        }
-
-        match import_resolution.type_target {
-            Some(ref target) if target.shadowable != Shadowable::Always => {
-                if let Some(ref ty) = *name_bindings.type_def.borrow() {
-                    let (what, note) = if ty.module_def.is_some() {
-                        ("existing submodule", "note conflicting module here")
-                    } else {
-                        ("type in this module", "note conflicting type here")
-                    };
-                    span_err!(self.session, import_span, E0256,
-                              "import `{}` conflicts with {}",
-                              &token::get_name(name), what);
-                    if let Some(span) = ty.type_span {
-                        self.session.span_note(span, note);
-                    }
-                }
-            }
-            Some(_) | None => {}
-        }
-    }
-
     /// Checks that the names of external crates don't collide with other
     /// external crates.
     fn check_for_conflicts_between_external_crates(&self,
@@ -1964,7 +996,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                               false) {
                 Failed(None) => {
                     let segment_name = token::get_name(name);
-                    let module_name = self.module_to_string(&*search_module);
+                    let module_name = module_to_string(&*search_module);
                     let mut span = span;
                     let msg = if "???" == &module_name[..] {
                         span.hi = span.lo + Pos::from_usize(segment_name.len());
@@ -1972,10 +1004,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         match search_parent_externals(name,
                                                      &self.current_module) {
                             Some(module) => {
-                                let path_str = self.names_to_string(module_path);
-                                let target_mod_str = self.module_to_string(&*module);
+                                let path_str = names_to_string(module_path);
+                                let target_mod_str = module_to_string(&*module);
                                 let current_mod_str =
-                                    self.module_to_string(&*self.current_module);
+                                    module_to_string(&*self.current_module);
 
                                 let prefix = if target_mod_str == current_mod_str {
                                     "self::".to_string()
@@ -2066,8 +1098,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         assert!(module_path_len > 0);
 
         debug!("(resolving module path for import) processing `{}` rooted at `{}`",
-               self.names_to_string(module_path),
-               self.module_to_string(&*module_));
+               names_to_string(module_path),
+               module_to_string(&*module_));
 
         // Resolve the module prefix, if any.
         let module_prefix_result = self.resolve_module_prefix(module_.clone(),
@@ -2078,7 +1110,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let last_private;
         match module_prefix_result {
             Failed(None) => {
-                let mpath = self.names_to_string(module_path);
+                let mpath = names_to_string(module_path);
                 let mpath = &mpath[..];
                 match mpath.rfind(':') {
                     Some(idx) => {
@@ -2161,7 +1193,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 namespace {:?} in `{}`",
                token::get_name(name),
                namespace,
-               self.module_to_string(&*module_));
+               module_to_string(&*module_));
 
         // The current module node is handled specially. First, check for
         // its immediate children.
@@ -2398,7 +1430,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 break
             }
             debug!("(resolving module prefix) resolving `super` at {}",
-                   self.module_to_string(&*containing_module));
+                   module_to_string(&*containing_module));
             match self.get_nearest_normal_module_parent(containing_module) {
                 None => return Failed(None),
                 Some(new_module) => {
@@ -2409,7 +1441,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
 
         debug!("(resolving module prefix) finished resolving prefix at {}",
-               self.module_to_string(&*containing_module));
+               module_to_string(&*containing_module));
 
         return Success(PrefixFound(containing_module, i));
     }
@@ -2429,7 +1461,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                               -> ResolveResult<(Target, bool)> {
         debug!("(resolving name in module) resolving `{}` in `{}`",
                &token::get_name(name),
-               self.module_to_string(&*module_));
+               module_to_string(&*module_));
 
         // First, check the direct children of the module.
         build_reduced_graph::populate_module_if_necessary(self, &module_);
@@ -2583,7 +1615,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     None => {
                         debug!("!!! (with scope) didn't find `{}` in `{}`",
                                token::get_name(name),
-                               self.module_to_string(&*orig_module));
+                               module_to_string(&*orig_module));
                     }
                     Some(name_bindings) => {
                         match (*name_bindings).get_module_if_available() {
@@ -2591,7 +1623,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 debug!("!!! (with scope) didn't find module \
                                         for `{}` in `{}`",
                                        token::get_name(name),
-                                       self.module_to_string(&*orig_module));
+                                       module_to_string(&*orig_module));
                             }
                             Some(module_) => {
                                 self.current_module = module_;
@@ -2970,7 +2002,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             } else {
                 self.resolve_error(trait_path.span,
                     &format!("`{}` is not a trait",
-                             self.path_names_to_string(trait_path, path_depth)));
+                             path_names_to_string(trait_path, path_depth)));
 
                 // If it's a typedef, give a note
                 if let DefTy(..) = path_res.base_def {
@@ -2981,7 +2013,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             }
         } else {
             let msg = format!("use of undeclared trait name `{}`",
-                              self.path_names_to_string(trait_path, path_depth));
+                              path_names_to_string(trait_path, path_depth));
             self.resolve_error(trait_path.span, &msg);
             Err(())
         }
@@ -3097,7 +2129,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         // If there is a TraitRef in scope for an impl, then the method must be in the trait.
         if let Some((did, ref trait_ref)) = self.current_trait_ref {
             if !self.trait_item_map.contains_key(&(name, did)) {
-                let path_str = self.path_names_to_string(&trait_ref.path, 0);
+                let path_str = path_names_to_string(&trait_ref.path, 0);
                 self.resolve_error(span,
                                     &format!("method `{}` is not a member of trait `{}`",
                                             token::get_name(name),
@@ -3279,7 +2311,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         // Write the result into the def map.
                         debug!("(resolving type) writing resolution for `{}` \
                                 (id {}) = {:?}",
-                               self.path_names_to_string(path, 0),
+                               path_names_to_string(path, 0),
                                ty.id, def);
                         self.record_def(ty.id, def);
                     }
@@ -3294,7 +2326,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         };
 
                         let msg = format!("use of undeclared {} `{}`", kind,
-                                          self.path_names_to_string(path, 0));
+                                          path_names_to_string(path, 0));
                         self.resolve_error(ty.span, &msg[..]);
                     }
                 }
@@ -3465,7 +2497,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             debug!("(resolving pattern) didn't find struct \
                                     def: {:?}", result);
                             let msg = format!("`{}` does not name a structure",
-                                              self.path_names_to_string(path, 0));
+                                              path_names_to_string(path, 0));
                             self.resolve_error(path.span, &msg[..]);
                         }
                     }
@@ -3718,7 +2750,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     Some((span, msg)) => (span, msg),
                     None => {
                         let msg = format!("Use of undeclared type or module `{}`",
-                                          self.names_to_string(&module_path));
+                                          names_to_string(&module_path));
                         (span, msg)
                     }
                 };
@@ -3778,7 +2810,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     Some((span, msg)) => (span, msg),
                     None => {
                         let msg = format!("Use of undeclared module `::{}`",
-                                          self.names_to_string(&module_path[..]));
+                                          names_to_string(&module_path[..]));
                         (span, msg)
                     }
                 };
@@ -3998,7 +3030,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             if let Some(binding) = module.children.borrow().get(&name) {
                 if let Some(DefMethod(did, _)) = binding.def_for_namespace(ValueNS) {
                     if is_static_method(self, did) {
-                        return StaticMethod(self.path_names_to_string(&path, 0))
+                        return StaticMethod(path_names_to_string(&path, 0))
                     }
                     if self.current_trait_ref.is_some() {
                         return TraitItem;
@@ -4013,7 +3045,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         if let Some((trait_did, ref trait_ref)) = self.current_trait_ref {
             if let Some(&did) = self.trait_item_map.get(&(name, trait_did)) {
                 if is_static_method(self, did) {
-                    return TraitMethod(self.path_names_to_string(&trait_ref.path, 0));
+                    return TraitMethod(path_names_to_string(&trait_ref.path, 0));
                 } else {
                     return TraitItem;
                 }
@@ -4105,7 +3137,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 if let Some(path_res) = resolution {
                     // Check if struct variant
                     if let DefVariant(_, _, true) = path_res.base_def {
-                        let path_name = self.path_names_to_string(path, 0);
+                        let path_name = path_names_to_string(path, 0);
                         self.resolve_error(expr.span,
                                 &format!("`{}` is a struct variant name, but \
                                           this expression \
@@ -4123,7 +3155,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     } else {
                         // Write the result into the def map.
                         debug!("(resolving expr) resolved `{}`",
-                               self.path_names_to_string(path, 0));
+                               path_names_to_string(path, 0));
 
                         // Partial resolutions will need the set of traits in scope,
                         // so they can be completed during typeck.
@@ -4140,7 +3172,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     // (The pattern matching def_tys where the id is in self.structs
                     // matches on regular structs while excluding tuple- and enum-like
                     // structs, which wouldn't result in this error.)
-                    let path_name = self.path_names_to_string(path, 0);
+                    let path_name = path_names_to_string(path, 0);
                     let type_res = self.with_no_errors(|this| {
                         this.resolve_path(expr.id, path, 0, TypeNS, false)
                     });
@@ -4227,7 +3259,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     None => {
                         debug!("(resolving expression) didn't find struct def",);
                         let msg = format!("`{}` does not name a structure",
-                                          self.path_names_to_string(path, 0));
+                                          path_names_to_string(path, 0));
                         self.resolve_error(path.span, &msg[..]);
                     }
                 }
@@ -4417,36 +3449,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     // hit.
     //
 
-    /// A somewhat inefficient routine to obtain the name of a module.
-    fn module_to_string(&self, module: &Module) -> String {
-        let mut names = Vec::new();
-
-        fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
-            match module.parent_link {
-                NoParentLink => {}
-                ModuleParentLink(ref module, name) => {
-                    names.push(name);
-                    collect_mod(names, &*module.upgrade().unwrap());
-                }
-                BlockParentLink(ref module, _) => {
-                    // danger, shouldn't be ident?
-                    names.push(special_idents::opaque.name);
-                    collect_mod(names, &*module.upgrade().unwrap());
-                }
-            }
-        }
-        collect_mod(&mut names, module);
-
-        if names.len() == 0 {
-            return "???".to_string();
-        }
-        self.names_to_string(&names.into_iter().rev()
-                                  .collect::<Vec<ast::Name>>())
-    }
-
     #[allow(dead_code)]   // useful for debugging
     fn dump_module(&mut self, module_: Rc<Module>) {
-        debug!("Dump of module `{}`:", self.module_to_string(&*module_));
+        debug!("Dump of module `{}`:", module_to_string(&*module_));
 
         debug!("Children:");
         build_reduced_graph::populate_module_if_necessary(self, &module_);
@@ -4480,6 +3485,56 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     }
 }
 
+
+fn names_to_string(names: &[Name]) -> String {
+    let mut first = true;
+    let mut result = String::new();
+    for name in names {
+        if first {
+            first = false
+        } else {
+            result.push_str("::")
+        }
+        result.push_str(&token::get_name(*name));
+    };
+    result
+}
+
+fn path_names_to_string(path: &Path, depth: usize) -> String {
+    let names: Vec<ast::Name> = path.segments[..path.segments.len()-depth]
+                                    .iter()
+                                    .map(|seg| seg.identifier.name)
+                                    .collect();
+    names_to_string(&names[..])
+}
+
+/// A somewhat inefficient routine to obtain the name of a module.
+fn module_to_string(module: &Module) -> String {
+    let mut names = Vec::new();
+
+    fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
+        match module.parent_link {
+            NoParentLink => {}
+            ModuleParentLink(ref module, name) => {
+                names.push(name);
+                collect_mod(names, &*module.upgrade().unwrap());
+            }
+            BlockParentLink(ref module, _) => {
+                // danger, shouldn't be ident?
+                names.push(special_idents::opaque.name);
+                collect_mod(names, &*module.upgrade().unwrap());
+            }
+        }
+    }
+    collect_mod(&mut names, module);
+
+    if names.len() == 0 {
+        return "???".to_string();
+    }
+    names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
+}
+
+
 pub struct CrateMap {
     pub def_map: DefMap,
     pub freevars: RefCell<FreevarMap>,
@@ -4507,7 +3562,7 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
     build_reduced_graph::build_reduced_graph(&mut resolver, krate);
     session.abort_if_errors();
 
-    resolver.resolve_imports();
+    resolve_imports::resolve_imports(&mut resolver);
     session.abort_if_errors();
 
     record_exports::record(&mut resolver);
diff --git a/src/librustc_resolve/record_exports.rs b/src/librustc_resolve/record_exports.rs
index 5d025f40d32..e953b6398f9 100644
--- a/src/librustc_resolve/record_exports.rs
+++ b/src/librustc_resolve/record_exports.rs
@@ -22,6 +22,7 @@ use {Module, NameBindings, Resolver};
 use Namespace::{self, TypeNS, ValueNS};
 
 use build_reduced_graph;
+use module_to_string;
 
 use rustc::middle::def::Export;
 use syntax::ast;
@@ -60,19 +61,19 @@ impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> {
                 // OK. Continue.
                 debug!("(recording exports for module subtree) recording \
                         exports for local module `{}`",
-                       self.module_to_string(&*module_));
+                       module_to_string(&*module_));
             }
             None => {
                 // Record exports for the root module.
                 debug!("(recording exports for module subtree) recording \
                         exports for root module `{}`",
-                       self.module_to_string(&*module_));
+                       module_to_string(&*module_));
             }
             Some(_) => {
                 // Bail out.
                 debug!("(recording exports for module subtree) not recording \
                         exports for `{}`",
-                       self.module_to_string(&*module_));
+                       module_to_string(&*module_));
                 return;
             }
         }
@@ -133,13 +134,13 @@ impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> {
     fn add_exports_for_module(&mut self,
                               exports: &mut Vec<Export>,
                               module_: &Module) {
-        for (name, importresolution) in &*module_.import_resolutions.borrow() {
-            if !importresolution.is_public {
+        for (name, import_resolution) in &*module_.import_resolutions.borrow() {
+            if !import_resolution.is_public {
                 continue
             }
             let xs = [TypeNS, ValueNS];
             for &ns in &xs {
-                match importresolution.target_for_namespace(ns) {
+                match import_resolution.target_for_namespace(ns) {
                     Some(target) => {
                         debug!("(computing exports) maybe export '{}'",
                                token::get_name(*name));
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
new file mode 100644
index 00000000000..737ec71cab3
--- /dev/null
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -0,0 +1,1021 @@
+// Copyright 2015 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.
+
+use self::ImportDirectiveSubclass::*;
+
+use {PUBLIC, IMPORTABLE};
+use Module;
+use Namespace::{self, TypeNS, ValueNS};
+use NameBindings;
+use NamespaceResult::{BoundResult, UnboundResult, UnknownResult};
+use NamespaceResult;
+use NameSearchType;
+use ResolveResult;
+use Resolver;
+use UseLexicalScopeFlag;
+use {names_to_string, module_to_string};
+
+use build_reduced_graph;
+
+use rustc::middle::def::*;
+use rustc::middle::privacy::*;
+
+use syntax::ast::{DefId, NodeId, Name};
+use syntax::attr::AttrMetaMethods;
+use syntax::parse::token;
+use syntax::codemap::Span;
+
+use std::mem::replace;
+use std::rc::Rc;
+
+
+/// Contains data for specific types of import directives.
+#[derive(Copy,Debug)]
+pub enum ImportDirectiveSubclass {
+    SingleImport(Name /* target */, Name /* source */),
+    GlobImport
+}
+
+/// Whether an import can be shadowed by another import.
+#[derive(Debug,PartialEq,Clone,Copy)]
+pub enum Shadowable {
+    Always,
+    Never
+}
+
+/// One import directive.
+#[derive(Debug)]
+pub struct ImportDirective {
+    pub module_path: Vec<Name>,
+    pub subclass: ImportDirectiveSubclass,
+    pub span: Span,
+    pub id: NodeId,
+    pub is_public: bool, // see note in ImportResolution about how to use this
+    pub shadowable: Shadowable,
+}
+
+impl ImportDirective {
+    pub fn new(module_path: Vec<Name> ,
+           subclass: ImportDirectiveSubclass,
+           span: Span,
+           id: NodeId,
+           is_public: bool,
+           shadowable: Shadowable)
+           -> ImportDirective {
+        ImportDirective {
+            module_path: module_path,
+            subclass: subclass,
+            span: span,
+            id: id,
+            is_public: is_public,
+            shadowable: shadowable,
+        }
+    }
+}
+
+/// The item that an import resolves to.
+#[derive(Clone,Debug)]
+pub struct Target {
+    pub target_module: Rc<Module>,
+    pub bindings: Rc<NameBindings>,
+    pub shadowable: Shadowable,
+}
+
+impl Target {
+    pub fn new(target_module: Rc<Module>,
+           bindings: Rc<NameBindings>,
+           shadowable: Shadowable)
+           -> Target {
+        Target {
+            target_module: target_module,
+            bindings: bindings,
+            shadowable: shadowable,
+        }
+    }
+}
+
+/// An ImportResolution represents a particular `use` directive.
+#[derive(Debug)]
+pub struct ImportResolution {
+    /// Whether this resolution came from a `use` or a `pub use`. Note that this
+    /// should *not* be used whenever resolution is being performed. Privacy
+    /// testing occurs during a later phase of compilation.
+    pub is_public: bool,
+
+    // The number of outstanding references to this name. When this reaches
+    // zero, outside modules can count on the targets being correct. Before
+    // then, all bets are off; future imports could override this name.
+    // Note that this is usually either 0 or 1 - shadowing is forbidden the only
+    // way outstanding_references is > 1 in a legal program is if the name is
+    // used in both namespaces.
+    pub outstanding_references: uint,
+
+    /// The value that this `use` directive names, if there is one.
+    pub value_target: Option<Target>,
+    /// The source node of the `use` directive leading to the value target
+    /// being non-none
+    pub value_id: NodeId,
+
+    /// The type that this `use` directive names, if there is one.
+    pub type_target: Option<Target>,
+    /// The source node of the `use` directive leading to the type target
+    /// being non-none
+    pub type_id: NodeId,
+}
+
+impl ImportResolution {
+    pub fn new(id: NodeId, is_public: bool) -> ImportResolution {
+        ImportResolution {
+            type_id: id,
+            value_id: id,
+            outstanding_references: 0,
+            value_target: None,
+            type_target: None,
+            is_public: is_public,
+        }
+    }
+
+    pub fn target_for_namespace(&self, namespace: Namespace)
+                                -> Option<Target> {
+        match namespace {
+            TypeNS  => self.type_target.clone(),
+            ValueNS => self.value_target.clone(),
+        }
+    }
+
+    pub fn id(&self, namespace: Namespace) -> NodeId {
+        match namespace {
+            TypeNS  => self.type_id,
+            ValueNS => self.value_id,
+        }
+    }
+
+    pub fn shadowable(&self, namespace: Namespace) -> Shadowable {
+        let target = self.target_for_namespace(namespace);
+        if target.is_none() {
+            return Shadowable::Always;
+        }
+
+        target.unwrap().shadowable
+    }
+
+    pub fn set_target_and_id(&mut self,
+                         namespace: Namespace,
+                         target: Option<Target>,
+                         id: NodeId) {
+        match namespace {
+            TypeNS  => {
+                self.type_target = target;
+                self.type_id = id;
+            }
+            ValueNS => {
+                self.value_target = target;
+                self.value_id = id;
+            }
+        }
+    }
+}
+
+
+struct ImportResolver<'a, 'b:'a, 'tcx:'b> {
+    resolver: &'a mut Resolver<'b, 'tcx>
+}
+
+impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
+    // Import resolution
+    //
+    // This is a fixed-point algorithm. We resolve imports until our efforts
+    // are stymied by an unresolved import; then we bail out of the current
+    // module and continue. We terminate successfully once no more imports
+    // remain or unsuccessfully when no forward progress in resolving imports
+    // is made.
+
+    /// Resolves all imports for the crate. This method performs the fixed-
+    /// point iteration.
+    fn resolve_imports(&mut self) {
+        let mut i = 0;
+        let mut prev_unresolved_imports = 0;
+        loop {
+            debug!("(resolving imports) iteration {}, {} imports left",
+                   i, self.resolver.unresolved_imports);
+
+            let module_root = self.resolver.graph_root.get_module();
+            self.resolve_imports_for_module_subtree(module_root.clone());
+
+            if self.resolver.unresolved_imports == 0 {
+                debug!("(resolving imports) success");
+                break;
+            }
+
+            if self.resolver.unresolved_imports == prev_unresolved_imports {
+                self.resolver.report_unresolved_imports(module_root);
+                break;
+            }
+
+            i += 1;
+            prev_unresolved_imports = self.resolver.unresolved_imports;
+        }
+    }
+
+    /// Attempts to resolve imports for the given module and all of its
+    /// submodules.
+    fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
+        debug!("(resolving imports for module subtree) resolving {}",
+               module_to_string(&*module_));
+        let orig_module = replace(&mut self.resolver.current_module, module_.clone());
+        self.resolve_imports_for_module(module_.clone());
+        self.resolver.current_module = orig_module;
+
+        build_reduced_graph::populate_module_if_necessary(self.resolver, &module_);
+        for (_, child_node) in &*module_.children.borrow() {
+            match child_node.get_module_if_available() {
+                None => {
+                    // Nothing to do.
+                }
+                Some(child_module) => {
+                    self.resolve_imports_for_module_subtree(child_module);
+                }
+            }
+        }
+
+        for (_, child_module) in &*module_.anonymous_children.borrow() {
+            self.resolve_imports_for_module_subtree(child_module.clone());
+        }
+    }
+
+    /// Attempts to resolve imports for the given module only.
+    fn resolve_imports_for_module(&mut self, module: Rc<Module>) {
+        if module.all_imports_resolved() {
+            debug!("(resolving imports for module) all imports resolved for \
+                   {}",
+                   module_to_string(&*module));
+            return;
+        }
+
+        let imports = module.imports.borrow();
+        let import_count = imports.len();
+        while module.resolved_import_count.get() < import_count {
+            let import_index = module.resolved_import_count.get();
+            let import_directive = &(*imports)[import_index];
+            match self.resolve_import_for_module(module.clone(),
+                                                 import_directive) {
+                ResolveResult::Failed(err) => {
+                    let (span, help) = match err {
+                        Some((span, msg)) => (span, format!(". {}", msg)),
+                        None => (import_directive.span, String::new())
+                    };
+                    let msg = format!("unresolved import `{}`{}",
+                                      import_path_to_string(
+                                          &import_directive.module_path,
+                                          import_directive.subclass),
+                                      help);
+                    self.resolver.resolve_error(span, &msg[..]);
+                }
+                ResolveResult::Indeterminate => break, // Bail out. We'll come around next time.
+                ResolveResult::Success(()) => () // Good. Continue.
+            }
+
+            module.resolved_import_count
+                  .set(module.resolved_import_count.get() + 1);
+        }
+    }
+
+    /// Attempts to resolve the given import. The return value indicates
+    /// failure if we're certain the name does not exist, indeterminate if we
+    /// don't know whether the name exists at the moment due to other
+    /// currently-unresolved imports, or success if we know the name exists.
+    /// If successful, the resolved bindings are written into the module.
+    fn resolve_import_for_module(&mut self,
+                                 module_: Rc<Module>,
+                                 import_directive: &ImportDirective)
+                                 -> ResolveResult<()> {
+        let mut resolution_result = ResolveResult::Failed(None);
+        let module_path = &import_directive.module_path;
+
+        debug!("(resolving import for module) resolving import `{}::...` in `{}`",
+               names_to_string(&module_path[..]),
+               module_to_string(&*module_));
+
+        // First, resolve the module path for the directive, if necessary.
+        let container = if module_path.len() == 0 {
+            // Use the crate root.
+            Some((self.resolver.graph_root.get_module(), LastMod(AllPublic)))
+        } else {
+            match self.resolver.resolve_module_path(module_.clone(),
+                                                    &module_path[..],
+                                                    UseLexicalScopeFlag::DontUseLexicalScope,
+                                                    import_directive.span,
+                                                    NameSearchType::ImportSearch) {
+                ResolveResult::Failed(err) => {
+                    resolution_result = ResolveResult::Failed(err);
+                    None
+                },
+                ResolveResult::Indeterminate => {
+                    resolution_result = ResolveResult::Indeterminate;
+                    None
+                }
+                ResolveResult::Success(container) => Some(container),
+            }
+        };
+
+        match container {
+            None => {}
+            Some((containing_module, lp)) => {
+                // We found the module that the target is contained
+                // within. Attempt to resolve the import within it.
+
+                match import_directive.subclass {
+                    SingleImport(target, source) => {
+                        resolution_result =
+                            self.resolve_single_import(&module_,
+                                                       containing_module,
+                                                       target,
+                                                       source,
+                                                       import_directive,
+                                                       lp);
+                    }
+                    GlobImport => {
+                        resolution_result =
+                            self.resolve_glob_import(&module_,
+                                                     containing_module,
+                                                     import_directive,
+                                                     lp);
+                    }
+                }
+            }
+        }
+
+        // Decrement the count of unresolved imports.
+        match resolution_result {
+            ResolveResult::Success(()) => {
+                assert!(self.resolver.unresolved_imports >= 1);
+                self.resolver.unresolved_imports -= 1;
+            }
+            _ => {
+                // Nothing to do here; just return the error.
+            }
+        }
+
+        // Decrement the count of unresolved globs if necessary. But only if
+        // the resolution result is indeterminate -- otherwise we'll stop
+        // processing imports here. (See the loop in
+        // resolve_imports_for_module).
+
+        if !resolution_result.indeterminate() {
+            match import_directive.subclass {
+                GlobImport => {
+                    assert!(module_.glob_count.get() >= 1);
+                    module_.glob_count.set(module_.glob_count.get() - 1);
+                }
+                SingleImport(..) => {
+                    // Ignore.
+                }
+            }
+        }
+
+        return resolution_result;
+    }
+
+    fn resolve_single_import(&mut self,
+                             module_: &Module,
+                             target_module: Rc<Module>,
+                             target: Name,
+                             source: Name,
+                             directive: &ImportDirective,
+                             lp: LastPrivate)
+                             -> ResolveResult<()> {
+        debug!("(resolving single import) resolving `{}` = `{}::{}` from \
+                `{}` id {}, last private {:?}",
+               token::get_name(target),
+               module_to_string(&*target_module),
+               token::get_name(source),
+               module_to_string(module_),
+               directive.id,
+               lp);
+
+        let lp = match lp {
+            LastMod(lp) => lp,
+            LastImport {..} => {
+                self.resolver.session
+                    .span_bug(directive.span,
+                              "not expecting Import here, must be LastMod")
+            }
+        };
+
+        // We need to resolve both namespaces for this to succeed.
+        //
+
+        let mut value_result = UnknownResult;
+        let mut type_result = UnknownResult;
+
+        // Search for direct children of the containing module.
+        build_reduced_graph::populate_module_if_necessary(self.resolver, &target_module);
+
+        match target_module.children.borrow().get(&source) {
+            None => {
+                // Continue.
+            }
+            Some(ref child_name_bindings) => {
+                // pub_err makes sure we don't give the same error twice.
+                let mut pub_err = false;
+                if child_name_bindings.defined_in_namespace(ValueNS) {
+                    debug!("(resolving single import) found value binding");
+                    value_result = BoundResult(target_module.clone(),
+                                               (*child_name_bindings).clone());
+                    if directive.is_public && !child_name_bindings.is_public(ValueNS) {
+                        let msg = format!("`{}` is private", token::get_name(source));
+                        span_err!(self.resolver.session, directive.span, E0364, "{}", &msg);
+                        pub_err = true;
+                    }
+                }
+                if child_name_bindings.defined_in_namespace(TypeNS) {
+                    debug!("(resolving single import) found type binding");
+                    type_result = BoundResult(target_module.clone(),
+                                              (*child_name_bindings).clone());
+                    if !pub_err && directive.is_public && !child_name_bindings.is_public(TypeNS) {
+                        let msg = format!("`{}` is private", token::get_name(source));
+                        span_err!(self.resolver.session, directive.span, E0365, "{}", &msg);
+                    }
+                }
+            }
+        }
+
+        // Unless we managed to find a result in both namespaces (unlikely),
+        // search imports as well.
+        let mut value_used_reexport = false;
+        let mut type_used_reexport = false;
+        match (value_result.clone(), type_result.clone()) {
+            (BoundResult(..), BoundResult(..)) => {} // Continue.
+            _ => {
+                // If there is an unresolved glob at this point in the
+                // containing module, bail out. We don't know enough to be
+                // able to resolve this import.
+
+                if target_module.glob_count.get() > 0 {
+                    debug!("(resolving single import) unresolved glob; \
+                            bailing out");
+                    return ResolveResult::Indeterminate;
+                }
+
+                // Now search the exported imports within the containing module.
+                match target_module.import_resolutions.borrow().get(&source) {
+                    None => {
+                        debug!("(resolving single import) no import");
+                        // The containing module definitely doesn't have an
+                        // exported import with the name in question. We can
+                        // therefore accurately report that the names are
+                        // unbound.
+
+                        if value_result.is_unknown() {
+                            value_result = UnboundResult;
+                        }
+                        if type_result.is_unknown() {
+                            type_result = UnboundResult;
+                        }
+                    }
+                    Some(import_resolution)
+                            if import_resolution.outstanding_references == 0 => {
+
+                        fn get_binding(this: &mut Resolver,
+                                       import_resolution: &ImportResolution,
+                                       namespace: Namespace,
+                                       source: &Name)
+                                    -> NamespaceResult {
+
+                            // Import resolutions must be declared with "pub"
+                            // in order to be exported.
+                            if !import_resolution.is_public {
+                                return UnboundResult;
+                            }
+
+                            match import_resolution.target_for_namespace(namespace) {
+                                None => {
+                                    return UnboundResult;
+                                }
+                                Some(Target {
+                                    target_module,
+                                    bindings,
+                                    shadowable: _
+                                }) => {
+                                    debug!("(resolving single import) found \
+                                            import in ns {:?}", namespace);
+                                    let id = import_resolution.id(namespace);
+                                    // track used imports and extern crates as well
+                                    this.used_imports.insert((id, namespace));
+                                    this.record_import_use(id, *source);
+                                    match target_module.def_id.get() {
+                                        Some(DefId{krate: kid, ..}) => {
+                                            this.used_crates.insert(kid);
+                                        },
+                                        _ => {}
+                                    }
+                                    return BoundResult(target_module, bindings);
+                                }
+                            }
+                        }
+
+                        // The name is an import which has been fully
+                        // resolved. We can, therefore, just follow it.
+                        if value_result.is_unknown() {
+                            value_result = get_binding(self.resolver,
+                                                       import_resolution,
+                                                       ValueNS,
+                                                       &source);
+                            value_used_reexport = import_resolution.is_public;
+                        }
+                        if type_result.is_unknown() {
+                            type_result = get_binding(self.resolver,
+                                                      import_resolution,
+                                                      TypeNS,
+                                                      &source);
+                            type_used_reexport = import_resolution.is_public;
+                        }
+
+                    }
+                    Some(_) => {
+                        // If target_module is the same module whose import we are resolving
+                        // and there it has an unresolved import with the same name as `source`,
+                        // then the user is actually trying to import an item that is declared
+                        // in the same scope
+                        //
+                        // e.g
+                        // use self::submodule;
+                        // pub mod submodule;
+                        //
+                        // In this case we continue as if we resolved the import and let the
+                        // check_for_conflicts_between_imports_and_items call below handle
+                        // the conflict
+                        match (module_.def_id.get(),  target_module.def_id.get()) {
+                            (Some(id1), Some(id2)) if id1 == id2  => {
+                                if value_result.is_unknown() {
+                                    value_result = UnboundResult;
+                                }
+                                if type_result.is_unknown() {
+                                    type_result = UnboundResult;
+                                }
+                            }
+                            _ =>  {
+                                // The import is unresolved. Bail out.
+                                debug!("(resolving single import) unresolved import; \
+                                        bailing out");
+                                return ResolveResult::Indeterminate;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        let mut value_used_public = false;
+        let mut type_used_public = false;
+
+        // If we didn't find a result in the type namespace, search the
+        // external modules.
+        match type_result {
+            BoundResult(..) => {}
+            _ => {
+                match target_module.external_module_children.borrow_mut().get(&source).cloned() {
+                    None => {} // Continue.
+                    Some(module) => {
+                        debug!("(resolving single import) found external module");
+                        // track the module as used.
+                        match module.def_id.get() {
+                            Some(DefId{krate: kid, ..}) => {
+                                self.resolver.used_crates.insert(kid);
+                            }
+                            _ => {}
+                        }
+                        let name_bindings =
+                            Rc::new(Resolver::create_name_bindings_from_module(module));
+                        type_result = BoundResult(target_module.clone(), name_bindings);
+                        type_used_public = true;
+                    }
+                }
+            }
+        }
+
+        // We've successfully resolved the import. Write the results in.
+        let mut import_resolutions = module_.import_resolutions.borrow_mut();
+        let import_resolution = &mut (*import_resolutions)[target];
+
+        {
+            let mut check_and_write_import = |namespace, result: &_, used_public: &mut bool| {
+                let namespace_name = match namespace {
+                    TypeNS => "type",
+                    ValueNS => "value",
+                };
+
+                match *result {
+                    BoundResult(ref target_module, ref name_bindings) => {
+                        debug!("(resolving single import) found {:?} target: {:?}",
+                               namespace_name,
+                               name_bindings.def_for_namespace(namespace));
+                        self.check_for_conflicting_import(
+                            &import_resolution.target_for_namespace(namespace),
+                            directive.span,
+                            target,
+                            namespace);
+
+                        self.check_that_import_is_importable(
+                            &**name_bindings,
+                            directive.span,
+                            target,
+                            namespace);
+
+                        let target = Some(Target::new(target_module.clone(),
+                                                      name_bindings.clone(),
+                                                      directive.shadowable));
+                        import_resolution.set_target_and_id(namespace, target, directive.id);
+                        import_resolution.is_public = directive.is_public;
+                        *used_public = name_bindings.defined_in_public_namespace(namespace);
+                    }
+                    UnboundResult => { /* Continue. */ }
+                    UnknownResult => {
+                        panic!("{:?} result should be known at this point", namespace_name);
+                    }
+                }
+            };
+            check_and_write_import(ValueNS, &value_result, &mut value_used_public);
+            check_and_write_import(TypeNS, &type_result, &mut type_used_public);
+        }
+
+        self.check_for_conflicts_between_imports_and_items(
+            module_,
+            import_resolution,
+            directive.span,
+            target);
+
+        if value_result.is_unbound() && type_result.is_unbound() {
+            let msg = format!("There is no `{}` in `{}`",
+                              token::get_name(source),
+                              module_to_string(&target_module));
+            return ResolveResult::Failed(Some((directive.span, msg)));
+        }
+        let value_used_public = value_used_reexport || value_used_public;
+        let type_used_public = type_used_reexport || type_used_public;
+
+        assert!(import_resolution.outstanding_references >= 1);
+        import_resolution.outstanding_references -= 1;
+
+        // Record what this import resolves to for later uses in documentation,
+        // this may resolve to either a value or a type, but for documentation
+        // purposes it's good enough to just favor one over the other.
+        let value_def_and_priv = import_resolution.value_target.as_ref().map(|target| {
+            let def = target.bindings.def_for_namespace(ValueNS).unwrap();
+            (def, if value_used_public { lp } else { DependsOn(def.def_id()) })
+        });
+        let type_def_and_priv = import_resolution.type_target.as_ref().map(|target| {
+            let def = target.bindings.def_for_namespace(TypeNS).unwrap();
+            (def, if type_used_public { lp } else { DependsOn(def.def_id()) })
+        });
+
+        let import_lp = LastImport {
+            value_priv: value_def_and_priv.map(|(_, p)| p),
+            value_used: Used,
+            type_priv: type_def_and_priv.map(|(_, p)| p),
+            type_used: Used
+        };
+
+        if let Some((def, _)) = value_def_and_priv {
+            self.resolver.def_map.borrow_mut().insert(directive.id, PathResolution {
+                base_def: def,
+                last_private: import_lp,
+                depth: 0
+            });
+        }
+        if let Some((def, _)) = type_def_and_priv {
+            self.resolver.def_map.borrow_mut().insert(directive.id, PathResolution {
+                base_def: def,
+                last_private: import_lp,
+                depth: 0
+            });
+        }
+
+        debug!("(resolving single import) successfully resolved import");
+        return ResolveResult::Success(());
+    }
+
+    // Resolves a glob import. Note that this function cannot fail; it either
+    // succeeds or bails out (as importing * from an empty module or a module
+    // that exports nothing is valid). target_module is the module we are
+    // actually importing, i.e., `foo` in `use foo::*`.
+    fn resolve_glob_import(&mut self,
+                           module_: &Module,
+                           target_module: Rc<Module>,
+                           import_directive: &ImportDirective,
+                           lp: LastPrivate)
+                           -> ResolveResult<()> {
+        let id = import_directive.id;
+        let is_public = import_directive.is_public;
+
+        // This function works in a highly imperative manner; it eagerly adds
+        // everything it can to the list of import resolutions of the module
+        // node.
+        debug!("(resolving glob import) resolving glob import {}", id);
+
+        // We must bail out if the node has unresolved imports of any kind
+        // (including globs).
+        if !(*target_module).all_imports_resolved() {
+            debug!("(resolving glob import) target module has unresolved \
+                    imports; bailing out");
+            return ResolveResult::Indeterminate;
+        }
+
+        assert_eq!(target_module.glob_count.get(), 0);
+
+        // Add all resolved imports from the containing module.
+        let import_resolutions = target_module.import_resolutions.borrow();
+        for (ident, target_import_resolution) in &*import_resolutions {
+            debug!("(resolving glob import) writing module resolution \
+                    {} into `{}`",
+                   token::get_name(*ident),
+                   module_to_string(module_));
+
+            if !target_import_resolution.is_public {
+                debug!("(resolving glob import) nevermind, just kidding");
+                continue
+            }
+
+            // Here we merge two import resolutions.
+            let mut import_resolutions = module_.import_resolutions.borrow_mut();
+            match import_resolutions.get_mut(ident) {
+                Some(dest_import_resolution) => {
+                    // Merge the two import resolutions at a finer-grained
+                    // level.
+
+                    match target_import_resolution.value_target {
+                        None => {
+                            // Continue.
+                        }
+                        Some(ref value_target) => {
+                            self.check_for_conflicting_import(&dest_import_resolution.value_target,
+                                                              import_directive.span,
+                                                              *ident,
+                                                              ValueNS);
+                            dest_import_resolution.value_target = Some(value_target.clone());
+                        }
+                    }
+                    match target_import_resolution.type_target {
+                        None => {
+                            // Continue.
+                        }
+                        Some(ref type_target) => {
+                            self.check_for_conflicting_import(&dest_import_resolution.type_target,
+                                                              import_directive.span,
+                                                              *ident,
+                                                              TypeNS);
+                            dest_import_resolution.type_target = Some(type_target.clone());
+                        }
+                    }
+                    dest_import_resolution.is_public = is_public;
+                    continue;
+                }
+                None => {}
+            }
+
+            // Simple: just copy the old import resolution.
+            let mut new_import_resolution = ImportResolution::new(id, is_public);
+            new_import_resolution.value_target =
+                target_import_resolution.value_target.clone();
+            new_import_resolution.type_target =
+                target_import_resolution.type_target.clone();
+
+            import_resolutions.insert(*ident, new_import_resolution);
+        }
+
+        // Add all children from the containing module.
+        build_reduced_graph::populate_module_if_necessary(self.resolver, &target_module);
+
+        for (&name, name_bindings) in &*target_module.children.borrow() {
+            self.merge_import_resolution(module_,
+                                         target_module.clone(),
+                                         import_directive,
+                                         name,
+                                         name_bindings.clone());
+
+        }
+
+        // Add external module children from the containing module.
+        for (&name, module) in &*target_module.external_module_children.borrow() {
+            let name_bindings =
+                Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
+            self.merge_import_resolution(module_,
+                                         target_module.clone(),
+                                         import_directive,
+                                         name,
+                                         name_bindings);
+        }
+
+        // Record the destination of this import
+        if let Some(did) = target_module.def_id.get() {
+            self.resolver.def_map.borrow_mut().insert(id, PathResolution {
+                base_def: DefMod(did),
+                last_private: lp,
+                depth: 0
+            });
+        }
+
+        debug!("(resolving glob import) successfully resolved import");
+        return ResolveResult::Success(());
+    }
+
+    fn merge_import_resolution(&mut self,
+                               module_: &Module,
+                               containing_module: Rc<Module>,
+                               import_directive: &ImportDirective,
+                               name: Name,
+                               name_bindings: Rc<NameBindings>) {
+        let id = import_directive.id;
+        let is_public = import_directive.is_public;
+
+        let mut import_resolutions = module_.import_resolutions.borrow_mut();
+        let dest_import_resolution = import_resolutions.entry(name).get().unwrap_or_else(
+            |vacant_entry| {
+                // Create a new import resolution from this child.
+                vacant_entry.insert(ImportResolution::new(id, is_public))
+            });
+
+        debug!("(resolving glob import) writing resolution `{}` in `{}` \
+               to `{}`",
+               &token::get_name(name),
+               module_to_string(&*containing_module),
+               module_to_string(module_));
+
+        // Merge the child item into the import resolution.
+        {
+            let mut merge_child_item = |namespace| {
+                if name_bindings.defined_in_namespace_with(namespace, IMPORTABLE | PUBLIC) {
+                    let namespace_name = match namespace {
+                        TypeNS => "type",
+                        ValueNS => "value",
+                    };
+                    debug!("(resolving glob import) ... for {} target", namespace_name);
+                    if dest_import_resolution.shadowable(namespace) == Shadowable::Never {
+                        let msg = format!("a {} named `{}` has already been imported \
+                                           in this module",
+                                          namespace_name,
+                                          &token::get_name(name));
+                        span_err!(self.resolver.session, import_directive.span, E0251, "{}", msg);
+                    } else {
+                        let target = Target::new(containing_module.clone(),
+                                                 name_bindings.clone(),
+                                                 import_directive.shadowable);
+                        dest_import_resolution.set_target_and_id(namespace,
+                                                                 Some(target),
+                                                                 id);
+                    }
+                }
+            };
+            merge_child_item(ValueNS);
+            merge_child_item(TypeNS);
+        }
+
+        dest_import_resolution.is_public = is_public;
+
+        self.check_for_conflicts_between_imports_and_items(
+            module_,
+            dest_import_resolution,
+            import_directive.span,
+            name);
+    }
+
+    /// Checks that imported names and items don't have the same name.
+    fn check_for_conflicting_import(&mut self,
+                                    target: &Option<Target>,
+                                    import_span: Span,
+                                    name: Name,
+                                    namespace: Namespace) {
+        debug!("check_for_conflicting_import: {}; target exists: {}",
+               &token::get_name(name),
+               target.is_some());
+
+        match *target {
+            Some(ref target) if target.shadowable != Shadowable::Always => {
+                let msg = format!("a {} named `{}` has already been imported \
+                                   in this module",
+                                  match namespace {
+                                    TypeNS => "type",
+                                    ValueNS => "value",
+                                  },
+                                  &token::get_name(name));
+                span_err!(self.resolver.session, import_span, E0252, "{}", &msg[..]);
+            }
+            Some(_) | None => {}
+        }
+    }
+
+    /// Checks that an import is actually importable
+    fn check_that_import_is_importable(&mut self,
+                                       name_bindings: &NameBindings,
+                                       import_span: Span,
+                                       name: Name,
+                                       namespace: Namespace) {
+        if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
+            let msg = format!("`{}` is not directly importable",
+                              token::get_name(name));
+            span_err!(self.resolver.session, import_span, E0253, "{}", &msg[..]);
+        }
+    }
+
+    /// Checks that imported names and items don't have the same name.
+    fn check_for_conflicts_between_imports_and_items(&mut self,
+                                                     module: &Module,
+                                                     import_resolution:
+                                                     &ImportResolution,
+                                                     import_span: Span,
+                                                     name: Name) {
+        // First, check for conflicts between imports and `extern crate`s.
+        if module.external_module_children
+                 .borrow()
+                 .contains_key(&name) {
+            match import_resolution.type_target {
+                Some(ref target) if target.shadowable != Shadowable::Always => {
+                    let msg = format!("import `{0}` conflicts with imported \
+                                       crate in this module \
+                                       (maybe you meant `use {0}::*`?)",
+                                      &token::get_name(name));
+                    span_err!(self.resolver.session, import_span, E0254, "{}", &msg[..]);
+                }
+                Some(_) | None => {}
+            }
+        }
+
+        // Check for item conflicts.
+        let children = module.children.borrow();
+        let name_bindings = match children.get(&name) {
+            None => {
+                // There can't be any conflicts.
+                return
+            }
+            Some(ref name_bindings) => (*name_bindings).clone(),
+        };
+
+        match import_resolution.value_target {
+            Some(ref target) if target.shadowable != Shadowable::Always => {
+                if let Some(ref value) = *name_bindings.value_def.borrow() {
+                    span_err!(self.resolver.session, import_span, E0255,
+                              "import `{}` conflicts with value in this module",
+                              &token::get_name(name));
+                    if let Some(span) = value.value_span {
+                        self.resolver.session.span_note(span, "conflicting value here");
+                    }
+                }
+            }
+            Some(_) | None => {}
+        }
+
+        match import_resolution.type_target {
+            Some(ref target) if target.shadowable != Shadowable::Always => {
+                if let Some(ref ty) = *name_bindings.type_def.borrow() {
+                    let (what, note) = if ty.module_def.is_some() {
+                        ("existing submodule", "note conflicting module here")
+                    } else {
+                        ("type in this module", "note conflicting type here")
+                    };
+                    span_err!(self.resolver.session, import_span, E0256,
+                              "import `{}` conflicts with {}",
+                              &token::get_name(name), what);
+                    if let Some(span) = ty.type_span {
+                        self.resolver.session.span_note(span, note);
+                    }
+                }
+            }
+            Some(_) | None => {}
+        }
+    }
+}
+
+fn import_path_to_string(names: &[Name],
+                         subclass: ImportDirectiveSubclass)
+                         -> String {
+    if names.is_empty() {
+        import_directive_subclass_to_string(subclass)
+    } else {
+        (format!("{}::{}",
+                 names_to_string(names),
+                 import_directive_subclass_to_string(subclass))).to_string()
+    }
+}
+
+fn import_directive_subclass_to_string(subclass: ImportDirectiveSubclass) -> String {
+    match subclass {
+        SingleImport(_, source) => {
+            token::get_name(source).to_string()
+        }
+        GlobImport => "*".to_string()
+    }
+}
+
+pub fn resolve_imports(resolver: &mut Resolver) {
+    let mut import_resolver = ImportResolver {
+        resolver: resolver,
+    };
+    import_resolver.resolve_imports();
+}
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index 3087a8ea45d..34a23f3efac 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -626,12 +626,7 @@ fn link_rlib<'a>(sess: &'a Session,
                                                  e))
                 }
 
-                let bc_data_deflated = match flate::deflate_bytes(&bc_data[..]) {
-                    Some(compressed) => compressed,
-                    None => sess.fatal(&format!("failed to compress bytecode \
-                                                 from {}",
-                                                 bc_filename.display()))
-                };
+                let bc_data_deflated = flate::deflate_bytes(&bc_data[..]);
 
                 let mut bc_file_deflated = match fs::File::create(&bc_deflated_filename) {
                     Ok(file) => file,
diff --git a/src/librustc_trans/back/lto.rs b/src/librustc_trans/back/lto.rs
index db9966e0548..a3ab863c4ec 100644
--- a/src/librustc_trans/back/lto.rs
+++ b/src/librustc_trans/back/lto.rs
@@ -21,7 +21,6 @@ use libc;
 use flate;
 
 use std::ffi::CString;
-use std::iter;
 use std::mem;
 use std::num::Int;
 
@@ -62,7 +61,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
         let file = path.file_name().unwrap().to_str().unwrap();
         let file = &file[3..file.len() - 5]; // chop off lib/.rlib
         debug!("reading {}", file);
-        for i in iter::count(0, 1) {
+        for i in 0.. {
             let bc_encoded = time(sess.time_passes(),
                                   &format!("check for {}.{}.bytecode.deflate", name, i),
                                   (),
@@ -96,8 +95,8 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
                             (link::RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET + data_size as uint)];
 
                         match flate::inflate_bytes(compressed_data) {
-                            Some(inflated) => inflated,
-                            None => {
+                            Ok(inflated) => inflated,
+                            Err(_) => {
                                 sess.fatal(&format!("failed to decompress bc of `{}`",
                                                    name))
                             }
@@ -112,8 +111,8 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
                 // the object must be in the old, pre-versioning format, so simply
                 // inflate everything and let LLVM decide if it can make sense of it
                     match flate::inflate_bytes(bc_encoded) {
-                        Some(bc) => bc,
-                        None => {
+                        Ok(bc) => bc,
+                        Err(_) => {
                             sess.fatal(&format!("failed to decompress bc of `{}`",
                                                name))
                         }
@@ -213,4 +212,3 @@ fn read_from_le_bytes<T: Int>(bytes: &[u8], position_in_bytes: uint) -> T {
 
     Int::from_le(data)
 }
-
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index ccf24f7e859..e9f58ec53df 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -2974,10 +2974,7 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec<u8> {
     let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item);
     let metadata = encoder::encode_metadata(encode_parms, krate);
     let mut compressed = encoder::metadata_encoding_version.to_vec();
-    compressed.push_all(&match flate::deflate_bytes(&metadata) {
-        Some(compressed) => compressed,
-        None => cx.sess().fatal("failed to compress metadata"),
-    });
+    compressed.push_all(&flate::deflate_bytes(&metadata));
     let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed[..]);
     let llconst = C_struct_in_context(cx.metadata_llcx(), &[llmeta], false);
     let name = format!("rust_metadata_{}_{}",
diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs
index a5c3923336a..2fd79c1ddb4 100644
--- a/src/librustc_trans/trans/tvec.rs
+++ b/src/librustc_trans/trans/tvec.rs
@@ -293,7 +293,7 @@ pub fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 }
                 SaveIn(lldest) => {
                     match ty::eval_repeat_count(bcx.tcx(), &**count_expr) {
-                        0 => bcx,
+                        0 => expr::trans_into(bcx, &**element, Ignore),
                         1 => expr::trans_into(bcx, &**element, SaveIn(lldest)),
                         count => {
                             let elem = unpack_datum!(bcx, expr::trans(bcx, &**element));
@@ -410,8 +410,12 @@ pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
     F: FnOnce(Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>,
 {
     let _icx = push_ctxt("tvec::iter_vec_loop");
-    let fcx = bcx.fcx;
 
+    if bcx.unreachable.get() {
+        return bcx;
+    }
+
+    let fcx = bcx.fcx;
     let loop_bcx = fcx.new_temp_block("expr_repeat");
     let next_bcx = fcx.new_temp_block("expr_repeat: next");
 
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 718804d317f..1f7cc3bb647 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -289,11 +289,87 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
             ty::ty_param(p) => {
                 self.assemble_inherent_candidates_from_param(self_ty, p);
             }
+            ty::ty_char => {
+                let lang_def_id = self.tcx().lang_items.char_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_str => {
+                let lang_def_id = self.tcx().lang_items.str_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_vec(_, None) => {
+                let lang_def_id = self.tcx().lang_items.slice_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_ptr(ty::mt { ty: _, mutbl: ast::MutImmutable }) => {
+                let lang_def_id = self.tcx().lang_items.const_ptr_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_ptr(ty::mt { ty: _, mutbl: ast::MutMutable }) => {
+                let lang_def_id = self.tcx().lang_items.mut_ptr_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_int(ast::TyI8) => {
+                let lang_def_id = self.tcx().lang_items.i8_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_int(ast::TyI16) => {
+                let lang_def_id = self.tcx().lang_items.i16_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_int(ast::TyI32) => {
+                let lang_def_id = self.tcx().lang_items.i32_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_int(ast::TyI64) => {
+                let lang_def_id = self.tcx().lang_items.i64_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_int(ast::TyIs(_)) => {
+                let lang_def_id = self.tcx().lang_items.isize_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_uint(ast::TyU8) => {
+                let lang_def_id = self.tcx().lang_items.u8_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_uint(ast::TyU16) => {
+                let lang_def_id = self.tcx().lang_items.u16_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_uint(ast::TyU32) => {
+                let lang_def_id = self.tcx().lang_items.u32_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_uint(ast::TyU64) => {
+                let lang_def_id = self.tcx().lang_items.u64_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_uint(ast::TyUs(_)) => {
+                let lang_def_id = self.tcx().lang_items.usize_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_float(ast::TyF32) => {
+                let lang_def_id = self.tcx().lang_items.f32_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
+            ty::ty_float(ast::TyF64) => {
+                let lang_def_id = self.tcx().lang_items.f64_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
             _ => {
             }
         }
     }
 
+    fn assemble_inherent_impl_for_primitive(&mut self, lang_def_id: Option<ast::DefId>) {
+        if let Some(impl_def_id) = lang_def_id {
+            ty::populate_implementations_for_primitive_if_necessary(self.tcx(), impl_def_id);
+
+            self.assemble_inherent_impl_probe(impl_def_id);
+        }
+    }
+
     fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: ast::DefId) {
         // Read the inherent implementation candidates for this type from the
         // metadata if necessary.
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index 5dfe80cfcb2..ab694d26b15 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -16,6 +16,7 @@ use middle::ty;
 use syntax::ast::{Item, ItemImpl};
 use syntax::ast;
 use syntax::ast_util;
+use syntax::codemap::Span;
 use syntax::visit;
 use util::ppaux::{Repr, UserString};
 
@@ -38,6 +39,23 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
         }
     }
 
+    fn check_primitive_impl(&self,
+                            impl_def_id: ast::DefId,
+                            lang_def_id: Option<ast::DefId>,
+                            lang: &str,
+                            ty: &str,
+                            span: Span) {
+        match lang_def_id {
+            Some(lang_def_id) if lang_def_id == impl_def_id => { /* OK */ },
+            _ => {
+                self.tcx.sess.span_err(
+                    span,
+                    &format!("only a single inherent implementation marked with `#[lang = \"{}\"]` \
+                              is allowed for the `{}` primitive", lang, ty));
+            }
+        }
+    }
+
     /// Checks exactly one impl for orphan rules and other such
     /// restrictions.  In this fn, it can happen that multiple errors
     /// apply to a specific impl, so just return after reporting one
@@ -62,6 +80,125 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
                     ty::ty_uniq(..) => {
                         self.check_def_id(item, self.tcx.lang_items.owned_box().unwrap());
                     }
+                    ty::ty_char => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.char_impl(),
+                                                  "char",
+                                                  "char",
+                                                  item.span);
+                    }
+                    ty::ty_str => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.str_impl(),
+                                                  "str",
+                                                  "str",
+                                                  item.span);
+                    }
+                    ty::ty_vec(_, None) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.slice_impl(),
+                                                  "slice",
+                                                  "[T]",
+                                                  item.span);
+                    }
+                    ty::ty_ptr(ty::mt { ty: _, mutbl: ast::MutImmutable }) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.const_ptr_impl(),
+                                                  "const_ptr",
+                                                  "*const T",
+                                                  item.span);
+                    }
+                    ty::ty_ptr(ty::mt { ty: _, mutbl: ast::MutMutable }) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.mut_ptr_impl(),
+                                                  "mut_ptr",
+                                                  "*mut T",
+                                                  item.span);
+                    }
+                    ty::ty_int(ast::TyI8) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.i8_impl(),
+                                                  "i8",
+                                                  "i8",
+                                                  item.span);
+                    }
+                    ty::ty_int(ast::TyI16) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.i16_impl(),
+                                                  "i16",
+                                                  "i16",
+                                                  item.span);
+                    }
+                    ty::ty_int(ast::TyI32) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.i32_impl(),
+                                                  "i32",
+                                                  "i32",
+                                                  item.span);
+                    }
+                    ty::ty_int(ast::TyI64) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.i64_impl(),
+                                                  "i64",
+                                                  "i64",
+                                                  item.span);
+                    }
+                    ty::ty_int(ast::TyIs(_)) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.isize_impl(),
+                                                  "isize",
+                                                  "isize",
+                                                  item.span);
+                    }
+                    ty::ty_uint(ast::TyU8) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.u8_impl(),
+                                                  "u8",
+                                                  "u8",
+                                                  item.span);
+                    }
+                    ty::ty_uint(ast::TyU16) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.u16_impl(),
+                                                  "u16",
+                                                  "u16",
+                                                  item.span);
+                    }
+                    ty::ty_uint(ast::TyU32) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.u32_impl(),
+                                                  "u32",
+                                                  "u32",
+                                                  item.span);
+                    }
+                    ty::ty_uint(ast::TyU64) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.u64_impl(),
+                                                  "u64",
+                                                  "u64",
+                                                  item.span);
+                    }
+                    ty::ty_uint(ast::TyUs(_)) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.usize_impl(),
+                                                  "usize",
+                                                  "usize",
+                                                  item.span);
+                    }
+                    ty::ty_float(ast::TyF32) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.f32_impl(),
+                                                  "f32",
+                                                  "f32",
+                                                  item.span);
+                    }
+                    ty::ty_float(ast::TyF64) => {
+                        self.check_primitive_impl(def_id,
+                                                  self.tcx.lang_items.f64_impl(),
+                                                  "f64",
+                                                  "f64",
+                                                  item.span);
+                    }
                     _ => {
                         span_err!(self.tcx.sess, item.span, E0118,
                                   "no base type found for inherent implementation; \
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index dba7b16ecee..f97470dbaed 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -34,6 +34,7 @@
 //! both occur before the crate is rendered.
 pub use self::ExternalLocation::*;
 
+use std::ascii::OwnedAsciiExt;
 use std::cell::RefCell;
 use std::cmp::Ordering;
 use std::collections::{HashMap, HashSet};
@@ -239,6 +240,51 @@ struct IndexItem {
     path: String,
     desc: String,
     parent: Option<ast::DefId>,
+    search_type: Option<IndexItemFunctionType>,
+}
+
+/// A type used for the search index.
+struct Type {
+    name: Option<String>,
+}
+
+impl fmt::Display for Type {
+    /// Formats type as {name: $name}.
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        // Wrapping struct fmt should never call us when self.name is None,
+        // but just to be safe we write `null` in that case.
+        match self.name {
+            Some(ref n) => write!(f, "{{\"name\":\"{}\"}}", n),
+            None => write!(f, "null")
+        }
+    }
+}
+
+/// Full type of functions/methods in the search index.
+struct IndexItemFunctionType {
+    inputs: Vec<Type>,
+    output: Option<Type>
+}
+
+impl fmt::Display for IndexItemFunctionType {
+    /// Formats a full fn type as a JSON {inputs: [Type], outputs: Type/null}.
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        // If we couldn't figure out a type, just write `null`.
+        if self.inputs.iter().any(|ref i| i.name.is_none()) ||
+           (self.output.is_some() && self.output.as_ref().unwrap().name.is_none()) {
+            return write!(f, "null")
+        }
+
+        let inputs: Vec<String> = self.inputs.iter().map(|ref t| format!("{}", t)).collect();
+        try!(write!(f, "{{\"inputs\":[{}],\"output\":", inputs.connect(",")));
+
+        match self.output {
+            Some(ref t) => try!(write!(f, "{}", t)),
+            None => try!(write!(f, "null"))
+        };
+
+        Ok(try!(write!(f, "}}")))
+    }
 }
 
 // TLS keys used to carry information around during rendering.
@@ -407,8 +453,9 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::Result<String> {
                         ty: shortty(item),
                         name: item.name.clone().unwrap(),
                         path: fqp[..fqp.len() - 1].connect("::"),
-                        desc: shorter(item.doc_value()).to_string(),
+                        desc: shorter(item.doc_value()),
                         parent: Some(did),
+                        search_type: None,
                     });
                 },
                 None => {}
@@ -458,7 +505,11 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::Result<String> {
                 let pathid = *nodeid_to_pathid.get(&nodeid).unwrap();
                 try!(write!(&mut w, ",{}", pathid));
             }
-            None => {}
+            None => try!(write!(&mut w, ",null"))
+        }
+        match item.search_type {
+            Some(ref t) => try!(write!(&mut w, ",{}", t)),
+            None => try!(write!(&mut w, ",null"))
         }
         try!(write!(&mut w, "]"));
     }
@@ -872,12 +923,21 @@ impl DocFolder for Cache {
 
             match parent {
                 (parent, Some(path)) if is_method || (!self.privmod && !hidden_field) => {
+                    // Needed to determine `self` type.
+                    let parent_basename = self.parent_stack.first().and_then(|parent| {
+                        match self.paths.get(parent) {
+                            Some(&(ref fqp, _)) => Some(fqp[fqp.len() - 1].clone()),
+                            _ => None
+                        }
+                    });
+
                     self.search_index.push(IndexItem {
                         ty: shortty(&item),
                         name: s.to_string(),
                         path: path.connect("::").to_string(),
-                        desc: shorter(item.doc_value()).to_string(),
+                        desc: shorter(item.doc_value()),
                         parent: parent,
+                        search_type: get_index_search_type(&item, parent_basename),
                     });
                 }
                 (Some(parent), None) if is_method || (!self.privmod && !hidden_field)=> {
@@ -1467,13 +1527,14 @@ fn full_path(cx: &Context, item: &clean::Item) -> String {
     return s
 }
 
-fn shorter<'a>(s: Option<&'a str>) -> &'a str {
+fn shorter<'a>(s: Option<&'a str>) -> String {
     match s {
-        Some(s) => match s.find("\n\n") {
-            Some(pos) => &s[..pos],
-            None => s,
-        },
-        None => ""
+        Some(s) => s.lines().take_while(|line|{
+            (*line).chars().any(|chr|{
+                !chr.is_whitespace()
+            })
+        }).collect::<Vec<_>>().connect("\n"),
+        None => "".to_string()
     }
 }
 
@@ -1603,7 +1664,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
                     </tr>
                 ",
                 *myitem.name.as_ref().unwrap(),
-                Markdown(shorter(myitem.doc_value())),
+                Markdown(&shorter(myitem.doc_value())[..]),
                 class = shortty(myitem),
                 href = item_path(myitem),
                 title = full_path(cx, myitem),
@@ -2307,6 +2368,52 @@ fn make_item_keywords(it: &clean::Item) -> String {
     format!("{}, {}", get_basic_keywords(), it.name.as_ref().unwrap())
 }
 
+fn get_index_search_type(item: &clean::Item,
+                         parent: Option<String>) -> Option<IndexItemFunctionType> {
+    let decl = match item.inner {
+        clean::FunctionItem(ref f) => &f.decl,
+        clean::MethodItem(ref m) => &m.decl,
+        clean::TyMethodItem(ref m) => &m.decl,
+        _ => return None
+    };
+
+    let mut inputs = Vec::new();
+
+    // Consider `self` an argument as well.
+    if let Some(name) = parent {
+        inputs.push(Type { name: Some(name.into_ascii_lowercase()) });
+    }
+
+    inputs.extend(&mut decl.inputs.values.iter().map(|arg| {
+        get_index_type(&arg.type_)
+    }));
+
+    let output = match decl.output {
+        clean::FunctionRetTy::Return(ref return_type) => Some(get_index_type(return_type)),
+        _ => None
+    };
+
+    Some(IndexItemFunctionType { inputs: inputs, output: output })
+}
+
+fn get_index_type(clean_type: &clean::Type) -> Type {
+    Type { name: get_index_type_name(clean_type).map(|s| s.into_ascii_lowercase()) }
+}
+
+fn get_index_type_name(clean_type: &clean::Type) -> Option<String> {
+    match *clean_type {
+        clean::ResolvedPath { ref path, .. } => {
+            let segments = &path.segments;
+            Some(segments[segments.len() - 1].name.clone())
+        },
+        clean::Generic(ref s) => Some(s.clone()),
+        clean::Primitive(ref p) => Some(format!("{:?}", p)),
+        clean::BorrowedRef { ref type_, .. } => get_index_type_name(type_),
+        // FIXME: add all from clean::Type.
+        _ => None
+    }
+}
+
 pub fn cache() -> Arc<Cache> {
     CACHE_KEY.with(|c| c.borrow().clone())
 }
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 9fa8cf7941e..ca6d9441957 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -209,6 +209,33 @@
                         break;
                     }
                 }
+            // searching by type
+            } else if (val.search("->") > -1) {
+                var trimmer = function (s) { return s.trim(); };
+                var parts = val.split("->").map(trimmer);
+                var input = parts[0];
+                // sort inputs so that order does not matter
+                var inputs = input.split(",").map(trimmer).sort();
+                var output = parts[1];
+
+                for (var i = 0; i < nSearchWords; ++i) {
+                    var type = searchIndex[i].type;
+                    if (!type) {
+                        continue;
+                    }
+
+                    // sort index inputs so that order does not matter
+                    var typeInputs = type.inputs.map(function (input) {
+                        return input.name;
+                    }).sort();
+
+                    // allow searching for void (no output) functions as well
+                    var typeOutput = type.output ? type.output.name : "";
+                    if (inputs.toString() === typeInputs.toString() &&
+                        output == typeOutput) {
+                        results.push({id: i, index: -1, dontValidate: true});
+                    }
+                }
             } else {
                 // gather matching search results up to a certain maximum
                 val = val.replace(/\_/g, "");
@@ -329,6 +356,11 @@
                     path = result.item.path.toLowerCase(),
                     parent = result.item.parent;
 
+                // this validation does not make sense when searching by types
+                if (result.dontValidate) {
+                    continue;
+                }
+
                 var valid = validateResult(name, path, split, parent);
                 if (!valid) {
                     result.id = -1;
@@ -573,7 +605,8 @@
                 //              (String) name,
                 //              (String) full path or empty string for previous path,
                 //              (String) description,
-                //              (optional Number) the parent path index to `paths`]
+                //              (Number | null) the parent path index to `paths`]
+                //              (Object | null) the type of the function (if any)
                 var items = rawSearchIndex[crate].items;
                 // an array of [(Number) item type,
                 //              (String) name]
@@ -598,7 +631,7 @@
                     var rawRow = items[i];
                     var row = {crate: crate, ty: rawRow[0], name: rawRow[1],
                                path: rawRow[2] || lastPath, desc: rawRow[3],
-                               parent: paths[rawRow[4]]};
+                               parent: paths[rawRow[4]], type: rawRow[5]};
                     searchIndex.push(row);
                     if (typeof row.name === "string") {
                         var word = row.name.toLowerCase();
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 152b6f5c80a..bd4177861dd 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -26,7 +26,7 @@
 #![feature(core)]
 #![feature(exit_status)]
 #![feature(int_uint)]
-#![feature(set_panic)]
+#![feature(set_stdio)]
 #![feature(libc)]
 #![feature(old_path)]
 #![feature(rustc_private)]
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index d0ef89e811b..366b90cfbfd 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -204,6 +204,7 @@ use std::io::prelude::*;
 use std::io;
 use std::mem::{swap};
 use std::num::FpCategory as Fp;
+#[cfg(stage0)]
 use std::num::{Float, Int};
 use std::ops::Index;
 use std::str::FromStr;
@@ -2622,7 +2623,6 @@ mod tests {
                 StackElement, Stack, Decoder, Encoder, EncoderError};
     use std::{i64, u64, f32, f64};
     use std::collections::BTreeMap;
-    use std::num::Float;
     use std::string;
 
     #[derive(RustcDecodable, Eq, PartialEq, Debug)]
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index 8b275d1bc4a..93215090d95 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -16,8 +16,8 @@
 
 use prelude::v1::*;
 
+use ops::Range;
 use mem;
-use iter::Range;
 
 /// Extension methods for ASCII-subset only operations on owned strings
 #[unstable(feature = "std_misc",
@@ -270,7 +270,7 @@ pub fn escape_default(c: u8) -> EscapeDefault {
         _ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4),
     };
 
-    return EscapeDefault { range: range(0, len), data: data };
+    return EscapeDefault { range: (0.. len), data: data };
 
     fn hexify(b: u8) -> u8 {
         match b {
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 18f86901b8f..6f8151c2b9f 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -23,6 +23,7 @@ use hash::{Hash, SipHasher};
 use iter::{self, Iterator, ExactSizeIterator, IntoIterator, IteratorExt, FromIterator, Extend, Map};
 use marker::Sized;
 use mem::{self, replace};
+#[cfg(stage0)]
 use num::{Int, UnsignedInt};
 use ops::{Deref, FnMut, Index, IndexMut};
 use option::Option::{self, Some, None};
@@ -217,6 +218,11 @@ fn test_resize_policy() {
 /// It is required that the keys implement the `Eq` and `Hash` traits, although
 /// this can frequently be achieved by using `#[derive(Eq, Hash)]`.
 ///
+/// It is a logic error for a key to be modified in such a way that the key's
+/// hash, as determined by the `Hash` trait, or its equality, as determined by
+/// the `Eq` trait, changes while it is in the map. This is normally only
+/// possible through `Cell`, `RefCell`, global state, I/O, or unsafe code.
+///
 /// Relevant papers/articles:
 ///
 /// 1. Pedro Celis. ["Robin Hood Hashing"](https://cs.uwaterloo.ca/research/tr/1986/CS-86-14.pdf)
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index 35115ad77fe..de3f080de82 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -38,6 +38,12 @@ use super::state::HashState;
 /// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
 /// requires that the elements implement the `Eq` and `Hash` traits.
 ///
+/// It is a logic error for an item to be modified in such a way that the
+/// item's hash, as determined by the `Hash` trait, or its equality, as
+/// determined by the `Eq` trait, changes while it is in the set. This is
+/// normally only possible through `Cell`, `RefCell`, global state, I/O, or
+/// unsafe code.
+///
 /// # Examples
 ///
 /// ```
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 69fd0a57d5f..cba46859f34 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -19,12 +19,16 @@ use iter::{Iterator, IteratorExt, ExactSizeIterator, count};
 use marker::{Copy, Send, Sync, Sized, self};
 use mem::{min_align_of, size_of};
 use mem;
+#[cfg(stage0)]
 use num::{Int, UnsignedInt};
 use num::wrapping::{OverflowingOps, WrappingOps};
 use ops::{Deref, DerefMut, Drop};
 use option::Option;
 use option::Option::{Some, None};
+#[cfg(stage0)]
 use ptr::{self, PtrExt, Unique};
+#[cfg(not(stage0))]
+use ptr::{self, Unique};
 use rt::heap::{allocate, deallocate, EMPTY};
 use collections::hash_state::HashState;
 
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index 90373441edc..d06b027adf6 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -272,7 +272,9 @@ mod dl {
     use ptr;
     use result::Result;
     use result::Result::{Ok, Err};
+    #[cfg(stage0)]
     use slice::SliceExt;
+    #[cfg(stage0)]
     use str::StrExt;
     use str;
     use string::String;
diff --git a/src/libstd/env.rs b/src/libstd/env.rs
index 11e8f24f523..4b6fbe01f76 100644
--- a/src/libstd/env.rs
+++ b/src/libstd/env.rs
@@ -452,7 +452,7 @@ pub fn get_exit_status() -> i32 {
     EXIT_STATUS.load(Ordering::SeqCst) as i32
 }
 
-/// An iterator over the arguments of a process, yielding an `String` value
+/// An iterator over the arguments of a process, yielding a `String` value
 /// for each argument.
 ///
 /// This structure is created through the `std::env::args` method.
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 677894ba6e4..48526f2bf2d 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -22,7 +22,11 @@ use old_io;
 use ops::Deref;
 use option::Option::{self, Some, None};
 use result::Result::{self, Ok, Err};
+#[cfg(stage0)]
 use slice::{self, SliceExt};
+#[cfg(not(stage0))]
+use slice;
+#[cfg(stage0)]
 use str::StrExt;
 use string::String;
 use vec::Vec;
diff --git a/src/libstd/fs/mod.rs b/src/libstd/fs/mod.rs
index 825a11c3464..ba89b3a0ea6 100644
--- a/src/libstd/fs/mod.rs
+++ b/src/libstd/fs/mod.rs
@@ -124,7 +124,7 @@ impl File {
     /// This function will return an error if `path` does not already exist.
     /// Other errors may also be returned according to `OpenOptions::open`.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn open<P: AsPath + ?Sized>(path: &P) -> io::Result<File> {
+    pub fn open<P: AsPath>(path: P) -> io::Result<File> {
         OpenOptions::new().read(true).open(path)
     }
 
@@ -135,7 +135,7 @@ impl File {
     ///
     /// See the `OpenOptions::open` function for more details.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn create<P: AsPath + ?Sized>(path: &P) -> io::Result<File> {
+    pub fn create<P: AsPath>(path: P) -> io::Result<File> {
         OpenOptions::new().write(true).create(true).truncate(true).open(path)
     }
 
@@ -297,7 +297,7 @@ impl OpenOptions {
     ///   permissions for
     /// * Filesystem-level errors (full disk, etc)
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn open<P: AsPath + ?Sized>(&self, path: &P) -> io::Result<File> {
+    pub fn open<P: AsPath>(&self, path: P) -> io::Result<File> {
         let path = path.as_path();
         let inner = try!(fs_imp::File::open(path, &self.0));
         Ok(File { path: path.to_path_buf(), inner: inner })
@@ -410,7 +410,7 @@ impl DirEntry {
 /// user lacks permissions to remove the file, or if some other filesystem-level
 /// error occurs.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn remove_file<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
+pub fn remove_file<P: AsPath>(path: P) -> io::Result<()> {
     fs_imp::unlink(path.as_path())
 }
 
@@ -438,7 +438,7 @@ pub fn remove_file<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
 /// permissions to perform a `metadata` call on the given `path` or if there
 /// is no entry in the filesystem at the provided path.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn metadata<P: AsPath + ?Sized>(path: &P) -> io::Result<Metadata> {
+pub fn metadata<P: AsPath>(path: P) -> io::Result<Metadata> {
     fs_imp::stat(path.as_path()).map(Metadata)
 }
 
@@ -459,8 +459,7 @@ pub fn metadata<P: AsPath + ?Sized>(path: &P) -> io::Result<Metadata> {
 /// reside on separate filesystems, or if some other intermittent I/O error
 /// occurs.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn rename<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
-                                                      -> io::Result<()> {
+pub fn rename<P: AsPath, Q: AsPath>(from: P, to: Q) -> io::Result<()> {
     fs_imp::rename(from.as_path(), to.as_path())
 }
 
@@ -490,9 +489,9 @@ pub fn rename<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
 /// * The current process does not have the permission rights to access
 ///   `from` or write `to`
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn copy<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
-                                                    -> io::Result<u64> {
+pub fn copy<P: AsPath, Q: AsPath>(from: P, to: Q) -> io::Result<u64> {
     let from = from.as_path();
+    let to = to.as_path();
     if !from.is_file() {
         return Err(Error::new(ErrorKind::MismatchedFileTypeForOperation,
                               "the source path is not an existing file",
@@ -513,8 +512,7 @@ pub fn copy<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
 /// The `dst` path will be a link pointing to the `src` path. Note that systems
 /// often require these two paths to both be located on the same filesystem.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn hard_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
-                                                         -> io::Result<()> {
+pub fn hard_link<P: AsPath, Q: AsPath>(src: P, dst: Q) -> io::Result<()> {
     fs_imp::link(src.as_path(), dst.as_path())
 }
 
@@ -522,8 +520,7 @@ pub fn hard_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
 ///
 /// The `dst` path will be a soft link pointing to the `src` path.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn soft_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
-                                                         -> io::Result<()> {
+pub fn soft_link<P: AsPath, Q: AsPath>(src: P, dst: Q) -> io::Result<()> {
     fs_imp::symlink(src.as_path(), dst.as_path())
 }
 
@@ -535,7 +532,7 @@ pub fn soft_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
 /// reading a file that does not exist or reading a file that is not a soft
 /// link.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn read_link<P: AsPath + ?Sized>(path: &P) -> io::Result<PathBuf> {
+pub fn read_link<P: AsPath>(path: P) -> io::Result<PathBuf> {
     fs_imp::readlink(path.as_path())
 }
 
@@ -554,7 +551,7 @@ pub fn read_link<P: AsPath + ?Sized>(path: &P) -> io::Result<PathBuf> {
 /// This function will return an error if the user lacks permissions to make a
 /// new directory at the provided `path`, or if the directory already exists.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn create_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
+pub fn create_dir<P: AsPath>(path: P) -> io::Result<()> {
     fs_imp::mkdir(path.as_path())
 }
 
@@ -568,7 +565,7 @@ pub fn create_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
 /// error conditions for when a directory is being created (after it is
 /// determined to not exist) are outlined by `fs::create_dir`.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn create_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
+pub fn create_dir_all<P: AsPath>(path: P) -> io::Result<()> {
     let path = path.as_path();
     if path.is_dir() { return Ok(()) }
     if let Some(p) = path.parent() { try!(create_dir_all(p)) }
@@ -590,7 +587,7 @@ pub fn create_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
 /// This function will return an error if the user lacks permissions to remove
 /// the directory at the provided `path`, or if the directory isn't empty.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn remove_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
+pub fn remove_dir<P: AsPath>(path: P) -> io::Result<()> {
     fs_imp::rmdir(path.as_path())
 }
 
@@ -604,7 +601,7 @@ pub fn remove_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
 ///
 /// See `file::remove_file` and `fs::remove_dir`
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn remove_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
+pub fn remove_dir_all<P: AsPath>(path: P) -> io::Result<()> {
     let path = path.as_path();
     for child in try!(read_dir(path)) {
         let child = try!(child).path();
@@ -657,7 +654,7 @@ pub fn remove_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
 /// the process lacks permissions to view the contents or if the `path` points
 /// at a non-directory file
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn read_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<ReadDir> {
+pub fn read_dir<P: AsPath>(path: P) -> io::Result<ReadDir> {
     fs_imp::readdir(path.as_path()).map(ReadDir)
 }
 
@@ -673,7 +670,7 @@ pub fn read_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<ReadDir> {
            reason = "the precise semantics and defaults for a recursive walk \
                      may change and this may end up accounting for files such \
                      as symlinks differently")]
-pub fn walk_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<WalkDir> {
+pub fn walk_dir<P: AsPath>(path: P) -> io::Result<WalkDir> {
     let start = try!(read_dir(path));
     Ok(WalkDir { cur: Some(start), stack: Vec::new() })
 }
@@ -759,8 +756,8 @@ impl PathExt for Path {
            reason = "the argument type of u64 is not quite appropriate for \
                      this function and may change if the standard library \
                      gains a type to represent a moment in time")]
-pub fn set_file_times<P: AsPath + ?Sized>(path: &P, accessed: u64,
-                                          modified: u64) -> io::Result<()> {
+pub fn set_file_times<P: AsPath>(path: P, accessed: u64,
+                                 modified: u64) -> io::Result<()> {
     fs_imp::utimes(path.as_path(), accessed, modified)
 }
 
@@ -788,8 +785,7 @@ pub fn set_file_times<P: AsPath + ?Sized>(path: &P, accessed: u64,
            reason = "a more granual ability to set specific permissions may \
                      be exposed on the Permissions structure itself and this \
                      method may not always exist")]
-pub fn set_permissions<P: AsPath + ?Sized>(path: &P, perm: Permissions)
-                                           -> io::Result<()> {
+pub fn set_permissions<P: AsPath>(path: P, perm: Permissions) -> io::Result<()> {
     fs_imp::set_perm(path.as_path(), perm.0)
 }
 
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 3fddaaad807..d1231f549bb 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -9,10 +9,6 @@
 // except according to those terms.
 
 //! Traits, helpers, and type definitions for core I/O functionality.
-//!
-//! > **NOTE**: This module is very much a work in progress and is under active
-//! > development. At this time it is still recommended to use the `old_io`
-//! > module while the details of this module shake out.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -24,12 +20,19 @@ use iter::Iterator;
 use marker::Sized;
 use ops::{Drop, FnOnce};
 use option::Option::{self, Some, None};
+#[cfg(stage0)]
 use ptr::PtrExt;
 use result::Result::{Ok, Err};
 use result;
+#[cfg(stage0)]
 use slice::{self, SliceExt};
+#[cfg(not(stage0))]
+use slice;
 use string::String;
+#[cfg(stage0)]
 use str::{self, StrExt};
+#[cfg(not(stage0))]
+use str;
 use vec::Vec;
 
 pub use self::buffered::{BufReader, BufWriter, BufStream, LineWriter};
@@ -37,10 +40,10 @@ pub use self::buffered::IntoInnerError;
 pub use self::cursor::Cursor;
 pub use self::error::{Result, Error, ErrorKind};
 pub use self::util::{copy, sink, Sink, empty, Empty, repeat, Repeat};
-pub use self::stdio::{stdin, stdout, stderr, Stdin, Stdout, Stderr};
+pub use self::stdio::{stdin, stdout, stderr, _print, Stdin, Stdout, Stderr};
 pub use self::stdio::{StdoutLock, StderrLock, StdinLock};
 #[doc(no_inline, hidden)]
-pub use self::stdio::set_panic;
+pub use self::stdio::{set_panic, set_print};
 
 #[macro_use] mod lazy;
 
@@ -360,7 +363,7 @@ pub trait Write {
     ///
     /// It is considered an error if not all bytes could be written due to
     /// I/O errors or EOF being reached.
-    #[unstable(feature = "io", reason = "waiting for RFC 950")]
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn flush(&mut self) -> Result<()>;
 
     /// Attempts to write an entire buffer into this write.
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 3b4e396953d..75d047d5c9c 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -11,6 +11,7 @@
 use prelude::v1::*;
 use io::prelude::*;
 
+use cell::RefCell;
 use cmp;
 use fmt;
 use io::lazy::Lazy;
@@ -18,23 +19,30 @@ use io::{self, BufReader, LineWriter};
 use sync::{Arc, Mutex, MutexGuard};
 use sys::stdio;
 
+/// Stdout used by print! and println! macroses
+thread_local! {
+    static LOCAL_STDOUT: RefCell<Option<Box<Write + Send>>> = {
+        RefCell::new(None)
+    }
+}
+
 /// A handle to a raw instance of the standard input stream of this process.
 ///
 /// This handle is not synchronized or buffered in any fashion. Constructed via
-/// the `std::io::stdin_raw` function.
-pub struct StdinRaw(stdio::Stdin);
+/// the `std::io::stdio::stdin_raw` function.
+struct StdinRaw(stdio::Stdin);
 
 /// A handle to a raw instance of the standard output stream of this process.
 ///
 /// This handle is not synchronized or buffered in any fashion. Constructed via
-/// the `std::io::stdout_raw` function.
-pub struct StdoutRaw(stdio::Stdout);
+/// the `std::io::stdio::stdout_raw` function.
+struct StdoutRaw(stdio::Stdout);
 
 /// A handle to a raw instance of the standard output stream of this process.
 ///
 /// This handle is not synchronized or buffered in any fashion. Constructed via
-/// the `std::io::stderr_raw` function.
-pub struct StderrRaw(stdio::Stderr);
+/// the `std::io::stdio::stderr_raw` function.
+struct StderrRaw(stdio::Stderr);
 
 /// Construct a new raw handle to the standard input of this process.
 ///
@@ -43,7 +51,7 @@ pub struct StderrRaw(stdio::Stderr);
 /// handles is **not** available to raw handles returned from this function.
 ///
 /// The returned handle has no external synchronization or buffering.
-pub fn stdin_raw() -> StdinRaw { StdinRaw(stdio::Stdin::new()) }
+fn stdin_raw() -> StdinRaw { StdinRaw(stdio::Stdin::new()) }
 
 /// Construct a new raw handle to the standard input stream of this process.
 ///
@@ -54,7 +62,7 @@ pub fn stdin_raw() -> StdinRaw { StdinRaw(stdio::Stdin::new()) }
 ///
 /// The returned handle has no external synchronization or buffering layered on
 /// top.
-pub fn stdout_raw() -> StdoutRaw { StdoutRaw(stdio::Stdout::new()) }
+fn stdout_raw() -> StdoutRaw { StdoutRaw(stdio::Stdout::new()) }
 
 /// Construct a new raw handle to the standard input stream of this process.
 ///
@@ -63,7 +71,7 @@ pub fn stdout_raw() -> StdoutRaw { StdoutRaw(stdio::Stdout::new()) }
 ///
 /// The returned handle has no external synchronization or buffering layered on
 /// top.
-pub fn stderr_raw() -> StderrRaw { StderrRaw(stdio::Stderr::new()) }
+fn stderr_raw() -> StderrRaw { StderrRaw(stdio::Stderr::new()) }
 
 impl Read for StdinRaw {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
@@ -109,9 +117,6 @@ pub struct StdinLock<'a> {
 /// The `Read` trait is implemented for the returned value but the `BufRead`
 /// trait is not due to the global nature of the standard input stream. The
 /// locked version, `StdinLock`, implements both `Read` and `BufRead`, however.
-///
-/// To avoid locking and buffering altogether, it is recommended to use the
-/// `stdin_raw` constructor.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn stdin() -> Stdin {
     static INSTANCE: Lazy<Mutex<BufReader<StdinRaw>>> = lazy_init!(stdin_init);
@@ -224,9 +229,6 @@ pub struct StdoutLock<'a> {
 /// provided via the `lock` method.
 ///
 /// The returned handle implements the `Write` trait.
-///
-/// To avoid locking and buffering altogether, it is recommended to use the
-/// `stdout_raw` constructor.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn stdout() -> Stdout {
     static INSTANCE: Lazy<Mutex<LineWriter<StdoutRaw>>> = lazy_init!(stdout_init);
@@ -297,9 +299,6 @@ pub struct StderrLock<'a> {
 /// this function. No handles are buffered, however.
 ///
 /// The returned handle implements the `Write` trait.
-///
-/// To avoid locking altogether, it is recommended to use the `stderr_raw`
-/// constructor.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn stderr() -> Stderr {
     static INSTANCE: Lazy<Mutex<StderrRaw>> = lazy_init!(stderr_init);
@@ -347,15 +346,15 @@ impl<'a> Write for StderrLock<'a> {
     fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
 }
 
-/// Resets the task-local stdout handle to the specified writer
+/// Resets the task-local stderr handle to the specified writer
 ///
-/// This will replace the current task's stdout handle, returning the old
-/// handle. All future calls to `print` and friends will emit their output to
+/// This will replace the current task's stderr handle, returning the old
+/// handle. All future calls to `panic!` and friends will emit their output to
 /// this specified handle.
 ///
 /// Note that this does not need to be called for all new tasks; the default
-/// output handle is to the process's stdout stream.
-#[unstable(feature = "set_panic",
+/// output handle is to the process's stderr stream.
+#[unstable(feature = "set_stdio",
            reason = "this function may disappear completely or be replaced \
                      with a more general mechanism")]
 #[doc(hidden)]
@@ -369,3 +368,37 @@ pub fn set_panic(sink: Box<Write + Send>) -> Option<Box<Write + Send>> {
         Some(s)
     })
 }
+
+/// Resets the task-local stdout handle to the specified writer
+///
+/// This will replace the current task's stdout handle, returning the old
+/// handle. All future calls to `print!` and friends will emit their output to
+/// this specified handle.
+///
+/// Note that this does not need to be called for all new tasks; the default
+/// output handle is to the process's stdout stream.
+#[unstable(feature = "set_stdio",
+           reason = "this function may disappear completely or be replaced \
+                     with a more general mechanism")]
+#[doc(hidden)]
+pub fn set_print(sink: Box<Write + Send>) -> Option<Box<Write + Send>> {
+    use mem;
+    LOCAL_STDOUT.with(move |slot| {
+        mem::replace(&mut *slot.borrow_mut(), Some(sink))
+    }).and_then(|mut s| {
+        let _ = s.flush();
+        Some(s)
+    })
+}
+
+#[unstable(feature = "print",
+           reason = "implementation detail which may disappear or be replaced at any time")]
+#[doc(hidden)]
+pub fn _print(args: fmt::Arguments) {
+    if let Err(e) = LOCAL_STDOUT.with(|s| match s.borrow_mut().as_mut() {
+        Some(w) => w.write_fmt(args),
+        None => stdout().write_fmt(args)
+    }) {
+        panic!("failed printing to stdout: {}", e);
+    }
+}
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 995544c49a4..e1ef3062794 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -60,19 +60,21 @@ macro_rules! panic {
     });
 }
 
+/// Macro for printing to the standard output.
+///
 /// Equivalent to the `println!` macro except that a newline is not printed at
 /// the end of the message.
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow_internal_unstable]
 macro_rules! print {
-    ($($arg:tt)*) => ($crate::old_io::stdio::print_args(format_args!($($arg)*)))
+    ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
 }
 
-/// Macro for printing to a task's stdout handle.
+/// Macro for printing to the standard output.
 ///
-/// Each task can override its stdout handle via `std::old_io::stdio::set_stdout`.
-/// The syntax of this macro is the same as that used for `format!`. For more
-/// information, see `std::fmt` and `std::old_io::stdio`.
+/// Use the `format!` syntax to write data to the standard output.
+/// See `std::fmt` for more information.
 ///
 /// # Examples
 ///
@@ -83,7 +85,8 @@ macro_rules! print {
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! println {
-    ($($arg:tt)*) => ($crate::old_io::stdio::println_args(format_args!($($arg)*)))
+    ($fmt:expr) => (print!(concat!($fmt, "\n")));
+    ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
 }
 
 /// Helper macro for unwrapping `Result` values while returning early with an
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs
index 101aae3eb24..702f81db8e2 100644
--- a/src/libstd/net/addr.rs
+++ b/src/libstd/net/addr.rs
@@ -15,150 +15,220 @@ use hash;
 use io;
 use libc::{self, socklen_t, sa_family_t};
 use mem;
-use net::{IpAddr, lookup_host, ntoh, hton};
+use net::{lookup_host, ntoh, hton, Ipv4Addr, Ipv6Addr};
 use option;
 use sys_common::{FromInner, AsInner, IntoInner};
 use vec;
 
-/// Representation of a socket address for networking applications
+/// Representation of a socket address for networking applications.
 ///
-/// A socket address consists of at least an (ip, port) pair and may also
-/// contain other information depending on the protocol.
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-pub struct SocketAddr {
-    repr: Repr,
+/// A socket address can either represent the IPv4 or IPv6 protocol and is
+/// paired with at least a port number as well. Each protocol may have more
+/// specific information about the address available to it as well.
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub enum SocketAddr {
+    /// An IPv4 socket address which is a (ip, port) combination.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    V4(SocketAddrV4),
+    /// An IPv6 socket address
+    #[stable(feature = "rust1", since = "1.0.0")]
+    V6(SocketAddrV6),
 }
 
+/// An IPv4 socket address which is a (ip, port) combination.
 #[derive(Copy)]
-enum Repr {
-    V4(libc::sockaddr_in),
-    V6(libc::sockaddr_in6),
-}
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct SocketAddrV4 { inner: libc::sockaddr_in }
+
+/// An IPv6 socket address
+#[derive(Copy)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct SocketAddrV6 { inner: libc::sockaddr_in6 }
 
 impl SocketAddr {
+    /// Gets the port number associated with this socket address
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn port(&self) -> u16 {
+        match *self {
+            SocketAddr::V4(ref a) => a.port(),
+            SocketAddr::V6(ref a) => a.port(),
+        }
+    }
+}
+
+impl SocketAddrV4 {
     /// Creates a new socket address from the (ip, port) pair.
-    pub fn new(ip: IpAddr, port: u16) -> SocketAddr {
-        let repr = match ip {
-            IpAddr::V4(ref ip) => {
-                Repr::V4(libc::sockaddr_in {
-                    sin_family: libc::AF_INET as sa_family_t,
-                    sin_port: hton(port),
-                    sin_addr: *ip.as_inner(),
-                    .. unsafe { mem::zeroed() }
-                })
-            }
-            IpAddr::V6(ref ip) => {
-                Repr::V6(libc::sockaddr_in6 {
-                    sin6_family: libc::AF_INET6 as sa_family_t,
-                    sin6_port: hton(port),
-                    sin6_addr: *ip.as_inner(),
-                    .. unsafe { mem::zeroed() }
-                })
-            }
-        };
-        SocketAddr { repr: repr }
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 {
+        SocketAddrV4 {
+            inner: libc::sockaddr_in {
+                sin_family: libc::AF_INET as sa_family_t,
+                sin_port: hton(port),
+                sin_addr: *ip.as_inner(),
+                .. unsafe { mem::zeroed() }
+            },
+        }
     }
 
     /// Gets the IP address associated with this socket address.
-    pub fn ip(&self) -> IpAddr {
-        match self.repr {
-            Repr::V4(ref sa) => IpAddr::V4(FromInner::from_inner(sa.sin_addr)),
-            Repr::V6(ref sa) => IpAddr::V6(FromInner::from_inner(sa.sin6_addr)),
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn ip(&self) -> &Ipv4Addr {
+        unsafe {
+            &*(&self.inner.sin_addr as *const libc::in_addr as *const Ipv4Addr)
         }
     }
 
     /// Gets the port number associated with this socket address
-    pub fn port(&self) -> u16 {
-        match self.repr {
-            Repr::V4(ref sa) => ntoh(sa.sin_port),
-            Repr::V6(ref sa) => ntoh(sa.sin6_port),
-        }
-    }
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn port(&self) -> u16 { ntoh(self.inner.sin_port) }
+}
 
-    fn set_port(&mut self, port: u16) {
-        match self.repr {
-            Repr::V4(ref mut sa) => sa.sin_port = hton(port),
-            Repr::V6(ref mut sa) => sa.sin6_port = hton(port),
+impl SocketAddrV6 {
+    /// Creates a new socket address from the ip/port/flowinfo/scope_id
+    /// components.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn new(ip: Ipv6Addr, port: u16, flowinfo: u32, scope_id: u32)
+               -> SocketAddrV6 {
+        SocketAddrV6 {
+            inner: libc::sockaddr_in6 {
+                sin6_family: libc::AF_INET6 as sa_family_t,
+                sin6_port: hton(port),
+                sin6_addr: *ip.as_inner(),
+                sin6_flowinfo: hton(flowinfo),
+                sin6_scope_id: hton(scope_id),
+                .. unsafe { mem::zeroed() }
+            },
         }
     }
-}
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for SocketAddr {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match self.repr {
-            Repr::V4(_) => write!(f, "{}:{}", self.ip(), self.port()),
-            Repr::V6(_) => write!(f, "[{}]:{}", self.ip(), self.port()),
+    /// Gets the IP address associated with this socket address.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn ip(&self) -> &Ipv6Addr {
+        unsafe {
+            &*(&self.inner.sin6_addr as *const libc::in6_addr as *const Ipv6Addr)
         }
     }
+
+    /// Gets the port number associated with this socket address
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn port(&self) -> u16 { ntoh(self.inner.sin6_port) }
+
+    /// Gets scope ID associated with this address, corresponding to the
+    /// `sin6_flowinfo` field in C.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn flowinfo(&self) -> u32 { ntoh(self.inner.sin6_flowinfo) }
+
+    /// Gets scope ID associated with this address, corresponding to the
+    /// `sin6_scope_id` field in C.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn scope_id(&self) -> u32 { ntoh(self.inner.sin6_scope_id) }
 }
 
-impl FromInner<libc::sockaddr_in> for SocketAddr {
-    fn from_inner(addr: libc::sockaddr_in) -> SocketAddr {
-        SocketAddr { repr: Repr::V4(addr) }
+impl FromInner<libc::sockaddr_in> for SocketAddrV4 {
+    fn from_inner(addr: libc::sockaddr_in) -> SocketAddrV4 {
+        SocketAddrV4 { inner: addr }
     }
 }
 
-impl FromInner<libc::sockaddr_in6> for SocketAddr {
-    fn from_inner(addr: libc::sockaddr_in6) -> SocketAddr {
-        SocketAddr { repr: Repr::V6(addr) }
+impl FromInner<libc::sockaddr_in6> for SocketAddrV6 {
+    fn from_inner(addr: libc::sockaddr_in6) -> SocketAddrV6 {
+        SocketAddrV6 { inner: addr }
     }
 }
 
 impl<'a> IntoInner<(*const libc::sockaddr, socklen_t)> for &'a SocketAddr {
     fn into_inner(self) -> (*const libc::sockaddr, socklen_t) {
-        match self.repr {
-            Repr::V4(ref a) => {
+        match *self {
+            SocketAddr::V4(ref a) => {
                 (a as *const _ as *const _, mem::size_of_val(a) as socklen_t)
             }
-            Repr::V6(ref a) => {
+            SocketAddr::V6(ref a) => {
                 (a as *const _ as *const _, mem::size_of_val(a) as socklen_t)
             }
         }
     }
 }
 
-impl fmt::Debug for SocketAddr {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for SocketAddr {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            SocketAddr::V4(ref a) => a.fmt(f),
+            SocketAddr::V6(ref a) => a.fmt(f),
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for SocketAddrV4 {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}:{}", self.ip(), self.port())
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Debug for SocketAddrV4 {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         fmt::Display::fmt(self, fmt)
     }
 }
 
-impl Clone for Repr {
-    fn clone(&self) -> Repr { *self }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for SocketAddrV6 {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "[{}]:{}", self.ip(), self.port())
+    }
 }
 
-impl PartialEq for Repr {
-    fn eq(&self, other: &Repr) -> bool {
-        match (*self, *other) {
-            (Repr::V4(ref a), Repr::V4(ref b)) => {
-                a.sin_port == b.sin_port &&
-                    a.sin_addr.s_addr == b.sin_addr.s_addr
-            }
-            (Repr::V6(ref a), Repr::V6(ref b)) => {
-                a.sin6_port == b.sin6_port &&
-                    a.sin6_addr.s6_addr == b.sin6_addr.s6_addr &&
-                    a.sin6_flowinfo == b.sin6_flowinfo &&
-                    a.sin6_scope_id == b.sin6_scope_id
-            }
-            _ => false,
-        }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Debug for SocketAddrV6 {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(self, fmt)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Clone for SocketAddrV4 {
+    fn clone(&self) -> SocketAddrV4 { *self }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Clone for SocketAddrV6 {
+    fn clone(&self) -> SocketAddrV6 { *self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl PartialEq for SocketAddrV4 {
+    fn eq(&self, other: &SocketAddrV4) -> bool {
+        self.inner.sin_port == other.inner.sin_port &&
+            self.inner.sin_addr.s_addr == other.inner.sin_addr.s_addr
     }
 }
-impl Eq for Repr {}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl PartialEq for SocketAddrV6 {
+    fn eq(&self, other: &SocketAddrV6) -> bool {
+        self.inner.sin6_port == other.inner.sin6_port &&
+            self.inner.sin6_addr.s6_addr == other.inner.sin6_addr.s6_addr &&
+            self.inner.sin6_flowinfo == other.inner.sin6_flowinfo &&
+            self.inner.sin6_scope_id == other.inner.sin6_scope_id
+    }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Eq for SocketAddrV4 {}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Eq for SocketAddrV6 {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl hash::Hash for Repr {
+impl hash::Hash for SocketAddrV4 {
     fn hash<H: hash::Hasher>(&self, s: &mut H) {
-        match *self {
-            Repr::V4(ref a) => {
-                (a.sin_family, a.sin_port, a.sin_addr.s_addr).hash(s)
-            }
-            Repr::V6(ref a) => {
-                (a.sin6_family, a.sin6_port, &a.sin6_addr.s6_addr,
-                 a.sin6_flowinfo, a.sin6_scope_id).hash(s)
-            }
-        }
+        (self.inner.sin_port, self.inner.sin_addr.s_addr).hash(s)
+    }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl hash::Hash for SocketAddrV6 {
+    fn hash<H: hash::Hasher>(&self, s: &mut H) {
+        (self.inner.sin6_port, &self.inner.sin6_addr.s6_addr,
+         self.inner.sin6_flowinfo, self.inner.sin6_scope_id).hash(s)
     }
 }
 
@@ -168,12 +238,13 @@ impl hash::Hash for Repr {
 /// This trait is used for generic address resolution when constructing network
 /// objects.  By default it is implemented for the following types:
 ///
-///  * `SocketAddr` - `to_socket_addrs` is identity function.
+///  * `SocketAddr`, `SocketAddrV4`, `SocketAddrV6` - `to_socket_addrs` is
+///    identity function.
 ///
-///  * `(IpAddr, u16)` - `to_socket_addrs` constructs `SocketAddr` trivially.
+///  * `(IpvNAddr, u16)` - `to_socket_addrs` constructs `SocketAddr` trivially.
 ///
 ///  * `(&str, u16)` - the string should be either a string representation of an
-///    IP address expected by `FromStr` implementation for `IpAddr` or a host
+///    IP address expected by `FromStr` implementation for `IpvNAddr` or a host
 ///    name.
 ///
 ///  * `&str` - the string should be either a string representation of a
@@ -192,18 +263,18 @@ impl hash::Hash for Repr {
 /// Some examples:
 ///
 /// ```no_run
-/// use std::net::{IpAddr, SocketAddr, TcpStream, UdpSocket, TcpListener};
+/// use std::net::{SocketAddrV4, TcpStream, UdpSocket, TcpListener, Ipv4Addr};
 ///
 /// fn main() {
-///     let ip = IpAddr::new_v4(127, 0, 0, 1);
+///     let ip = Ipv4Addr::new(127, 0, 0, 1);
 ///     let port = 12345;
 ///
 ///     // The following lines are equivalent modulo possible "localhost" name
 ///     // resolution differences
-///     let tcp_s = TcpStream::connect(&SocketAddr::new(ip, port));
-///     let tcp_s = TcpStream::connect(&(ip, port));
-///     let tcp_s = TcpStream::connect(&("127.0.0.1", port));
-///     let tcp_s = TcpStream::connect(&("localhost", port));
+///     let tcp_s = TcpStream::connect(SocketAddrV4::new(ip, port));
+///     let tcp_s = TcpStream::connect((ip, port));
+///     let tcp_s = TcpStream::connect(("127.0.0.1", port));
+///     let tcp_s = TcpStream::connect(("localhost", port));
 ///     let tcp_s = TcpStream::connect("127.0.0.1:12345");
 ///     let tcp_s = TcpStream::connect("localhost:12345");
 ///
@@ -211,13 +282,15 @@ impl hash::Hash for Repr {
 ///     // behave similarly
 ///     let tcp_l = TcpListener::bind("localhost:12345");
 ///
-///     let mut udp_s = UdpSocket::bind(&("127.0.0.1", port)).unwrap();
-///     udp_s.send_to(&[7], &(ip, 23451));
+///     let mut udp_s = UdpSocket::bind(("127.0.0.1", port)).unwrap();
+///     udp_s.send_to(&[7], (ip, 23451));
 /// }
 /// ```
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait ToSocketAddrs {
     /// Returned iterator over socket addresses which this type may correspond
     /// to.
+    #[stable(feature = "rust1", since = "1.0.0")]
     type Iter: Iterator<Item=SocketAddr>;
 
     /// Converts this object to an iterator of resolved `SocketAddr`s.
@@ -231,9 +304,11 @@ pub trait ToSocketAddrs {
     /// # Errors
     ///
     /// Any errors encountered during resolution will be returned as an `Err`.
+    #[stable(feature = "rust1", since = "1.0.0")]
     fn to_socket_addrs(&self) -> io::Result<Self::Iter>;
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl ToSocketAddrs for SocketAddr {
     type Iter = option::IntoIter<SocketAddr>;
     fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
@@ -241,31 +316,72 @@ impl ToSocketAddrs for SocketAddr {
     }
 }
 
-impl ToSocketAddrs for (IpAddr, u16) {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl ToSocketAddrs for SocketAddrV4 {
+    type Iter = option::IntoIter<SocketAddr>;
+    fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
+        SocketAddr::V4(*self).to_socket_addrs()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl ToSocketAddrs for SocketAddrV6 {
+    type Iter = option::IntoIter<SocketAddr>;
+    fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
+        SocketAddr::V6(*self).to_socket_addrs()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl ToSocketAddrs for (Ipv4Addr, u16) {
+    type Iter = option::IntoIter<SocketAddr>;
+    fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
+        let (ip, port) = *self;
+        SocketAddrV4::new(ip, port).to_socket_addrs()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl ToSocketAddrs for (Ipv6Addr, u16) {
     type Iter = option::IntoIter<SocketAddr>;
     fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
         let (ip, port) = *self;
-        Ok(Some(SocketAddr::new(ip, port)).into_iter())
+        SocketAddrV6::new(ip, port, 0, 0).to_socket_addrs()
     }
 }
 
 fn resolve_socket_addr(s: &str, p: u16) -> io::Result<vec::IntoIter<SocketAddr>> {
     let ips = try!(lookup_host(s));
     let v: Vec<_> = try!(ips.map(|a| {
-        a.map(|mut a| { a.set_port(p); a })
+        a.map(|a| {
+            match a {
+                SocketAddr::V4(ref a) => {
+                    SocketAddr::V4(SocketAddrV4::new(*a.ip(), p))
+                }
+                SocketAddr::V6(ref a) => {
+                    SocketAddr::V6(SocketAddrV6::new(*a.ip(), p, a.flowinfo(),
+                                                     a.scope_id()))
+                }
+            }
+        })
     }).collect());
     Ok(v.into_iter())
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> ToSocketAddrs for (&'a str, u16) {
     type Iter = vec::IntoIter<SocketAddr>;
     fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
         let (host, port) = *self;
 
-        // try to parse the host as a regular IpAddr first
-        match host.parse().ok() {
-            Some(addr) => return Ok(vec![SocketAddr::new(addr, port)].into_iter()),
-            None => {}
+        // try to parse the host as a regular IP address first
+        if let Ok(addr) = host.parse::<Ipv4Addr>() {
+            let addr = SocketAddrV4::new(addr, port);
+            return Ok(vec![SocketAddr::V4(addr)].into_iter())
+        }
+        if let Ok(addr) = host.parse::<Ipv6Addr>() {
+            let addr = SocketAddrV6::new(addr, port, 0, 0);
+            return Ok(vec![SocketAddr::V6(addr)].into_iter())
         }
 
         resolve_socket_addr(host, port)
@@ -273,6 +389,7 @@ impl<'a> ToSocketAddrs for (&'a str, u16) {
 }
 
 // accepts strings like 'localhost:12345'
+#[stable(feature = "rust1", since = "1.0.0")]
 impl ToSocketAddrs for str {
     type Iter = vec::IntoIter<SocketAddr>;
     fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
@@ -322,16 +439,16 @@ mod tests {
         assert_eq!(Ok(Ipv4Addr::new(0, 0, 0, 0)), "0.0.0.0".parse());
 
         // out of range
-        let none: Option<IpAddr> = "256.0.0.1".parse().ok();
+        let none: Option<Ipv4Addr> = "256.0.0.1".parse().ok();
         assert_eq!(None, none);
         // too short
-        let none: Option<IpAddr> = "255.0.0".parse().ok();
+        let none: Option<Ipv4Addr> = "255.0.0".parse().ok();
         assert_eq!(None, none);
         // too long
-        let none: Option<IpAddr> = "255.0.0.1.2".parse().ok();
+        let none: Option<Ipv4Addr> = "255.0.0.1.2".parse().ok();
         assert_eq!(None, none);
         // no number between dots
-        let none: Option<IpAddr> = "255.0..1".parse().ok();
+        let none: Option<Ipv4Addr> = "255.0..1".parse().ok();
         assert_eq!(None, none);
     }
 
@@ -347,19 +464,19 @@ mod tests {
                 "2a02:6b8::11:11".parse());
 
         // too long group
-        let none: Option<IpAddr> = "::00000".parse().ok();
+        let none: Option<Ipv6Addr> = "::00000".parse().ok();
         assert_eq!(None, none);
         // too short
-        let none: Option<IpAddr> = "1:2:3:4:5:6:7".parse().ok();
+        let none: Option<Ipv6Addr> = "1:2:3:4:5:6:7".parse().ok();
         assert_eq!(None, none);
         // too long
-        let none: Option<IpAddr> = "1:2:3:4:5:6:7:8:9".parse().ok();
+        let none: Option<Ipv6Addr> = "1:2:3:4:5:6:7:8:9".parse().ok();
         assert_eq!(None, none);
         // triple colon
-        let none: Option<IpAddr> = "1:2:::6:7:8".parse().ok();
+        let none: Option<Ipv6Addr> = "1:2:::6:7:8".parse().ok();
         assert_eq!(None, none);
         // two double colons
-        let none: Option<IpAddr> = "1:2::6::8".parse().ok();
+        let none: Option<Ipv6Addr> = "1:2::6::8".parse().ok();
         assert_eq!(None, none);
     }
 
@@ -375,24 +492,24 @@ mod tests {
                 "2001:db8:122:c000:2:2100:192.0.2.33".parse());
 
         // colon after v4
-        let none: Option<IpAddr> = "::127.0.0.1:".parse().ok();
+        let none: Option<Ipv4Addr> = "::127.0.0.1:".parse().ok();
         assert_eq!(None, none);
         // not enough groups
-        let none: Option<IpAddr> = "1.2.3.4.5:127.0.0.1".parse().ok();
+        let none: Option<Ipv6Addr> = "1.2.3.4.5:127.0.0.1".parse().ok();
         assert_eq!(None, none);
         // too many groups
-        let none: Option<IpAddr> = "1.2.3.4.5:6:7:127.0.0.1".parse().ok();
+        let none: Option<Ipv6Addr> = "1.2.3.4.5:6:7:127.0.0.1".parse().ok();
         assert_eq!(None, none);
     }
 
     #[test]
     fn test_from_str_socket_addr() {
-        assert_eq!(Ok(SocketAddr::new(IpAddr::new_v4(77, 88, 21, 11), 80)),
-                "77.88.21.11:80".parse());
-        assert_eq!(Ok(SocketAddr::new(IpAddr::new_v6(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53)),
-                "[2a02:6b8:0:1::1]:53".parse());
-        assert_eq!(Ok(SocketAddr::new(IpAddr::new_v6(0, 0, 0, 0, 0, 0, 0x7F00, 1), 22)),
-                "[::127.0.0.1]:22".parse());
+        assert_eq!(Ok(sa4(Ipv4Addr::new(77, 88, 21, 11), 80)),
+                   "77.88.21.11:80".parse());
+        assert_eq!(Ok(sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53)),
+                   "[2a02:6b8:0:1::1]:53".parse());
+        assert_eq!(Ok(sa6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0x7F00, 1), 22)),
+                   "[::127.0.0.1]:22".parse());
 
         // without port
         let none: Option<SocketAddr> = "127.0.0.1".parse().ok();
@@ -555,39 +672,47 @@ mod tests {
 
     #[test]
     fn to_socket_addr_socketaddr() {
-        let a = SocketAddr::new(IpAddr::new_v4(77, 88, 21, 11), 12345);
+        let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 12345);
         assert_eq!(Ok(vec![a]), tsa(a));
     }
 
+    fn sa4(a: Ipv4Addr, p: u16) -> SocketAddr {
+        SocketAddr::V4(SocketAddrV4::new(a, p))
+    }
+
+    fn sa6(a: Ipv6Addr, p: u16) -> SocketAddr {
+        SocketAddr::V6(SocketAddrV6::new(a, p, 0, 0))
+    }
+
     #[test]
     fn to_socket_addr_ipaddr_u16() {
-        let a = IpAddr::new_v4(77, 88, 21, 11);
+        let a = Ipv4Addr::new(77, 88, 21, 11);
         let p = 12345;
-        let e = SocketAddr::new(a, p);
+        let e = SocketAddr::V4(SocketAddrV4::new(a, p));
         assert_eq!(Ok(vec![e]), tsa((a, p)));
     }
 
     #[test]
     fn to_socket_addr_str_u16() {
-        let a = SocketAddr::new(IpAddr::new_v4(77, 88, 21, 11), 24352);
+        let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352);
         assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352)));
 
-        let a = SocketAddr::new(IpAddr::new_v6(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53);
+        let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53);
         assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53)));
 
-        let a = SocketAddr::new(IpAddr::new_v4(127, 0, 0, 1), 23924);
+        let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924);
         assert!(tsa(("localhost", 23924)).unwrap().contains(&a));
     }
 
     #[test]
     fn to_socket_addr_str() {
-        let a = SocketAddr::new(IpAddr::new_v4(77, 88, 21, 11), 24352);
+        let a = sa4(Ipv4Addr::new(77, 88, 21, 11), 24352);
         assert_eq!(Ok(vec![a]), tsa("77.88.21.11:24352"));
 
-        let a = SocketAddr::new(IpAddr::new_v6(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53);
+        let a = sa6(Ipv6Addr::new(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53);
         assert_eq!(Ok(vec![a]), tsa("[2a02:6b8:0:1::1]:53"));
 
-        let a = SocketAddr::new(IpAddr::new_v4(127, 0, 0, 1), 23924);
+        let a = sa4(Ipv4Addr::new(127, 0, 0, 1), 23924);
         assert!(tsa("localhost:23924").unwrap().contains(&a));
     }
 
diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs
index d699886e577..c5f2ae53d22 100644
--- a/src/libstd/net/ip.rs
+++ b/src/libstd/net/ip.rs
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![unstable(feature = "ip", reason = "extra functionality has not been \
+                                      scrutinized to the level that it should \
+                                      be stable")]
+
 use prelude::v1::*;
 
 use cmp::Ordering;
@@ -19,12 +23,14 @@ use net::{hton, ntoh};
 
 /// Representation of an IPv4 address.
 #[derive(Copy)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Ipv4Addr {
     inner: libc::in_addr,
 }
 
 /// Representation of an IPv6 address.
 #[derive(Copy)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Ipv6Addr {
     inner: libc::in6_addr,
 }
@@ -41,46 +47,11 @@ pub enum Ipv6MulticastScope {
     Global
 }
 
-/// Enumeration of possible IP addresses
-#[derive(Copy, PartialEq, Eq, Clone, Hash, Debug)]
-pub enum IpAddr {
-    /// An IPv4 address.
-    V4(Ipv4Addr),
-    /// An IPv6 address.
-    V6(Ipv6Addr)
-}
-
-impl IpAddr {
-    /// Create a new IpAddr that contains an IPv4 address.
-    ///
-    /// The result will represent the IP address a.b.c.d
-    pub fn new_v4(a: u8, b: u8, c: u8, d: u8) -> IpAddr {
-        IpAddr::V4(Ipv4Addr::new(a, b, c, d))
-    }
-
-    /// Create a new IpAddr that contains an IPv6 address.
-    ///
-    /// The result will represent the IP address a:b:c:d:e:f
-    pub fn new_v6(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16,
-                  h: u16) -> IpAddr {
-        IpAddr::V6(Ipv6Addr::new(a, b, c, d, e, f, g, h))
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Display for IpAddr {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            IpAddr::V4(v4) => v4.fmt(f),
-            IpAddr::V6(v6) => v6.fmt(f)
-        }
-    }
-}
-
 impl Ipv4Addr {
     /// Create a new IPv4 address from four eight-bit octets.
     ///
     /// The result will represent the IP address a.b.c.d
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
         Ipv4Addr {
             inner: libc::in_addr {
@@ -93,6 +64,7 @@ impl Ipv4Addr {
     }
 
     /// Returns the four eight-bit integers that make up this address
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn octets(&self) -> [u8; 4] {
         let bits = ntoh(self.inner.s_addr);
         [(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8]
@@ -148,6 +120,7 @@ impl Ipv4Addr {
     /// Convert this address to an IPv4-compatible IPv6 address
     ///
     /// a.b.c.d becomes ::a.b.c.d
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_ipv6_compatible(&self) -> Ipv6Addr {
         Ipv6Addr::new(0, 0, 0, 0, 0, 0,
                       ((self.octets()[0] as u16) << 8) | self.octets()[1] as u16,
@@ -157,6 +130,7 @@ impl Ipv4Addr {
     /// Convert this address to an IPv4-mapped IPv6 address
     ///
     /// a.b.c.d becomes ::ffff:a.b.c.d
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_ipv6_mapped(&self) -> Ipv6Addr {
         Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff,
                       ((self.octets()[0] as u16) << 8) | self.octets()[1] as u16,
@@ -165,6 +139,7 @@ impl Ipv4Addr {
 
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for Ipv4Addr {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let octets = self.octets();
@@ -172,21 +147,26 @@ impl fmt::Display for Ipv4Addr {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Debug for Ipv4Addr {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         fmt::Display::fmt(self, fmt)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Clone for Ipv4Addr {
     fn clone(&self) -> Ipv4Addr { *self }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialEq for Ipv4Addr {
     fn eq(&self, other: &Ipv4Addr) -> bool {
         self.inner.s_addr == other.inner.s_addr
     }
 }
+
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Eq for Ipv4Addr {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -196,12 +176,14 @@ impl hash::Hash for Ipv4Addr {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialOrd for Ipv4Addr {
     fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> {
         Some(self.cmp(other))
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Ord for Ipv4Addr {
     fn cmp(&self, other: &Ipv4Addr) -> Ordering {
         self.inner.s_addr.cmp(&other.inner.s_addr)
@@ -221,6 +203,7 @@ impl Ipv6Addr {
     /// Create a new IPv6 address from eight 16-bit segments.
     ///
     /// The result will represent the IP address a:b:c:d:e:f
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16,
                h: u16) -> Ipv6Addr {
         Ipv6Addr {
@@ -232,6 +215,7 @@ impl Ipv6Addr {
     }
 
     /// Return the eight 16-bit segments that make up this address
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn segments(&self) -> [u16; 8] {
         [ntoh(self.inner.s6_addr[0]),
          ntoh(self.inner.s6_addr[1]),
@@ -324,6 +308,7 @@ impl Ipv6Addr {
     /// neither IPv4-compatible or IPv4-mapped.
     ///
     /// ::a.b.c.d and ::ffff:a.b.c.d become a.b.c.d
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_ipv4(&self) -> Option<Ipv4Addr> {
         match self.segments() {
             [0, 0, 0, 0, 0, f, g, h] if f == 0 || f == 0xffff => {
@@ -335,6 +320,7 @@ impl Ipv6Addr {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Display for Ipv6Addr {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         match self.segments() {
@@ -359,7 +345,7 @@ impl fmt::Display for Ipv6Addr {
                     let mut cur_span_len = 0;
                     let mut cur_span_at = 0;
 
-                    for i in range(0, 8) {
+                    for i in 0..8 {
                         if segments[i] == 0 {
                             if cur_span_len == 0 {
                                 cur_span_at = i;
@@ -405,21 +391,26 @@ impl fmt::Display for Ipv6Addr {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Debug for Ipv6Addr {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         fmt::Display::fmt(self, fmt)
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Clone for Ipv6Addr {
     fn clone(&self) -> Ipv6Addr { *self }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialEq for Ipv6Addr {
     fn eq(&self, other: &Ipv6Addr) -> bool {
         self.inner.s6_addr == other.inner.s6_addr
     }
 }
+
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Eq for Ipv6Addr {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -429,12 +420,14 @@ impl hash::Hash for Ipv6Addr {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl PartialOrd for Ipv6Addr {
     fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
         Some(self.cmp(other))
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Ord for Ipv6Addr {
     fn cmp(&self, other: &Ipv6Addr) -> Ordering {
         self.inner.s6_addr.cmp(&other.inner.s6_addr)
diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs
index b8cb8cb5289..36f36af73e1 100644
--- a/src/libstd/net/mod.rs
+++ b/src/libstd/net/mod.rs
@@ -11,10 +11,9 @@
 //! Networking primitives for TCP/UDP communication
 //!
 //! > **NOTE**: This module is very much a work in progress and is under active
-//! > development. At this time it is still recommended to use the `old_io`
-//! > module while the details of this module shake out.
+//! > development.
 
-#![unstable(feature = "net")]
+#![stable(feature = "rust1", since = "1.0.0")]
 
 use prelude::v1::*;
 
@@ -22,8 +21,8 @@ use io::{self, Error, ErrorKind};
 use num::Int;
 use sys_common::net2 as net_imp;
 
-pub use self::ip::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
-pub use self::addr::{SocketAddr, ToSocketAddrs};
+pub use self::ip::{Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
+pub use self::addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
 pub use self::tcp::{TcpStream, TcpListener};
 pub use self::udp::UdpSocket;
 
@@ -37,23 +36,27 @@ mod parser;
 /// Possible values which can be passed to the `shutdown` method of `TcpStream`
 /// and `UdpSocket`.
 #[derive(Copy, Clone, PartialEq)]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub enum Shutdown {
     /// Indicates that the reading portion of this stream/socket should be shut
     /// down. All currently blocked and future reads will return `Ok(0)`.
+    #[stable(feature = "rust1", since = "1.0.0")]
     Read,
     /// Indicates that the writing portion of this stream/socket should be shut
     /// down. All currently blocked and future writes will return an error.
+    #[stable(feature = "rust1", since = "1.0.0")]
     Write,
     /// Shut down both the reading and writing portions of this stream.
     ///
     /// See `Shutdown::Read` and `Shutdown::Write` for more information.
-    Both
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Both,
 }
 
 fn hton<I: Int>(i: I) -> I { i.to_be() }
 fn ntoh<I: Int>(i: I) -> I { Int::from_be(i) }
 
-fn each_addr<A: ToSocketAddrs + ?Sized, F, T>(addr: &A, mut f: F) -> io::Result<T>
+fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
     where F: FnMut(&SocketAddr) -> io::Result<T>
 {
     let mut last_err = None;
@@ -70,8 +73,10 @@ fn each_addr<A: ToSocketAddrs + ?Sized, F, T>(addr: &A, mut f: F) -> io::Result<
 }
 
 /// An iterator over `SocketAddr` values returned from a host lookup operation.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct LookupHost(net_imp::LookupHost);
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Iterator for LookupHost {
     type Item = io::Result<SocketAddr>;
     fn next(&mut self) -> Option<io::Result<SocketAddr>> { self.0.next() }
@@ -94,6 +99,7 @@ impl Iterator for LookupHost {
 /// # Ok(())
 /// # }
 /// ```
+#[stable(feature = "rust1", since = "1.0.0")]
 pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
     net_imp::lookup_host(host).map(LookupHost)
 }
diff --git a/src/libstd/net/parser.rs b/src/libstd/net/parser.rs
index aa54a432d62..9843a152718 100644
--- a/src/libstd/net/parser.rs
+++ b/src/libstd/net/parser.rs
@@ -16,7 +16,7 @@
 use prelude::v1::*;
 
 use str::FromStr;
-use net::{Ipv4Addr, Ipv6Addr, IpAddr, SocketAddr};
+use net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
 
 struct Parser<'a> {
     // parsing as ASCII, so can use byte array
@@ -24,6 +24,11 @@ struct Parser<'a> {
     pos: usize,
 }
 
+enum IpAddr {
+    V4(Ipv4Addr),
+    V6(Ipv6Addr),
+}
+
 impl<'a> Parser<'a> {
     fn new(s: &'a str) -> Parser<'a> {
         Parser {
@@ -281,18 +286,13 @@ impl<'a> Parser<'a> {
         let port  = |p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);
 
         // host, colon, port
-        self.read_seq_3::<IpAddr, char, u16, _, _, _>(ip_addr, colon, port)
-                .map(|t| match t { (ip, _, port) => SocketAddr::new(ip, port) })
-    }
-}
-
-impl FromStr for IpAddr {
-    type Err = ParseError;
-    fn from_str(s: &str) -> Result<IpAddr, ParseError> {
-        match Parser::new(s).read_till_eof(|p| p.read_ip_addr()) {
-            Some(s) => Ok(s),
-            None => Err(ParseError),
-        }
+        self.read_seq_3(ip_addr, colon, port).map(|t| {
+            let (ip, _, port): (IpAddr, char, u16) = t;
+            match ip {
+                IpAddr::V4(ip) => SocketAddr::V4(SocketAddrV4::new(ip, port)),
+                IpAddr::V6(ip) => SocketAddr::V6(SocketAddrV6::new(ip, port, 0, 0)),
+            }
+        })
     }
 }
 
diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs
index 76c04835473..501ba2dc2c1 100644
--- a/src/libstd/net/tcp.rs
+++ b/src/libstd/net/tcp.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![unstable(feature = "tcp", reason = "remaining functions have not been \
+                                       scrutinized enough to be stabilized")]
+
 use prelude::v1::*;
 use io::prelude::*;
 
@@ -35,6 +38,7 @@ use sys_common::AsInner;
 ///     let _ = stream.read(&mut [0; 128]); // ignore here too
 /// } // the stream is closed here
 /// ```
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct TcpStream(net_imp::TcpStream);
 
 /// A structure representing a socket server.
@@ -67,12 +71,14 @@ pub struct TcpStream(net_imp::TcpStream);
 /// // close the socket server
 /// drop(listener);
 /// ```
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct TcpListener(net_imp::TcpListener);
 
 /// An infinite iterator over the connections from a `TcpListener`.
 ///
 /// This iterator will infinitely yield `Some` of the accepted connections. It
 /// is equivalent to calling `accept` in a loop.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct Incoming<'a> { listener: &'a TcpListener }
 
 impl TcpStream {
@@ -81,25 +87,36 @@ impl TcpStream {
     /// `addr` is an address of the remote host. Anything which implements
     /// `ToSocketAddrs` trait can be supplied for the address; see this trait
     /// documentation for concrete examples.
-    pub fn connect<A: ToSocketAddrs + ?Sized>(addr: &A) -> io::Result<TcpStream> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
         super::each_addr(addr, net_imp::TcpStream::connect).map(TcpStream)
     }
 
     /// Returns the socket address of the remote peer of this TCP connection.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
         self.0.peer_addr()
     }
 
     /// Returns the socket address of the local half of this TCP connection.
+    #[unstable(feature = "net")]
+    #[deprecated(since = "1.0.0", reason = "renamed to local_addr")]
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
         self.0.socket_addr()
     }
 
+    /// Returns the socket address of the local half of this TCP connection.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        self.0.socket_addr()
+    }
+
     /// Shut down the read, write, or both halves of this connection.
     ///
     /// This function will cause all pending and future I/O on the specified
     /// portions to return immediately with an appropriate value (see the
     /// documentation of `Shutdown`).
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
         self.0.shutdown(how)
     }
@@ -110,6 +127,7 @@ impl TcpStream {
     /// object references. Both handles will read and write the same stream of
     /// data, and options set on one stream will be propagated to the other
     /// stream.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_clone(&self) -> io::Result<TcpStream> {
         self.0.duplicate().map(TcpStream)
     }
@@ -129,16 +147,20 @@ impl TcpStream {
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Read for TcpStream {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl Write for TcpStream {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
     fn flush(&mut self) -> io::Result<()> { Ok(()) }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Read for &'a TcpStream {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
 }
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Write for &'a TcpStream {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
     fn flush(&mut self) -> io::Result<()> { Ok(()) }
@@ -160,11 +182,20 @@ impl TcpListener {
     ///
     /// The address type can be any implementer of `ToSocketAddrs` trait. See
     /// its documentation for concrete examples.
-    pub fn bind<A: ToSocketAddrs + ?Sized>(addr: &A) -> io::Result<TcpListener> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
         super::each_addr(addr, net_imp::TcpListener::bind).map(TcpListener)
     }
 
     /// Returns the local socket address of this listener.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        self.0.socket_addr()
+    }
+
+    /// Deprecated, renamed to local_addr
+    #[unstable(feature = "net")]
+    #[deprecated(since = "1.0.0", reason = "renamed to local_addr")]
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
         self.0.socket_addr()
     }
@@ -174,6 +205,7 @@ impl TcpListener {
     /// The returned `TcpListener` is a reference to the same socket that this
     /// object references. Both handles can be used to accept incoming
     /// connections and options set on one listener will affect the other.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_clone(&self) -> io::Result<TcpListener> {
         self.0.duplicate().map(TcpListener)
     }
@@ -183,6 +215,7 @@ impl TcpListener {
     /// This function will block the calling thread until a new TCP connection
     /// is established. When established, the corresponding `TcpStream` and the
     /// remote peer's address will be returned.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
         self.0.accept().map(|(a, b)| (TcpStream(a), b))
     }
@@ -192,11 +225,13 @@ impl TcpListener {
     ///
     /// The returned iterator will never returned `None` and will also not yield
     /// the peer's `SocketAddr` structure.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn incoming(&self) -> Incoming {
         Incoming { listener: self }
     }
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Iterator for Incoming<'a> {
     type Item = io::Result<TcpStream>;
     fn next(&mut self) -> Option<io::Result<TcpStream>> {
diff --git a/src/libstd/net/test.rs b/src/libstd/net/test.rs
index dbebede9f50..3d42472f0fc 100644
--- a/src/libstd/net/test.rs
+++ b/src/libstd/net/test.rs
@@ -11,19 +11,20 @@
 use prelude::v1::*;
 
 use env;
-use net::{SocketAddr, IpAddr};
+use net::{SocketAddr, SocketAddrV4, SocketAddrV6, Ipv4Addr, Ipv6Addr};
 use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
 
 static PORT: AtomicUsize = ATOMIC_USIZE_INIT;
 
 pub fn next_test_ip4() -> SocketAddr {
-    SocketAddr::new(IpAddr::new_v4(127, 0, 0, 1),
-                    PORT.fetch_add(1, Ordering::SeqCst) as u16 + base_port())
+    let port = PORT.fetch_add(1, Ordering::SeqCst) as u16 + base_port();
+    SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), port))
 }
 
 pub fn next_test_ip6() -> SocketAddr {
-    SocketAddr::new(IpAddr::new_v6(0, 0, 0, 0, 0, 0, 0, 1),
-                    PORT.fetch_add(1, Ordering::SeqCst) as u16 + base_port())
+    let port = PORT.fetch_add(1, Ordering::SeqCst) as u16 + base_port();
+    SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1),
+                                     port, 0, 0))
 }
 
 // The bots run multiple builds at the same time, and these builds
diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs
index 041e6551ff5..1ace1957526 100644
--- a/src/libstd/net/udp.rs
+++ b/src/libstd/net/udp.rs
@@ -8,10 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![unstable(feature = "udp", reason = "remaining functions have not been \
+                                       scrutinized enough to be stabilized")]
+
 use prelude::v1::*;
 
 use io::{self, Error, ErrorKind};
-use net::{ToSocketAddrs, SocketAddr, IpAddr};
+use net::{ToSocketAddrs, SocketAddr};
 use sys_common::net2 as net_imp;
 use sys_common::AsInner;
 
@@ -41,6 +44,7 @@ use sys_common::AsInner;
 /// # Ok(())
 /// # }
 /// ```
+#[stable(feature = "rust1", since = "1.0.0")]
 pub struct UdpSocket(net_imp::UdpSocket);
 
 impl UdpSocket {
@@ -48,12 +52,14 @@ impl UdpSocket {
     ///
     /// Address type can be any implementor of `ToSocketAddr` trait. See its
     /// documentation for concrete examples.
-    pub fn bind<A: ToSocketAddrs + ?Sized>(addr: &A) -> io::Result<UdpSocket> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
         super::each_addr(addr, net_imp::UdpSocket::bind).map(UdpSocket)
     }
 
     /// Receives data from the socket. On success, returns the number of bytes
     /// read and the address from whence the data came.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
         self.0.recv_from(buf)
     }
@@ -63,8 +69,9 @@ impl UdpSocket {
     ///
     /// Address type can be any implementor of `ToSocketAddrs` trait. See its
     /// documentation for concrete examples.
-    pub fn send_to<A: ToSocketAddrs + ?Sized>(&self, buf: &[u8], addr: &A)
-                                              -> io::Result<usize> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A)
+                                     -> io::Result<usize> {
         match try!(addr.to_socket_addrs()).next() {
             Some(addr) => self.0.send_to(buf, &addr),
             None => Err(Error::new(ErrorKind::InvalidInput,
@@ -73,15 +80,24 @@ impl UdpSocket {
     }
 
     /// Returns the socket address that this socket was created from.
+    #[unstable(feature = "net")]
+    #[deprecated(since = "1.0.0", reason = "renamed to local_addr")]
     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
         self.0.socket_addr()
     }
 
+    /// Returns the socket address that this socket was created from.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        self.0.socket_addr()
+    }
+
     /// Create a new independently owned handle to the underlying socket.
     ///
     /// The returned `UdpSocket` is a reference to the same socket that this
     /// object references. Both handles will read and write the same port, and
     /// options set on one socket will be propagated to the other.
+    #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_clone(&self) -> io::Result<UdpSocket> {
         self.0.duplicate().map(UdpSocket)
     }
@@ -99,12 +115,12 @@ impl UdpSocket {
     }
 
     /// Joins a multicast IP address (becomes a member of it)
-    pub fn join_multicast(&self, multi: &IpAddr) -> io::Result<()> {
+    pub fn join_multicast(&self, multi: &SocketAddr) -> io::Result<()> {
         self.0.join_multicast(multi)
     }
 
     /// Leaves a multicast IP address (drops membership from it)
-    pub fn leave_multicast(&self, multi: &IpAddr) -> io::Result<()> {
+    pub fn leave_multicast(&self, multi: &SocketAddr) -> io::Result<()> {
         self.0.leave_multicast(multi)
     }
 
@@ -151,7 +167,7 @@ mod tests {
     #[cfg_attr(any(windows, target_os = "android"), ignore)]
     #[test]
     fn bind_error() {
-        let addr = SocketAddr::new(IpAddr::new_v4(0, 0, 0, 0), 1);
+        let addr = SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 1);
         match UdpSocket::bind(&addr) {
             Ok(..) => panic!(),
             Err(e) => assert_eq!(e.kind(), ErrorKind::PermissionDenied),
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index 969dd35ba22..a7825c4f93a 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -357,6 +357,1236 @@ impl Float for f32 {
     }
 }
 
+#[cfg(not(stage0))]
+#[cfg(not(test))]
+#[lang = "f32"]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl f32 {
+    // inlined methods from `num::Float`
+    /// Returns the `NaN` value.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let nan: f32 = Float::nan();
+    ///
+    /// assert!(nan.is_nan());
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn nan() -> f32 { num::Float::nan() }
+
+    /// Returns the infinite value.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f32;
+    ///
+    /// let infinity: f32 = Float::infinity();
+    ///
+    /// assert!(infinity.is_infinite());
+    /// assert!(!infinity.is_finite());
+    /// assert!(infinity > f32::MAX);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn infinity() -> f32 { num::Float::infinity() }
+
+    /// Returns the negative infinite value.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f32;
+    ///
+    /// let neg_infinity: f32 = Float::neg_infinity();
+    ///
+    /// assert!(neg_infinity.is_infinite());
+    /// assert!(!neg_infinity.is_finite());
+    /// assert!(neg_infinity < f32::MIN);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn neg_infinity() -> f32 { num::Float::neg_infinity() }
+
+    /// Returns `0.0`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let inf: f32 = Float::infinity();
+    /// let zero: f32 = Float::zero();
+    /// let neg_zero: f32 = Float::neg_zero();
+    ///
+    /// assert_eq!(zero, neg_zero);
+    /// assert_eq!(7.0f32/inf, zero);
+    /// assert_eq!(zero * 10.0, zero);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn zero() -> f32 { num::Float::zero() }
+
+    /// Returns `-0.0`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let inf: f32 = Float::infinity();
+    /// let zero: f32 = Float::zero();
+    /// let neg_zero: f32 = Float::neg_zero();
+    ///
+    /// assert_eq!(zero, neg_zero);
+    /// assert_eq!(7.0f32/inf, zero);
+    /// assert_eq!(zero * 10.0, zero);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn neg_zero() -> f32 { num::Float::neg_zero() }
+
+    /// Returns `1.0`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let one: f32 = Float::one();
+    ///
+    /// assert_eq!(one, 1.0f32);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn one() -> f32 { num::Float::one() }
+
+    // FIXME (#5527): These should be associated constants
+
+    /// Deprecated: use `std::f32::MANTISSA_DIGITS` or `std::f64::MANTISSA_DIGITS`
+    /// instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `std::f32::MANTISSA_DIGITS` or \
+                           `std::f64::MANTISSA_DIGITS` as appropriate")]
+    #[allow(deprecated)]
+    #[inline]
+    pub fn mantissa_digits(unused_self: Option<f32>) -> uint {
+        num::Float::mantissa_digits(unused_self)
+    }
+
+    /// Deprecated: use `std::f32::DIGITS` or `std::f64::DIGITS` instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `std::f32::DIGITS` or `std::f64::DIGITS` as appropriate")]
+    #[allow(deprecated)]
+    #[inline]
+    pub fn digits(unused_self: Option<f32>) -> uint { num::Float::digits(unused_self) }
+
+    /// Deprecated: use `std::f32::EPSILON` or `std::f64::EPSILON` instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `std::f32::EPSILON` or `std::f64::EPSILON` as appropriate")]
+    #[allow(deprecated)]
+    #[inline]
+    pub fn epsilon() -> f32 { num::Float::epsilon() }
+
+    /// Deprecated: use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` as appropriate")]
+    #[allow(deprecated)]
+    #[inline]
+    pub fn min_exp(unused_self: Option<f32>) -> int { num::Float::min_exp(unused_self) }
+
+    /// Deprecated: use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` as appropriate")]
+    #[allow(deprecated)]
+    #[inline]
+    pub fn max_exp(unused_self: Option<f32>) -> int { num::Float::max_exp(unused_self) }
+
+    /// Deprecated: use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` as appropriate")]
+    #[allow(deprecated)]
+    #[inline]
+    pub fn min_10_exp(unused_self: Option<f32>) -> int { num::Float::min_10_exp(unused_self) }
+
+    /// Deprecated: use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` as appropriate")]
+    #[allow(deprecated)]
+    #[inline]
+    pub fn max_10_exp(unused_self: Option<f32>) -> int { num::Float::max_10_exp(unused_self) }
+
+    /// Returns the smallest finite value that this type can represent.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x: f64 = Float::min_value();
+    ///
+    /// assert_eq!(x, f64::MIN);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    #[allow(deprecated)]
+    pub fn min_value() -> f32 { num::Float::min_value() }
+
+    /// Returns the smallest normalized positive number that this type can represent.
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    #[allow(deprecated)]
+    pub fn min_pos_value(unused_self: Option<f32>) -> f32 { num::Float::min_pos_value(unused_self) }
+
+    /// Returns the largest finite value that this type can represent.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x: f64 = Float::max_value();
+    /// assert_eq!(x, f64::MAX);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    #[allow(deprecated)]
+    pub fn max_value() -> f32 { num::Float::max_value() }
+
+    /// Returns `true` if this value is `NaN` and false otherwise.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let nan = f64::NAN;
+    /// let f = 7.0;
+    ///
+    /// assert!(nan.is_nan());
+    /// assert!(!f.is_nan());
+    /// ```
+    #[unstable(feature = "std_misc", reason = "position is undecided")]
+    #[inline]
+    pub fn is_nan(self) -> bool { num::Float::is_nan(self) }
+
+    /// Returns `true` if this value is positive infinity or negative infinity and
+    /// false otherwise.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f32;
+    ///
+    /// let f = 7.0f32;
+    /// let inf: f32 = Float::infinity();
+    /// let neg_inf: f32 = Float::neg_infinity();
+    /// let nan: f32 = f32::NAN;
+    ///
+    /// assert!(!f.is_infinite());
+    /// assert!(!nan.is_infinite());
+    ///
+    /// assert!(inf.is_infinite());
+    /// assert!(neg_inf.is_infinite());
+    /// ```
+    #[unstable(feature = "std_misc", reason = "position is undecided")]
+    #[inline]
+    pub fn is_infinite(self) -> bool { num::Float::is_infinite(self) }
+
+    /// Returns `true` if this number is neither infinite nor `NaN`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f32;
+    ///
+    /// let f = 7.0f32;
+    /// let inf: f32 = Float::infinity();
+    /// let neg_inf: f32 = Float::neg_infinity();
+    /// let nan: f32 = f32::NAN;
+    ///
+    /// assert!(f.is_finite());
+    ///
+    /// assert!(!nan.is_finite());
+    /// assert!(!inf.is_finite());
+    /// assert!(!neg_inf.is_finite());
+    /// ```
+    #[unstable(feature = "std_misc", reason = "position is undecided")]
+    #[inline]
+    pub fn is_finite(self) -> bool { num::Float::is_finite(self) }
+
+    /// Returns `true` if the number is neither zero, infinite,
+    /// [subnormal][subnormal], or `NaN`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f32;
+    ///
+    /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
+    /// let max = f32::MAX;
+    /// let lower_than_min = 1.0e-40_f32;
+    /// let zero = 0.0f32;
+    ///
+    /// assert!(min.is_normal());
+    /// assert!(max.is_normal());
+    ///
+    /// assert!(!zero.is_normal());
+    /// assert!(!f32::NAN.is_normal());
+    /// assert!(!f32::INFINITY.is_normal());
+    /// // Values between `0` and `min` are Subnormal.
+    /// assert!(!lower_than_min.is_normal());
+    /// ```
+    /// [subnormal]: http://en.wikipedia.org/wiki/Denormal_number
+    #[unstable(feature = "std_misc", reason = "position is undecided")]
+    #[inline]
+    pub fn is_normal(self) -> bool { num::Float::is_normal(self) }
+
+    /// Returns the floating point category of the number. If only one property
+    /// is going to be tested, it is generally faster to use the specific
+    /// predicate instead.
+    ///
+    /// ```
+    /// use std::num::{Float, FpCategory};
+    /// use std::f32;
+    ///
+    /// let num = 12.4f32;
+    /// let inf = f32::INFINITY;
+    ///
+    /// assert_eq!(num.classify(), FpCategory::Normal);
+    /// assert_eq!(inf.classify(), FpCategory::Infinite);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn classify(self) -> FpCategory { num::Float::classify(self) }
+
+    /// Returns the mantissa, base 2 exponent, and sign as integers, respectively.
+    /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`.
+    /// The floating point encoding is documented in the [Reference][floating-point].
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let num = 2.0f32;
+    ///
+    /// // (8388608, -22, 1)
+    /// let (mantissa, exponent, sign) = num.integer_decode();
+    /// let sign_f = sign as f32;
+    /// let mantissa_f = mantissa as f32;
+    /// let exponent_f = num.powf(exponent as f32);
+    ///
+    /// // 1 * 8388608 * 2^(-22) == 2
+    /// let abs_difference = (sign_f * mantissa_f * exponent_f - num).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    /// [floating-point]: ../../../../../reference.html#machine-types
+    #[unstable(feature = "std_misc", reason = "signature is undecided")]
+    #[inline]
+    pub fn integer_decode(self) -> (u64, i16, i8) { num::Float::integer_decode(self) }
+
+    /// Returns the largest integer less than or equal to a number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 3.99;
+    /// let g = 3.0;
+    ///
+    /// assert_eq!(f.floor(), 3.0);
+    /// assert_eq!(g.floor(), 3.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn floor(self) -> f32 { num::Float::floor(self) }
+
+    /// Returns the smallest integer greater than or equal to a number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 3.01;
+    /// let g = 4.0;
+    ///
+    /// assert_eq!(f.ceil(), 4.0);
+    /// assert_eq!(g.ceil(), 4.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn ceil(self) -> f32 { num::Float::ceil(self) }
+
+    /// Returns the nearest integer to a number. Round half-way cases away from
+    /// `0.0`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 3.3;
+    /// let g = -3.3;
+    ///
+    /// assert_eq!(f.round(), 3.0);
+    /// assert_eq!(g.round(), -3.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn round(self) -> f32 { num::Float::round(self) }
+
+    /// Return the integer part of a number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 3.3;
+    /// let g = -3.7;
+    ///
+    /// assert_eq!(f.trunc(), 3.0);
+    /// assert_eq!(g.trunc(), -3.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn trunc(self) -> f32 { num::Float::trunc(self) }
+
+    /// Returns the fractional part of a number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 3.5;
+    /// let y = -3.5;
+    /// let abs_difference_x = (x.fract() - 0.5).abs();
+    /// let abs_difference_y = (y.fract() - (-0.5)).abs();
+    ///
+    /// assert!(abs_difference_x < 1e-10);
+    /// assert!(abs_difference_y < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn fract(self) -> f32 { num::Float::fract(self) }
+
+    /// Computes the absolute value of `self`. Returns `Float::nan()` if the
+    /// number is `Float::nan()`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = 3.5;
+    /// let y = -3.5;
+    ///
+    /// let abs_difference_x = (x.abs() - x).abs();
+    /// let abs_difference_y = (y.abs() - (-y)).abs();
+    ///
+    /// assert!(abs_difference_x < 1e-10);
+    /// assert!(abs_difference_y < 1e-10);
+    ///
+    /// assert!(f64::NAN.abs().is_nan());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn abs(self) -> f32 { num::Float::abs(self) }
+
+    /// Returns a number that represents the sign of `self`.
+    ///
+    /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()`
+    /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()`
+    /// - `Float::nan()` if the number is `Float::nan()`
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let f = 3.5;
+    ///
+    /// assert_eq!(f.signum(), 1.0);
+    /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0);
+    ///
+    /// assert!(f64::NAN.signum().is_nan());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn signum(self) -> f32 { num::Float::signum(self) }
+
+    /// Returns `true` if `self` is positive, including `+0.0` and
+    /// `Float::infinity()`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let nan: f64 = f64::NAN;
+    ///
+    /// let f = 7.0;
+    /// let g = -7.0;
+    ///
+    /// assert!(f.is_positive());
+    /// assert!(!g.is_positive());
+    /// // Requires both tests to determine if is `NaN`
+    /// assert!(!nan.is_positive() && !nan.is_negative());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_positive(self) -> bool { num::Float::is_positive(self) }
+
+    /// Returns `true` if `self` is negative, including `-0.0` and
+    /// `Float::neg_infinity()`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let nan = f64::NAN;
+    ///
+    /// let f = 7.0;
+    /// let g = -7.0;
+    ///
+    /// assert!(!f.is_negative());
+    /// assert!(g.is_negative());
+    /// // Requires both tests to determine if is `NaN`.
+    /// assert!(!nan.is_positive() && !nan.is_negative());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_negative(self) -> bool { num::Float::is_negative(self) }
+
+    /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
+    /// error. This produces a more accurate result with better performance than
+    /// a separate multiplication operation followed by an add.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let m = 10.0;
+    /// let x = 4.0;
+    /// let b = 60.0;
+    ///
+    /// // 100.0
+    /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn mul_add(self, a: f32, b: f32) -> f32 { num::Float::mul_add(self, a, b) }
+
+    /// Take the reciprocal (inverse) of a number, `1/x`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 2.0;
+    /// let abs_difference = (x.recip() - (1.0/x)).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn recip(self) -> f32 { num::Float::recip(self) }
+
+    /// Raise a number to an integer power.
+    ///
+    /// Using this function is generally faster than using `powf`
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 2.0;
+    /// let abs_difference = (x.powi(2) - x*x).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn powi(self, n: i32) -> f32 { num::Float::powi(self, n) }
+
+    /// Raise a number to a floating point power.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 2.0;
+    /// let abs_difference = (x.powf(2.0) - x*x).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn powf(self, n: f32) -> f32 { num::Float::powf(self, n) }
+
+    /// Take the square root of a number.
+    ///
+    /// Returns NaN if `self` is a negative number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let positive = 4.0;
+    /// let negative = -4.0;
+    ///
+    /// let abs_difference = (positive.sqrt() - 2.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// assert!(negative.sqrt().is_nan());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sqrt(self) -> f32 { num::Float::sqrt(self) }
+
+
+    /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 4.0;
+    ///
+    /// let abs_difference = (f.rsqrt() - 0.5).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn rsqrt(self) -> f32 { num::Float::rsqrt(self) }
+
+    /// Returns `e^(self)`, (the exponential function).
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let one = 1.0;
+    /// // e^1
+    /// let e = one.exp();
+    ///
+    /// // ln(e) - 1 == 0
+    /// let abs_difference = (e.ln() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn exp(self) -> f32 { num::Float::exp(self) }
+
+    /// Returns `2^(self)`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 2.0;
+    ///
+    /// // 2^2 - 4 == 0
+    /// let abs_difference = (f.exp2() - 4.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn exp2(self) -> f32 { num::Float::exp2(self) }
+
+    /// Returns the natural logarithm of the number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let one = 1.0;
+    /// // e^1
+    /// let e = one.exp();
+    ///
+    /// // ln(e) - 1 == 0
+    /// let abs_difference = (e.ln() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn ln(self) -> f32 { num::Float::ln(self) }
+
+    /// Returns the logarithm of the number with respect to an arbitrary base.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let ten = 10.0;
+    /// let two = 2.0;
+    ///
+    /// // log10(10) - 1 == 0
+    /// let abs_difference_10 = (ten.log(10.0) - 1.0).abs();
+    ///
+    /// // log2(2) - 1 == 0
+    /// let abs_difference_2 = (two.log(2.0) - 1.0).abs();
+    ///
+    /// assert!(abs_difference_10 < 1e-10);
+    /// assert!(abs_difference_2 < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn log(self, base: f32) -> f32 { num::Float::log(self, base) }
+
+    /// Returns the base 2 logarithm of the number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let two = 2.0;
+    ///
+    /// // log2(2) - 1 == 0
+    /// let abs_difference = (two.log2() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn log2(self) -> f32 { num::Float::log2(self) }
+
+    /// Returns the base 10 logarithm of the number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let ten = 10.0;
+    ///
+    /// // log10(10) - 1 == 0
+    /// let abs_difference = (ten.log10() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn log10(self) -> f32 { num::Float::log10(self) }
+
+    /// Convert radians to degrees.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64::consts;
+    ///
+    /// let angle = consts::PI;
+    ///
+    /// let abs_difference = (angle.to_degrees() - 180.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc", reason = "desirability is unclear")]
+    #[inline]
+    pub fn to_degrees(self) -> f32 { num::Float::to_degrees(self) }
+
+    /// Convert degrees to radians.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64::consts;
+    ///
+    /// let angle = 180.0;
+    ///
+    /// let abs_difference = (angle.to_radians() - consts::PI).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc", reason = "desirability is unclear")]
+    #[inline]
+    pub fn to_radians(self) -> f32 { num::Float::to_radians(self) }
+
+    /// Constructs a floating point number of `x*2^exp`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// // 3*2^2 - 12 == 0
+    /// let abs_difference = (Float::ldexp(3.0, 2) - 12.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "pending integer conventions")]
+    #[inline]
+    pub fn ldexp(x: f32, exp: int) -> f32 {
+        unsafe { cmath::ldexpf(x, exp as c_int) }
+    }
+
+    /// Breaks the number into a normalized fraction and a base-2 exponent,
+    /// satisfying:
+    ///
+    ///  * `self = x * 2^exp`
+    ///  * `0.5 <= abs(x) < 1.0`
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 4.0;
+    ///
+    /// // (1/2)*2^3 -> 1 * 8/2 -> 4.0
+    /// let f = x.frexp();
+    /// let abs_difference_0 = (f.0 - 0.5).abs();
+    /// let abs_difference_1 = (f.1 as f64 - 3.0).abs();
+    ///
+    /// assert!(abs_difference_0 < 1e-10);
+    /// assert!(abs_difference_1 < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "pending integer conventions")]
+    #[inline]
+    pub fn frexp(self) -> (f32, int) {
+        unsafe {
+            let mut exp = 0;
+            let x = cmath::frexpf(self, &mut exp);
+            (x, exp as int)
+        }
+    }
+
+    /// Returns the next representable floating-point value in the direction of
+    /// `other`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 1.0f32;
+    ///
+    /// let abs_diff = (x.next_after(2.0) - 1.00000011920928955078125_f32).abs();
+    ///
+    /// assert!(abs_diff < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn next_after(self, other: f32) -> f32 {
+        unsafe { cmath::nextafterf(self, other) }
+    }
+
+    /// Returns the maximum of the two numbers.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 1.0;
+    /// let y = 2.0;
+    ///
+    /// assert_eq!(x.max(y), y);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn max(self, other: f32) -> f32 {
+        unsafe { cmath::fmaxf(self, other) }
+    }
+
+    /// Returns the minimum of the two numbers.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 1.0;
+    /// let y = 2.0;
+    ///
+    /// assert_eq!(x.min(y), x);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn min(self, other: f32) -> f32 {
+        unsafe { cmath::fminf(self, other) }
+    }
+
+    /// The positive difference of two numbers.
+    ///
+    /// * If `self <= other`: `0:0`
+    /// * Else: `self - other`
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 3.0;
+    /// let y = -3.0;
+    ///
+    /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs();
+    /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs();
+    ///
+    /// assert!(abs_difference_x < 1e-10);
+    /// assert!(abs_difference_y < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc", reason = "may be renamed")]
+    #[inline]
+    pub fn abs_sub(self, other: f32) -> f32 {
+        unsafe { cmath::fdimf(self, other) }
+    }
+
+    /// Take the cubic root of a number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 8.0;
+    ///
+    /// // x^(1/3) - 2 == 0
+    /// let abs_difference = (x.cbrt() - 2.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc", reason = "may be renamed")]
+    #[inline]
+    pub fn cbrt(self) -> f32 {
+        unsafe { cmath::cbrtf(self) }
+    }
+
+    /// Calculate the length of the hypotenuse of a right-angle triangle given
+    /// legs of length `x` and `y`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 2.0;
+    /// let y = 3.0;
+    ///
+    /// // sqrt(x^2 + y^2)
+    /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn hypot(self, other: f32) -> f32 {
+        unsafe { cmath::hypotf(self, other) }
+    }
+
+    /// Computes the sine of a number (in radians).
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/2.0;
+    ///
+    /// let abs_difference = (x.sin() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sin(self) -> f32 {
+        unsafe { intrinsics::sinf32(self) }
+    }
+
+    /// Computes the cosine of a number (in radians).
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = 2.0*f64::consts::PI;
+    ///
+    /// let abs_difference = (x.cos() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn cos(self) -> f32 {
+        unsafe { intrinsics::cosf32(self) }
+    }
+
+    /// Computes the tangent of a number (in radians).
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/4.0;
+    /// let abs_difference = (x.tan() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-14);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn tan(self) -> f32 {
+        unsafe { cmath::tanf(self) }
+    }
+
+    /// Computes the arcsine of a number. Return value is in radians in
+    /// the range [-pi/2, pi/2] or NaN if the number is outside the range
+    /// [-1, 1].
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let f = f64::consts::PI / 2.0;
+    ///
+    /// // asin(sin(pi/2))
+    /// let abs_difference = (f.sin().asin() - f64::consts::PI / 2.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn asin(self) -> f32 {
+        unsafe { cmath::asinf(self) }
+    }
+
+    /// Computes the arccosine of a number. Return value is in radians in
+    /// the range [0, pi] or NaN if the number is outside the range
+    /// [-1, 1].
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let f = f64::consts::PI / 4.0;
+    ///
+    /// // acos(cos(pi/4))
+    /// let abs_difference = (f.cos().acos() - f64::consts::PI / 4.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn acos(self) -> f32 {
+        unsafe { cmath::acosf(self) }
+    }
+
+    /// Computes the arctangent of a number. Return value is in radians in the
+    /// range [-pi/2, pi/2];
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 1.0;
+    ///
+    /// // atan(tan(1))
+    /// let abs_difference = (f.tan().atan() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn atan(self) -> f32 {
+        unsafe { cmath::atanf(self) }
+    }
+
+    /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`).
+    ///
+    /// * `x = 0`, `y = 0`: `0`
+    /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
+    /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
+    /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let pi = f64::consts::PI;
+    /// // All angles from horizontal right (+x)
+    /// // 45 deg counter-clockwise
+    /// let x1 = 3.0;
+    /// let y1 = -3.0;
+    ///
+    /// // 135 deg clockwise
+    /// let x2 = -3.0;
+    /// let y2 = 3.0;
+    ///
+    /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs();
+    /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs();
+    ///
+    /// assert!(abs_difference_1 < 1e-10);
+    /// assert!(abs_difference_2 < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn atan2(self, other: f32) -> f32 {
+        unsafe { cmath::atan2f(self, other) }
+    }
+
+    /// Simultaneously computes the sine and cosine of the number, `x`. Returns
+    /// `(sin(x), cos(x))`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/4.0;
+    /// let f = x.sin_cos();
+    ///
+    /// let abs_difference_0 = (f.0 - x.sin()).abs();
+    /// let abs_difference_1 = (f.1 - x.cos()).abs();
+    ///
+    /// assert!(abs_difference_0 < 1e-10);
+    /// assert!(abs_difference_0 < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sin_cos(self) -> (f32, f32) {
+        (self.sin(), self.cos())
+    }
+
+    /// Returns `e^(self) - 1` in a way that is accurate even if the
+    /// number is close to zero.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 7.0;
+    ///
+    /// // e^(ln(7)) - 1
+    /// let abs_difference = (x.ln().exp_m1() - 6.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc", reason = "may be renamed")]
+    #[inline]
+    pub fn exp_m1(self) -> f32 {
+        unsafe { cmath::expm1f(self) }
+    }
+
+    /// Returns `ln(1+n)` (natural logarithm) more accurately than if
+    /// the operations were performed separately.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::E - 1.0;
+    ///
+    /// // ln(1 + (e - 1)) == ln(e) == 1
+    /// let abs_difference = (x.ln_1p() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc", reason = "may be renamed")]
+    #[inline]
+    pub fn ln_1p(self) -> f32 {
+        unsafe { cmath::log1pf(self) }
+    }
+
+    /// Hyperbolic sine function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let x = 1.0;
+    ///
+    /// let f = x.sinh();
+    /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
+    /// let g = (e*e - 1.0)/(2.0*e);
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sinh(self) -> f32 {
+        unsafe { cmath::sinhf(self) }
+    }
+
+    /// Hyperbolic cosine function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let x = 1.0;
+    /// let f = x.cosh();
+    /// // Solving cosh() at 1 gives this result
+    /// let g = (e*e + 1.0)/(2.0*e);
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// // Same result
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn cosh(self) -> f32 {
+        unsafe { cmath::coshf(self) }
+    }
+
+    /// Hyperbolic tangent function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let x = 1.0;
+    ///
+    /// let f = x.tanh();
+    /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
+    /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2));
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn tanh(self) -> f32 {
+        unsafe { cmath::tanhf(self) }
+    }
+
+    /// Inverse hyperbolic sine function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 1.0;
+    /// let f = x.sinh().asinh();
+    ///
+    /// let abs_difference = (f - x).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn asinh(self) -> f32 {
+        match self {
+            NEG_INFINITY => NEG_INFINITY,
+            x => (x + ((x * x) + 1.0).sqrt()).ln(),
+        }
+    }
+
+    /// Inverse hyperbolic cosine function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 1.0;
+    /// let f = x.cosh().acosh();
+    ///
+    /// let abs_difference = (f - x).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn acosh(self) -> f32 {
+        match self {
+            x if x < 1.0 => Float::nan(),
+            x => (x + ((x * x) - 1.0).sqrt()).ln(),
+        }
+    }
+
+    /// Inverse hyperbolic tangent function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let f = e.tanh().atanh();
+    ///
+    /// let abs_difference = (f - e).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn atanh(self) -> f32 {
+        0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
+    }
+}
+
 //
 // Section: String Conversions
 //
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index 95065b59678..f3978cae485 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -366,6 +366,1235 @@ impl Float for f64 {
     }
 }
 
+#[cfg(not(stage0))]
+#[cfg(not(test))]
+#[lang = "f64"]
+#[stable(feature = "rust1", since = "1.0.0")]
+impl f64 {
+    // inlined methods from `num::Float`
+    /// Returns the `NaN` value.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let nan: f32 = Float::nan();
+    ///
+    /// assert!(nan.is_nan());
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn nan() -> f64 { num::Float::nan() }
+
+    /// Returns the infinite value.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f32;
+    ///
+    /// let infinity: f32 = Float::infinity();
+    ///
+    /// assert!(infinity.is_infinite());
+    /// assert!(!infinity.is_finite());
+    /// assert!(infinity > f32::MAX);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn infinity() -> f64 { num::Float::infinity() }
+
+    /// Returns the negative infinite value.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f32;
+    ///
+    /// let neg_infinity: f32 = Float::neg_infinity();
+    ///
+    /// assert!(neg_infinity.is_infinite());
+    /// assert!(!neg_infinity.is_finite());
+    /// assert!(neg_infinity < f32::MIN);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn neg_infinity() -> f64 { num::Float::neg_infinity() }
+
+    /// Returns `0.0`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let inf: f32 = Float::infinity();
+    /// let zero: f32 = Float::zero();
+    /// let neg_zero: f32 = Float::neg_zero();
+    ///
+    /// assert_eq!(zero, neg_zero);
+    /// assert_eq!(7.0f32/inf, zero);
+    /// assert_eq!(zero * 10.0, zero);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn zero() -> f64 { num::Float::zero() }
+
+    /// Returns `-0.0`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let inf: f32 = Float::infinity();
+    /// let zero: f32 = Float::zero();
+    /// let neg_zero: f32 = Float::neg_zero();
+    ///
+    /// assert_eq!(zero, neg_zero);
+    /// assert_eq!(7.0f32/inf, zero);
+    /// assert_eq!(zero * 10.0, zero);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn neg_zero() -> f64 { num::Float::neg_zero() }
+
+    /// Returns `1.0`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let one: f32 = Float::one();
+    ///
+    /// assert_eq!(one, 1.0f32);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn one() -> f64 { num::Float::one() }
+
+    // FIXME (#5527): These should be associated constants
+
+    /// Deprecated: use `std::f32::MANTISSA_DIGITS` or `std::f64::MANTISSA_DIGITS`
+    /// instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `std::f32::MANTISSA_DIGITS` or \
+                           `std::f64::MANTISSA_DIGITS` as appropriate")]
+    #[allow(deprecated)]
+    #[inline]
+    pub fn mantissa_digits(unused_self: Option<f64>) -> uint {
+        num::Float::mantissa_digits(unused_self)
+    }
+
+    /// Deprecated: use `std::f32::DIGITS` or `std::f64::DIGITS` instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `std::f32::DIGITS` or `std::f64::DIGITS` as appropriate")]
+    #[allow(deprecated)]
+    #[inline]
+    pub fn digits(unused_self: Option<f64>) -> uint { num::Float::digits(unused_self) }
+
+    /// Deprecated: use `std::f32::EPSILON` or `std::f64::EPSILON` instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `std::f32::EPSILON` or `std::f64::EPSILON` as appropriate")]
+    #[allow(deprecated)]
+    #[inline]
+    pub fn epsilon() -> f64 { num::Float::epsilon() }
+
+    /// Deprecated: use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` as appropriate")]
+    #[allow(deprecated)]
+    #[inline]
+    pub fn min_exp(unused_self: Option<f64>) -> int { num::Float::min_exp(unused_self) }
+
+    /// Deprecated: use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` as appropriate")]
+    #[allow(deprecated)]
+    #[inline]
+    pub fn max_exp(unused_self: Option<f64>) -> int { num::Float::max_exp(unused_self) }
+
+    /// Deprecated: use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` as appropriate")]
+    #[allow(deprecated)]
+    #[inline]
+    pub fn min_10_exp(unused_self: Option<f64>) -> int { num::Float::min_10_exp(unused_self) }
+
+    /// Deprecated: use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` instead.
+    #[unstable(feature = "std_misc")]
+    #[deprecated(since = "1.0.0",
+                 reason = "use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` as appropriate")]
+    #[allow(deprecated)]
+    #[inline]
+    pub fn max_10_exp(unused_self: Option<f64>) -> int { num::Float::max_10_exp(unused_self) }
+
+    /// Returns the smallest finite value that this type can represent.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x: f64 = Float::min_value();
+    ///
+    /// assert_eq!(x, f64::MIN);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    #[allow(deprecated)]
+    pub fn min_value() -> f64 { num::Float::min_value() }
+
+    /// Returns the smallest normalized positive number that this type can represent.
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    #[allow(deprecated)]
+    pub fn min_pos_value(unused_self: Option<f64>) -> f64 { num::Float::min_pos_value(unused_self) }
+
+    /// Returns the largest finite value that this type can represent.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x: f64 = Float::max_value();
+    /// assert_eq!(x, f64::MAX);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    #[allow(deprecated)]
+    pub fn max_value() -> f64 { num::Float::max_value() }
+
+    /// Returns `true` if this value is `NaN` and false otherwise.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let nan = f64::NAN;
+    /// let f = 7.0;
+    ///
+    /// assert!(nan.is_nan());
+    /// assert!(!f.is_nan());
+    /// ```
+    #[unstable(feature = "std_misc", reason = "position is undecided")]
+    #[inline]
+    pub fn is_nan(self) -> bool { num::Float::is_nan(self) }
+
+    /// Returns `true` if this value is positive infinity or negative infinity and
+    /// false otherwise.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f32;
+    ///
+    /// let f = 7.0f32;
+    /// let inf: f32 = Float::infinity();
+    /// let neg_inf: f32 = Float::neg_infinity();
+    /// let nan: f32 = f32::NAN;
+    ///
+    /// assert!(!f.is_infinite());
+    /// assert!(!nan.is_infinite());
+    ///
+    /// assert!(inf.is_infinite());
+    /// assert!(neg_inf.is_infinite());
+    /// ```
+    #[unstable(feature = "std_misc", reason = "position is undecided")]
+    #[inline]
+    pub fn is_infinite(self) -> bool { num::Float::is_infinite(self) }
+
+    /// Returns `true` if this number is neither infinite nor `NaN`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f32;
+    ///
+    /// let f = 7.0f32;
+    /// let inf: f32 = Float::infinity();
+    /// let neg_inf: f32 = Float::neg_infinity();
+    /// let nan: f32 = f32::NAN;
+    ///
+    /// assert!(f.is_finite());
+    ///
+    /// assert!(!nan.is_finite());
+    /// assert!(!inf.is_finite());
+    /// assert!(!neg_inf.is_finite());
+    /// ```
+    #[unstable(feature = "std_misc", reason = "position is undecided")]
+    #[inline]
+    pub fn is_finite(self) -> bool { num::Float::is_finite(self) }
+
+    /// Returns `true` if the number is neither zero, infinite,
+    /// [subnormal][subnormal], or `NaN`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f32;
+    ///
+    /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
+    /// let max = f32::MAX;
+    /// let lower_than_min = 1.0e-40_f32;
+    /// let zero = 0.0f32;
+    ///
+    /// assert!(min.is_normal());
+    /// assert!(max.is_normal());
+    ///
+    /// assert!(!zero.is_normal());
+    /// assert!(!f32::NAN.is_normal());
+    /// assert!(!f32::INFINITY.is_normal());
+    /// // Values between `0` and `min` are Subnormal.
+    /// assert!(!lower_than_min.is_normal());
+    /// ```
+    /// [subnormal]: http://en.wikipedia.org/wiki/Denormal_number
+    #[unstable(feature = "std_misc", reason = "position is undecided")]
+    #[inline]
+    pub fn is_normal(self) -> bool { num::Float::is_normal(self) }
+
+    /// Returns the floating point category of the number. If only one property
+    /// is going to be tested, it is generally faster to use the specific
+    /// predicate instead.
+    ///
+    /// ```
+    /// use std::num::{Float, FpCategory};
+    /// use std::f32;
+    ///
+    /// let num = 12.4f32;
+    /// let inf = f32::INFINITY;
+    ///
+    /// assert_eq!(num.classify(), FpCategory::Normal);
+    /// assert_eq!(inf.classify(), FpCategory::Infinite);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn classify(self) -> FpCategory { num::Float::classify(self) }
+
+    /// Returns the mantissa, base 2 exponent, and sign as integers, respectively.
+    /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`.
+    /// The floating point encoding is documented in the [Reference][floating-point].
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let num = 2.0f32;
+    ///
+    /// // (8388608, -22, 1)
+    /// let (mantissa, exponent, sign) = num.integer_decode();
+    /// let sign_f = sign as f32;
+    /// let mantissa_f = mantissa as f32;
+    /// let exponent_f = num.powf(exponent as f32);
+    ///
+    /// // 1 * 8388608 * 2^(-22) == 2
+    /// let abs_difference = (sign_f * mantissa_f * exponent_f - num).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    /// [floating-point]: ../../../../../reference.html#machine-types
+    #[unstable(feature = "std_misc", reason = "signature is undecided")]
+    #[inline]
+    pub fn integer_decode(self) -> (u64, i16, i8) { num::Float::integer_decode(self) }
+
+    /// Returns the largest integer less than or equal to a number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 3.99;
+    /// let g = 3.0;
+    ///
+    /// assert_eq!(f.floor(), 3.0);
+    /// assert_eq!(g.floor(), 3.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn floor(self) -> f64 { num::Float::floor(self) }
+
+    /// Returns the smallest integer greater than or equal to a number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 3.01;
+    /// let g = 4.0;
+    ///
+    /// assert_eq!(f.ceil(), 4.0);
+    /// assert_eq!(g.ceil(), 4.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn ceil(self) -> f64 { num::Float::ceil(self) }
+
+    /// Returns the nearest integer to a number. Round half-way cases away from
+    /// `0.0`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 3.3;
+    /// let g = -3.3;
+    ///
+    /// assert_eq!(f.round(), 3.0);
+    /// assert_eq!(g.round(), -3.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn round(self) -> f64 { num::Float::round(self) }
+
+    /// Return the integer part of a number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 3.3;
+    /// let g = -3.7;
+    ///
+    /// assert_eq!(f.trunc(), 3.0);
+    /// assert_eq!(g.trunc(), -3.0);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn trunc(self) -> f64 { num::Float::trunc(self) }
+
+    /// Returns the fractional part of a number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 3.5;
+    /// let y = -3.5;
+    /// let abs_difference_x = (x.fract() - 0.5).abs();
+    /// let abs_difference_y = (y.fract() - (-0.5)).abs();
+    ///
+    /// assert!(abs_difference_x < 1e-10);
+    /// assert!(abs_difference_y < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn fract(self) -> f64 { num::Float::fract(self) }
+
+    /// Computes the absolute value of `self`. Returns `Float::nan()` if the
+    /// number is `Float::nan()`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = 3.5;
+    /// let y = -3.5;
+    ///
+    /// let abs_difference_x = (x.abs() - x).abs();
+    /// let abs_difference_y = (y.abs() - (-y)).abs();
+    ///
+    /// assert!(abs_difference_x < 1e-10);
+    /// assert!(abs_difference_y < 1e-10);
+    ///
+    /// assert!(f64::NAN.abs().is_nan());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn abs(self) -> f64 { num::Float::abs(self) }
+
+    /// Returns a number that represents the sign of `self`.
+    ///
+    /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()`
+    /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()`
+    /// - `Float::nan()` if the number is `Float::nan()`
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let f = 3.5;
+    ///
+    /// assert_eq!(f.signum(), 1.0);
+    /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0);
+    ///
+    /// assert!(f64::NAN.signum().is_nan());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn signum(self) -> f64 { num::Float::signum(self) }
+
+    /// Returns `true` if `self` is positive, including `+0.0` and
+    /// `Float::infinity()`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let nan: f64 = f64::NAN;
+    ///
+    /// let f = 7.0;
+    /// let g = -7.0;
+    ///
+    /// assert!(f.is_positive());
+    /// assert!(!g.is_positive());
+    /// // Requires both tests to determine if is `NaN`
+    /// assert!(!nan.is_positive() && !nan.is_negative());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_positive(self) -> bool { num::Float::is_positive(self) }
+
+    /// Returns `true` if `self` is negative, including `-0.0` and
+    /// `Float::neg_infinity()`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let nan = f64::NAN;
+    ///
+    /// let f = 7.0;
+    /// let g = -7.0;
+    ///
+    /// assert!(!f.is_negative());
+    /// assert!(g.is_negative());
+    /// // Requires both tests to determine if is `NaN`.
+    /// assert!(!nan.is_positive() && !nan.is_negative());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn is_negative(self) -> bool { num::Float::is_negative(self) }
+
+    /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
+    /// error. This produces a more accurate result with better performance than
+    /// a separate multiplication operation followed by an add.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let m = 10.0;
+    /// let x = 4.0;
+    /// let b = 60.0;
+    ///
+    /// // 100.0
+    /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn mul_add(self, a: f64, b: f64) -> f64 { num::Float::mul_add(self, a, b) }
+
+    /// Take the reciprocal (inverse) of a number, `1/x`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 2.0;
+    /// let abs_difference = (x.recip() - (1.0/x)).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn recip(self) -> f64 { num::Float::recip(self) }
+
+    /// Raise a number to an integer power.
+    ///
+    /// Using this function is generally faster than using `powf`
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 2.0;
+    /// let abs_difference = (x.powi(2) - x*x).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn powi(self, n: i32) -> f64 { num::Float::powi(self, n) }
+
+    /// Raise a number to a floating point power.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 2.0;
+    /// let abs_difference = (x.powf(2.0) - x*x).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn powf(self, n: f64) -> f64 { num::Float::powf(self, n) }
+
+    /// Take the square root of a number.
+    ///
+    /// Returns NaN if `self` is a negative number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let positive = 4.0;
+    /// let negative = -4.0;
+    ///
+    /// let abs_difference = (positive.sqrt() - 2.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// assert!(negative.sqrt().is_nan());
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sqrt(self) -> f64 { num::Float::sqrt(self) }
+
+    /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 4.0;
+    ///
+    /// let abs_difference = (f.rsqrt() - 0.5).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn rsqrt(self) -> f64 { num::Float::rsqrt(self) }
+
+    /// Returns `e^(self)`, (the exponential function).
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let one = 1.0;
+    /// // e^1
+    /// let e = one.exp();
+    ///
+    /// // ln(e) - 1 == 0
+    /// let abs_difference = (e.ln() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn exp(self) -> f64 { num::Float::exp(self) }
+
+    /// Returns `2^(self)`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 2.0;
+    ///
+    /// // 2^2 - 4 == 0
+    /// let abs_difference = (f.exp2() - 4.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn exp2(self) -> f64 { num::Float::exp2(self) }
+
+    /// Returns the natural logarithm of the number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let one = 1.0;
+    /// // e^1
+    /// let e = one.exp();
+    ///
+    /// // ln(e) - 1 == 0
+    /// let abs_difference = (e.ln() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn ln(self) -> f64 { num::Float::ln(self) }
+
+    /// Returns the logarithm of the number with respect to an arbitrary base.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let ten = 10.0;
+    /// let two = 2.0;
+    ///
+    /// // log10(10) - 1 == 0
+    /// let abs_difference_10 = (ten.log(10.0) - 1.0).abs();
+    ///
+    /// // log2(2) - 1 == 0
+    /// let abs_difference_2 = (two.log(2.0) - 1.0).abs();
+    ///
+    /// assert!(abs_difference_10 < 1e-10);
+    /// assert!(abs_difference_2 < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn log(self, base: f64) -> f64 { num::Float::log(self, base) }
+
+    /// Returns the base 2 logarithm of the number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let two = 2.0;
+    ///
+    /// // log2(2) - 1 == 0
+    /// let abs_difference = (two.log2() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn log2(self) -> f64 { num::Float::log2(self) }
+
+    /// Returns the base 10 logarithm of the number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let ten = 10.0;
+    ///
+    /// // log10(10) - 1 == 0
+    /// let abs_difference = (ten.log10() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn log10(self) -> f64 { num::Float::log10(self) }
+
+    /// Convert radians to degrees.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64::consts;
+    ///
+    /// let angle = consts::PI;
+    ///
+    /// let abs_difference = (angle.to_degrees() - 180.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc", reason = "desirability is unclear")]
+    #[inline]
+    pub fn to_degrees(self) -> f64 { num::Float::to_degrees(self) }
+
+    /// Convert degrees to radians.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64::consts;
+    ///
+    /// let angle = 180.0;
+    ///
+    /// let abs_difference = (angle.to_radians() - consts::PI).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc", reason = "desirability is unclear")]
+    #[inline]
+    pub fn to_radians(self) -> f64 { num::Float::to_radians(self) }
+
+    /// Constructs a floating point number of `x*2^exp`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// // 3*2^2 - 12 == 0
+    /// let abs_difference = (Float::ldexp(3.0, 2) - 12.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "pending integer conventions")]
+    #[inline]
+    pub fn ldexp(x: f64, exp: int) -> f64 {
+        unsafe { cmath::ldexp(x, exp as c_int) }
+    }
+
+    /// Breaks the number into a normalized fraction and a base-2 exponent,
+    /// satisfying:
+    ///
+    ///  * `self = x * 2^exp`
+    ///  * `0.5 <= abs(x) < 1.0`
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 4.0;
+    ///
+    /// // (1/2)*2^3 -> 1 * 8/2 -> 4.0
+    /// let f = x.frexp();
+    /// let abs_difference_0 = (f.0 - 0.5).abs();
+    /// let abs_difference_1 = (f.1 as f64 - 3.0).abs();
+    ///
+    /// assert!(abs_difference_0 < 1e-10);
+    /// assert!(abs_difference_1 < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "pending integer conventions")]
+    #[inline]
+    pub fn frexp(self) -> (f64, int) {
+        unsafe {
+            let mut exp = 0;
+            let x = cmath::frexp(self, &mut exp);
+            (x, exp as int)
+        }
+    }
+
+    /// Returns the next representable floating-point value in the direction of
+    /// `other`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 1.0f32;
+    ///
+    /// let abs_diff = (x.next_after(2.0) - 1.00000011920928955078125_f32).abs();
+    ///
+    /// assert!(abs_diff < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn next_after(self, other: f64) -> f64 {
+        unsafe { cmath::nextafter(self, other) }
+    }
+
+    /// Returns the maximum of the two numbers.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 1.0;
+    /// let y = 2.0;
+    ///
+    /// assert_eq!(x.max(y), y);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn max(self, other: f64) -> f64 {
+        unsafe { cmath::fmax(self, other) }
+    }
+
+    /// Returns the minimum of the two numbers.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 1.0;
+    /// let y = 2.0;
+    ///
+    /// assert_eq!(x.min(y), x);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn min(self, other: f64) -> f64 {
+        unsafe { cmath::fmin(self, other) }
+    }
+
+    /// The positive difference of two numbers.
+    ///
+    /// * If `self <= other`: `0:0`
+    /// * Else: `self - other`
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 3.0;
+    /// let y = -3.0;
+    ///
+    /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs();
+    /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs();
+    ///
+    /// assert!(abs_difference_x < 1e-10);
+    /// assert!(abs_difference_y < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc", reason = "may be renamed")]
+    #[inline]
+    pub fn abs_sub(self, other: f64) -> f64 {
+        unsafe { cmath::fdim(self, other) }
+    }
+
+    /// Take the cubic root of a number.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 8.0;
+    ///
+    /// // x^(1/3) - 2 == 0
+    /// let abs_difference = (x.cbrt() - 2.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc", reason = "may be renamed")]
+    #[inline]
+    pub fn cbrt(self) -> f64 {
+        unsafe { cmath::cbrt(self) }
+    }
+
+    /// Calculate the length of the hypotenuse of a right-angle triangle given
+    /// legs of length `x` and `y`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 2.0;
+    /// let y = 3.0;
+    ///
+    /// // sqrt(x^2 + y^2)
+    /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc",
+               reason = "unsure about its place in the world")]
+    #[inline]
+    pub fn hypot(self, other: f64) -> f64 {
+        unsafe { cmath::hypot(self, other) }
+    }
+
+    /// Computes the sine of a number (in radians).
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/2.0;
+    ///
+    /// let abs_difference = (x.sin() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sin(self) -> f64 {
+        unsafe { intrinsics::sinf64(self) }
+    }
+
+    /// Computes the cosine of a number (in radians).
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = 2.0*f64::consts::PI;
+    ///
+    /// let abs_difference = (x.cos() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn cos(self) -> f64 {
+        unsafe { intrinsics::cosf64(self) }
+    }
+
+    /// Computes the tangent of a number (in radians).
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/4.0;
+    /// let abs_difference = (x.tan() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-14);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn tan(self) -> f64 {
+        unsafe { cmath::tan(self) }
+    }
+
+    /// Computes the arcsine of a number. Return value is in radians in
+    /// the range [-pi/2, pi/2] or NaN if the number is outside the range
+    /// [-1, 1].
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let f = f64::consts::PI / 2.0;
+    ///
+    /// // asin(sin(pi/2))
+    /// let abs_difference = (f.sin().asin() - f64::consts::PI / 2.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn asin(self) -> f64 {
+        unsafe { cmath::asin(self) }
+    }
+
+    /// Computes the arccosine of a number. Return value is in radians in
+    /// the range [0, pi] or NaN if the number is outside the range
+    /// [-1, 1].
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let f = f64::consts::PI / 4.0;
+    ///
+    /// // acos(cos(pi/4))
+    /// let abs_difference = (f.cos().acos() - f64::consts::PI / 4.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn acos(self) -> f64 {
+        unsafe { cmath::acos(self) }
+    }
+
+    /// Computes the arctangent of a number. Return value is in radians in the
+    /// range [-pi/2, pi/2];
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let f = 1.0;
+    ///
+    /// // atan(tan(1))
+    /// let abs_difference = (f.tan().atan() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn atan(self) -> f64 {
+        unsafe { cmath::atan(self) }
+    }
+
+    /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`).
+    ///
+    /// * `x = 0`, `y = 0`: `0`
+    /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
+    /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
+    /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let pi = f64::consts::PI;
+    /// // All angles from horizontal right (+x)
+    /// // 45 deg counter-clockwise
+    /// let x1 = 3.0;
+    /// let y1 = -3.0;
+    ///
+    /// // 135 deg clockwise
+    /// let x2 = -3.0;
+    /// let y2 = 3.0;
+    ///
+    /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs();
+    /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs();
+    ///
+    /// assert!(abs_difference_1 < 1e-10);
+    /// assert!(abs_difference_2 < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn atan2(self, other: f64) -> f64 {
+        unsafe { cmath::atan2(self, other) }
+    }
+
+    /// Simultaneously computes the sine and cosine of the number, `x`. Returns
+    /// `(sin(x), cos(x))`.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::PI/4.0;
+    /// let f = x.sin_cos();
+    ///
+    /// let abs_difference_0 = (f.0 - x.sin()).abs();
+    /// let abs_difference_1 = (f.1 - x.cos()).abs();
+    ///
+    /// assert!(abs_difference_0 < 1e-10);
+    /// assert!(abs_difference_0 < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sin_cos(self) -> (f64, f64) {
+        (self.sin(), self.cos())
+    }
+
+    /// Returns `e^(self) - 1` in a way that is accurate even if the
+    /// number is close to zero.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 7.0;
+    ///
+    /// // e^(ln(7)) - 1
+    /// let abs_difference = (x.ln().exp_m1() - 6.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc", reason = "may be renamed")]
+    #[inline]
+    pub fn exp_m1(self) -> f64 {
+        unsafe { cmath::expm1(self) }
+    }
+
+    /// Returns `ln(1+n)` (natural logarithm) more accurately than if
+    /// the operations were performed separately.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let x = f64::consts::E - 1.0;
+    ///
+    /// // ln(1 + (e - 1)) == ln(e) == 1
+    /// let abs_difference = (x.ln_1p() - 1.0).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[unstable(feature = "std_misc", reason = "may be renamed")]
+    #[inline]
+    pub fn ln_1p(self) -> f64 {
+        unsafe { cmath::log1p(self) }
+    }
+
+    /// Hyperbolic sine function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let x = 1.0;
+    ///
+    /// let f = x.sinh();
+    /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
+    /// let g = (e*e - 1.0)/(2.0*e);
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// assert!(abs_difference < 1e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn sinh(self) -> f64 {
+        unsafe { cmath::sinh(self) }
+    }
+
+    /// Hyperbolic cosine function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let x = 1.0;
+    /// let f = x.cosh();
+    /// // Solving cosh() at 1 gives this result
+    /// let g = (e*e + 1.0)/(2.0*e);
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// // Same result
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn cosh(self) -> f64 {
+        unsafe { cmath::cosh(self) }
+    }
+
+    /// Hyperbolic tangent function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let x = 1.0;
+    ///
+    /// let f = x.tanh();
+    /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
+    /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2));
+    /// let abs_difference = (f - g).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn tanh(self) -> f64 {
+        unsafe { cmath::tanh(self) }
+    }
+
+    /// Inverse hyperbolic sine function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 1.0;
+    /// let f = x.sinh().asinh();
+    ///
+    /// let abs_difference = (f - x).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn asinh(self) -> f64 {
+        match self {
+            NEG_INFINITY => NEG_INFINITY,
+            x => (x + ((x * x) + 1.0).sqrt()).ln(),
+        }
+    }
+
+    /// Inverse hyperbolic cosine function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    ///
+    /// let x = 1.0;
+    /// let f = x.cosh().acosh();
+    ///
+    /// let abs_difference = (f - x).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn acosh(self) -> f64 {
+        match self {
+            x if x < 1.0 => Float::nan(),
+            x => (x + ((x * x) - 1.0).sqrt()).ln(),
+        }
+    }
+
+    /// Inverse hyperbolic tangent function.
+    ///
+    /// ```
+    /// use std::num::Float;
+    /// use std::f64;
+    ///
+    /// let e = f64::consts::E;
+    /// let f = e.tanh().atanh();
+    ///
+    /// let abs_difference = (f - e).abs();
+    ///
+    /// assert!(abs_difference < 1.0e-10);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[inline]
+    pub fn atanh(self) -> f64 {
+        0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
+    }
+}
+
 //
 // Section: String Conversions
 //
diff --git a/src/libstd/num/float_macros.rs b/src/libstd/num/float_macros.rs
index 2b730cd6f9a..ece7af9c152 100644
--- a/src/libstd/num/float_macros.rs
+++ b/src/libstd/num/float_macros.rs
@@ -11,6 +11,7 @@
 #![unstable(feature = "std_misc")]
 #![doc(hidden)]
 
+#[cfg(stage0)]
 macro_rules! assert_approx_eq {
     ($a:expr, $b:expr) => ({
         use num::Float;
@@ -19,3 +20,12 @@ macro_rules! assert_approx_eq {
                 "{} is not approximately equal to {}", *a, *b);
     })
 }
+
+#[cfg(not(stage0))]
+macro_rules! assert_approx_eq {
+    ($a:expr, $b:expr) => ({
+        let (a, b) = (&$a, &$b);
+        assert!((*a - *b).abs() < 1.0e-6,
+                "{} is not approximately equal to {}", *a, *b);
+    })
+}
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index 35d973d2d4e..599f3f02a8b 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -23,7 +23,10 @@ use marker::Copy;
 use clone::Clone;
 use cmp::{PartialOrd, PartialEq};
 
+#[cfg(stage0)]
 pub use core::num::{Int, SignedInt, UnsignedInt};
+#[cfg(not(stage0))]
+pub use core::num::{Int, SignedInt};
 pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive};
 pub use core::num::{from_int, from_i8, from_i16, from_i32, from_i64};
 pub use core::num::{from_uint, from_u8, from_u16, from_u32, from_u64};
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index 5fdd42dbc7a..ea1e05df85f 100644
--- a/src/libstd/num/strconv.rs
+++ b/src/libstd/num/strconv.rs
@@ -16,11 +16,16 @@ use self::ExponentFormat::*;
 use self::SignificantDigits::*;
 use self::SignFormat::*;
 
+#[cfg(stage0)]
 use char::{self, CharExt};
+#[cfg(not(stage0))]
+use char;
 use num::{self, Int, Float, ToPrimitive};
 use num::FpCategory as Fp;
 use ops::FnMut;
+#[cfg(stage0)]
 use slice::SliceExt;
+#[cfg(stage0)]
 use str::StrExt;
 use string::String;
 use vec::Vec;
diff --git a/src/libstd/old_io/buffered.rs b/src/libstd/old_io/buffered.rs
index 9be7fcca1e8..82a48a72499 100644
--- a/src/libstd/old_io/buffered.rs
+++ b/src/libstd/old_io/buffered.rs
@@ -20,6 +20,7 @@ use ops::Drop;
 use option::Option;
 use option::Option::{Some, None};
 use result::Result::Ok;
+#[cfg(stage0)]
 use slice::{SliceExt};
 use slice;
 use vec::Vec;
diff --git a/src/libstd/old_io/comm_adapters.rs b/src/libstd/old_io/comm_adapters.rs
index 72ba653a986..33928d638e0 100644
--- a/src/libstd/old_io/comm_adapters.rs
+++ b/src/libstd/old_io/comm_adapters.rs
@@ -14,7 +14,10 @@ use sync::mpsc::{Sender, Receiver};
 use old_io;
 use option::Option::{None, Some};
 use result::Result::{Ok, Err};
+#[cfg(stage0)]
 use slice::{bytes, SliceExt};
+#[cfg(not(stage0))]
+use slice::bytes;
 use super::{Buffer, Reader, Writer, IoResult};
 use vec::Vec;
 
diff --git a/src/libstd/old_io/extensions.rs b/src/libstd/old_io/extensions.rs
index ec30121d78d..a81275952c5 100644
--- a/src/libstd/old_io/extensions.rs
+++ b/src/libstd/old_io/extensions.rs
@@ -26,8 +26,10 @@ use num::Int;
 use ops::FnOnce;
 use option::Option;
 use option::Option::{Some, None};
+#[cfg(stage0)]
 use ptr::PtrExt;
 use result::Result::{Ok, Err};
+#[cfg(stage0)]
 use slice::SliceExt;
 
 /// An iterator that reads a single byte on each iteration,
@@ -162,6 +164,7 @@ pub fn u64_to_be_bytes<T, F>(n: u64, size: uint, f: F) -> T where
 ///           32-bit value is parsed.
 pub fn u64_from_be_bytes(data: &[u8], start: uint, size: uint) -> u64 {
     use ptr::{copy_nonoverlapping_memory};
+    #[cfg(stage0)]
     use slice::SliceExt;
 
     assert!(size <= 8);
diff --git a/src/libstd/old_io/fs.rs b/src/libstd/old_io/fs.rs
index 80a09b3bd0b..ff3af380b7d 100644
--- a/src/libstd/old_io/fs.rs
+++ b/src/libstd/old_io/fs.rs
@@ -64,6 +64,7 @@ use option::Option::{Some, None};
 use old_path::{Path, GenericPath};
 use old_path;
 use result::Result::{Err, Ok};
+#[cfg(stage0)]
 use slice::SliceExt;
 use string::String;
 use vec::Vec;
diff --git a/src/libstd/old_io/mem.rs b/src/libstd/old_io/mem.rs
index 80d4b013fff..72774334c13 100644
--- a/src/libstd/old_io/mem.rs
+++ b/src/libstd/old_io/mem.rs
@@ -17,7 +17,10 @@ use option::Option::None;
 use result::Result::{Err, Ok};
 use old_io;
 use old_io::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, IoResult};
+#[cfg(stage0)]
 use slice::{self, SliceExt};
+#[cfg(not(stage0))]
+use slice;
 use vec::Vec;
 
 const BUF_CAPACITY: uint = 128;
@@ -395,7 +398,7 @@ impl<'a> Buffer for BufReader<'a> {
 mod test {
     extern crate "test" as test_crate;
     use old_io::{SeekSet, SeekCur, SeekEnd, Reader, Writer, Seek};
-    use prelude::v1::{Ok, Err, range,  Vec, Buffer,  AsSlice, SliceExt};
+    use prelude::v1::{Ok, Err, range,  Vec, Buffer,  AsSlice};
     use prelude::v1::IteratorExt;
     use old_io;
     use iter::repeat;
diff --git a/src/libstd/old_io/mod.rs b/src/libstd/old_io/mod.rs
index 9b1de45fdf8..15a80e34451 100644
--- a/src/libstd/old_io/mod.rs
+++ b/src/libstd/old_io/mod.rs
@@ -251,6 +251,7 @@ pub use self::FileMode::*;
 pub use self::FileAccess::*;
 pub use self::IoErrorKind::*;
 
+#[cfg(stage0)]
 use char::CharExt;
 use default::Default;
 use error::Error;
@@ -267,7 +268,9 @@ use boxed::Box;
 use result::Result;
 use result::Result::{Ok, Err};
 use sys;
+#[cfg(stage0)]
 use slice::SliceExt;
+#[cfg(stage0)]
 use str::StrExt;
 use str;
 use string::String;
@@ -931,15 +934,16 @@ impl<'a> Reader for &'a mut (Reader+'a) {
 // Private function here because we aren't sure if we want to expose this as
 // API yet. If so, it should be a method on Vec.
 unsafe fn slice_vec_capacity<'a, T>(v: &'a mut Vec<T>, start: uint, end: uint) -> &'a mut [T] {
-    use raw::Slice;
+    use slice;
+    #[cfg(stage0)]
     use ptr::PtrExt;
 
     assert!(start <= end);
     assert!(end <= v.capacity());
-    transmute(Slice {
-        data: v.as_ptr().offset(start as int),
-        len: end - start
-    })
+    slice::from_raw_parts_mut(
+        v.as_mut_ptr().offset(start as int),
+        end - start
+    )
 }
 
 /// A `RefReader` is a struct implementing `Reader` which contains a reference
@@ -1849,7 +1853,7 @@ impl fmt::Display for FilePermission {
 mod tests {
     use self::BadReaderBehavior::*;
     use super::{IoResult, Reader, MemReader, NoProgress, InvalidInput, Writer};
-    use prelude::v1::{Ok, Vec, Buffer, SliceExt};
+    use prelude::v1::{Ok, Vec, Buffer};
     use usize;
 
     #[derive(Clone, PartialEq, Debug)]
diff --git a/src/libstd/old_io/net/ip.rs b/src/libstd/old_io/net/ip.rs
index 6e2f491262d..2dda2c1277a 100644
--- a/src/libstd/old_io/net/ip.rs
+++ b/src/libstd/old_io/net/ip.rs
@@ -26,8 +26,12 @@ use ops::{FnOnce, FnMut};
 use option::Option;
 use option::Option::{None, Some};
 use result::Result::{self, Ok, Err};
+#[cfg(stage0)]
 use slice::SliceExt;
+#[cfg(stage0)]
 use str::{FromStr, StrExt};
+#[cfg(not(stage0))]
+use str::FromStr;
 use vec::Vec;
 
 pub type Port = u16;
diff --git a/src/libstd/old_io/process.rs b/src/libstd/old_io/process.rs
index cabba8e358a..e5f23643372 100644
--- a/src/libstd/old_io/process.rs
+++ b/src/libstd/old_io/process.rs
@@ -761,7 +761,7 @@ mod tests {
     use old_io::{Truncate, Write, TimedOut, timer, process, FileNotFound};
     use prelude::v1::{Ok, Err, range, drop, Some, None, Vec};
     use prelude::v1::{Path, String, Reader, Writer, Clone};
-    use prelude::v1::{SliceExt, Str, StrExt, AsSlice, ToString, GenericPath};
+    use prelude::v1::{Str, AsSlice, ToString, GenericPath};
     use old_io::fs::PathExtensions;
     use old_io::timer::*;
     use rt::running_on_valgrind;
diff --git a/src/libstd/old_io/stdio.rs b/src/libstd/old_io/stdio.rs
index 784d5faec88..b699b93f2b8 100644
--- a/src/libstd/old_io/stdio.rs
+++ b/src/libstd/old_io/stdio.rs
@@ -43,7 +43,9 @@ use ops::{Deref, DerefMut, FnOnce};
 use ptr;
 use result::Result::{Ok, Err};
 use rt;
+#[cfg(stage0)]
 use slice::SliceExt;
+#[cfg(stage0)]
 use str::StrExt;
 use string::String;
 use sys::{fs, tty};
@@ -535,18 +537,4 @@ mod tests {
         stdout();
         stderr();
     }
-
-    #[test]
-    fn capture_stdout() {
-        use old_io::{ChanReader, ChanWriter};
-
-        let (tx, rx) = channel();
-        let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
-        // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
-        let _t = thread::spawn(move|| {
-            set_stdout(Box::new(w));
-            println!("hello!");
-        });
-        assert_eq!(r.read_to_string().unwrap(), "hello!\n");
-    }
 }
diff --git a/src/libstd/old_io/tempfile.rs b/src/libstd/old_io/tempfile.rs
index 76753dca52e..b34804fce61 100644
--- a/src/libstd/old_io/tempfile.rs
+++ b/src/libstd/old_io/tempfile.rs
@@ -21,6 +21,7 @@ use option::Option;
 use old_path::{Path, GenericPath};
 use rand::{Rng, thread_rng};
 use result::Result::{Ok, Err};
+#[cfg(stage0)]
 use str::StrExt;
 use string::String;
 
diff --git a/src/libstd/old_path/mod.rs b/src/libstd/old_path/mod.rs
index 01eec230d21..37875658ae0 100644
--- a/src/libstd/old_path/mod.rs
+++ b/src/libstd/old_path/mod.rs
@@ -72,8 +72,10 @@ use iter::IteratorExt;
 use option::Option;
 use option::Option::{None, Some};
 use str;
+#[cfg(stage0)]
 use str::StrExt;
 use string::{String, CowString};
+#[cfg(stage0)]
 use slice::SliceExt;
 use vec::Vec;
 
diff --git a/src/libstd/old_path/posix.rs b/src/libstd/old_path/posix.rs
index 8d5765e1ffe..e35623d7b1a 100644
--- a/src/libstd/old_path/posix.rs
+++ b/src/libstd/old_path/posix.rs
@@ -20,8 +20,14 @@ use iter::{Iterator, IteratorExt, Map};
 use marker::Sized;
 use option::Option::{self, Some, None};
 use result::Result::{self, Ok, Err};
+#[cfg(stage0)]
 use slice::{AsSlice, Split, SliceExt, SliceConcatExt};
+#[cfg(not(stage0))]
+use slice::{AsSlice, Split, SliceConcatExt};
+#[cfg(stage0)]
 use str::{self, FromStr, StrExt};
+#[cfg(not(stage0))]
+use str::{self, FromStr};
 use vec::Vec;
 
 use super::{BytesContainer, GenericPath, GenericPathUnsafe};
@@ -447,8 +453,8 @@ mod tests {
     use iter::IteratorExt;
     use option::Option::{self, Some, None};
     use old_path::GenericPath;
-    use slice::{AsSlice, SliceExt};
-    use str::{self, Str, StrExt};
+    use slice::AsSlice;
+    use str::{self, Str};
     use string::ToString;
     use vec::Vec;
 
diff --git a/src/libstd/old_path/windows.rs b/src/libstd/old_path/windows.rs
index 838710b1aec..ff4f083333b 100644
--- a/src/libstd/old_path/windows.rs
+++ b/src/libstd/old_path/windows.rs
@@ -15,6 +15,7 @@
 use self::PathPrefix::*;
 
 use ascii::AsciiExt;
+#[cfg(stage0)]
 use char::CharExt;
 use clone::Clone;
 use cmp::{Ordering, Eq, Ord, PartialEq, PartialOrd};
@@ -26,8 +27,14 @@ use iter::{Iterator, IteratorExt, Map, repeat};
 use mem;
 use option::Option::{self, Some, None};
 use result::Result::{self, Ok, Err};
+#[cfg(stage0)]
 use slice::{SliceExt, SliceConcatExt};
+#[cfg(not(stage0))]
+use slice::SliceConcatExt;
+#[cfg(stage0)]
 use str::{SplitTerminator, FromStr, StrExt};
+#[cfg(not(stage0))]
+use str::{SplitTerminator, FromStr};
 use string::{String, ToString};
 use vec::Vec;
 
@@ -1126,7 +1133,7 @@ mod tests {
     use iter::IteratorExt;
     use option::Option::{self, Some, None};
     use old_path::GenericPath;
-    use slice::{AsSlice, SliceExt};
+    use slice::AsSlice;
     use str::Str;
     use string::ToString;
     use vec::Vec;
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index ffe762450d0..46233a46ee5 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -52,12 +52,19 @@ use option::Option::{Some, None};
 use option::Option;
 use old_path::{Path, GenericPath, BytesContainer};
 use path::{self, PathBuf};
+#[cfg(stage0)]
 use ptr::PtrExt;
 use ptr;
 use result::Result::{Err, Ok};
 use result::Result;
+#[cfg(stage0)]
 use slice::{AsSlice, SliceExt};
+#[cfg(not(stage0))]
+use slice::AsSlice;
+#[cfg(stage0)]
 use str::{Str, StrExt};
+#[cfg(not(stage0))]
+use str::Str;
 use str;
 use string::{String, ToString};
 use sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT, Ordering};
@@ -210,7 +217,7 @@ pub fn getenv_as_bytes(n: &str) -> Option<Vec<u8>> {
 
 #[cfg(unix)]
 fn byteify(s: OsString) -> Vec<u8> {
-    use os::unix::*;
+    use os::unix::prelude::*;
     s.into_vec()
 }
 #[cfg(windows)]
@@ -238,7 +245,7 @@ fn byteify(s: OsString) -> Vec<u8> {
 pub fn setenv<T: BytesContainer>(n: &str, v: T) {
     #[cfg(unix)]
     fn _setenv(n: &str, v: &[u8]) {
-        use os::unix::*;
+        use os::unix::prelude::*;
         let v: OsString = OsStringExt::from_vec(v.to_vec());
         env::set_var(n, &v)
     }
@@ -591,7 +598,6 @@ pub fn get_exit_status() -> int {
 unsafe fn load_argc_and_argv(argc: int,
                              argv: *const *const c_char) -> Vec<Vec<u8>> {
     use ffi::CStr;
-    use iter::range;
 
     (0..argc).map(|i| {
         CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec()
@@ -1709,13 +1715,13 @@ mod tests {
 
         #[cfg(not(windows))]
         fn get_fd(file: &File) -> libc::c_int {
-            use os::unix::AsRawFd;
+            use os::unix::prelude::*;
             file.as_raw_fd()
         }
 
         #[cfg(windows)]
         fn get_fd(file: &File) -> libc::HANDLE {
-            use os::windows::AsRawHandle;
+            use os::windows::prelude::*;
             file.as_raw_handle()
         }
 
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 536c7fbf66f..2d97d651366 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -86,8 +86,8 @@
 //!
 //! * Occurrences of `.` are normalized away, *except* if they are at
 //! the beginning of the path (in which case they are often meaningful
-//! in terms of path searching). So, fore xample, `a/./b`, `a/b/`,
-//! `/a/b/.` and `a/b` all ahve components `a` and `b`, but `./a/b`
+//! in terms of path searching). So, for example, `a/./b`, `a/b/`,
+//! `/a/b/.` and `a/b` all have components `a` and `b`, but `./a/b`
 //! has a leading current directory component.
 //!
 //! No other normalization takes place by default. In particular,
@@ -159,6 +159,7 @@ mod platform {
     use core::prelude::*;
     use ascii::*;
 
+    #[cfg(stage0)]
     use char::CharExt as UnicodeCharExt;
     use super::{os_str_as_u8_slice, u8_slice_as_os_str, Prefix};
     use ffi::OsStr;
@@ -877,7 +878,7 @@ impl PathBuf {
     /// Allocate a `PathBuf` with initial contents given by the
     /// argument.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new<S: ?Sized + AsOsStr>(s: &S) -> PathBuf {
+    pub fn new<S: AsOsStr>(s: S) -> PathBuf {
         PathBuf { inner: s.as_os_str().to_os_string() }
     }
 
@@ -891,7 +892,7 @@ impl PathBuf {
     ///   replaces everything except for the prefix (if any) of `self`.
     /// * if `path` has a prefix but no root, it replaces `self.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn push<P: ?Sized>(&mut self, path: &P) where P: AsPath {
+    pub fn push<P: AsPath>(&mut self, path: P) {
         let path = path.as_path();
 
         // in general, a separator is needed if the rightmost byte is not a separator
@@ -959,7 +960,7 @@ impl PathBuf {
     /// assert!(buf == PathBuf::new("/baz.txt"));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn set_file_name<S: ?Sized>(&mut self, file_name: &S) where S: AsOsStr {
+    pub fn set_file_name<S: AsOsStr>(&mut self, file_name: S) {
         if self.file_name().is_some() {
             let popped = self.pop();
             debug_assert!(popped);
@@ -974,7 +975,7 @@ impl PathBuf {
     /// Otherwise, returns `true`; if `self.extension()` is `None`, the extension
     /// is added; otherwise it is replaced.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn set_extension<S: ?Sized + AsOsStr>(&mut self, extension: &S) -> bool {
+    pub fn set_extension<S: AsOsStr>(&mut self, extension: S) -> bool {
         if self.file_name().is_none() { return false; }
 
         let mut stem = match self.file_stem() {
@@ -1000,8 +1001,8 @@ impl PathBuf {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, P: ?Sized + 'a> iter::FromIterator<&'a P> for PathBuf where P: AsPath {
-    fn from_iter<I: IntoIterator<Item = &'a P>>(iter: I) -> PathBuf {
+impl<P: AsPath> iter::FromIterator<P> for PathBuf {
+    fn from_iter<I: IntoIterator<Item = P>>(iter: I) -> PathBuf {
         let mut buf = PathBuf::new("");
         buf.extend(iter);
         buf
@@ -1009,8 +1010,8 @@ impl<'a, P: ?Sized + 'a> iter::FromIterator<&'a P> for PathBuf where P: AsPath {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, P: ?Sized + 'a> iter::Extend<&'a P> for PathBuf where P: AsPath {
-    fn extend<I: IntoIterator<Item = &'a P>>(&mut self, iter: I) {
+impl<P: AsPath> iter::Extend<P> for PathBuf {
+    fn extend<I: IntoIterator<Item = P>>(&mut self, iter: I) {
         for p in iter {
             self.push(p)
         }
@@ -1253,13 +1254,13 @@ impl Path {
 
     /// Determines whether `base` is a prefix of `self`.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn starts_with<P: ?Sized>(&self, base: &P) -> bool where P: AsPath {
+    pub fn starts_with<P: AsPath>(&self, base: P) -> bool {
         iter_after(self.components(), base.as_path().components()).is_some()
     }
 
     /// Determines whether `child` is a suffix of `self`.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn ends_with<P: ?Sized>(&self, child: &P) -> bool where P: AsPath {
+    pub fn ends_with<P: AsPath>(&self, child: P) -> bool {
         iter_after(self.components().rev(), child.as_path().components().rev()).is_some()
     }
 
@@ -1293,7 +1294,7 @@ impl Path {
     ///
     /// See `PathBuf::push` for more details on what it means to adjoin a path.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn join<P: ?Sized>(&self, path: &P) -> PathBuf where P: AsPath {
+    pub fn join<P: AsPath>(&self, path: P) -> PathBuf {
         let mut buf = self.to_path_buf();
         buf.push(path);
         buf
@@ -1303,7 +1304,7 @@ impl Path {
     ///
     /// See `PathBuf::set_file_name` for more details.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn with_file_name<S: ?Sized>(&self, file_name: &S) -> PathBuf where S: AsOsStr {
+    pub fn with_file_name<S: AsOsStr>(&self, file_name: S) -> PathBuf {
         let mut buf = self.to_path_buf();
         buf.set_file_name(file_name);
         buf
@@ -1313,7 +1314,7 @@ impl Path {
     ///
     /// See `PathBuf::set_extension` for more details.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn with_extension<S: ?Sized>(&self, extension: &S) -> PathBuf where S: AsOsStr {
+    pub fn with_extension<S: AsOsStr>(&self, extension: S) -> PathBuf {
         let mut buf = self.to_path_buf();
         buf.set_extension(extension);
         buf
diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs
index 60e1354482c..4327b26260a 100644
--- a/src/libstd/prelude/v1.rs
+++ b/src/libstd/prelude/v1.rs
@@ -25,6 +25,7 @@
 // Reexported types and traits
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use boxed::Box;
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use char::CharExt;
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -39,14 +40,23 @@
 #[doc(no_inline)] pub use iter::{Iterator, IteratorExt, Extend};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use option::Option::{self, Some, None};
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use ptr::{PtrExt, MutPtrExt};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use result::Result::{self, Ok, Err};
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use slice::{SliceExt, SliceConcatExt, AsSlice};
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[doc(no_inline)] pub use slice::{SliceConcatExt, AsSlice};
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use str::{Str, StrExt};
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[doc(no_inline)] pub use str::Str;
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)] pub use string::{String, ToString};
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -57,6 +67,7 @@
 // NB: remove when I/O reform lands
 #[doc(no_inline)] pub use old_io::{Buffer, Writer, Reader, Seek, BufferPrelude};
 // NB: remove when range syntax lands
+#[allow(deprecated)]
 #[doc(no_inline)] pub use iter::range;
 
 #[doc(no_inline)] pub use num::wrapping::{Wrapping, WrappingOps};
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index ebd0820669c..df8a5d27c7f 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -147,7 +147,7 @@ impl Command {
     /// Builder methods are provided to change these defaults and
     /// otherwise configure the process.
     #[stable(feature = "process", since = "1.0.0")]
-    pub fn new<S: AsOsStr + ?Sized>(program: &S) -> Command {
+    pub fn new<S: AsOsStr>(program: S) -> Command {
         Command {
             inner: CommandImp::new(program.as_os_str()),
             stdin: None,
@@ -158,7 +158,7 @@ impl Command {
 
     /// Add an argument to pass to the program.
     #[stable(feature = "process", since = "1.0.0")]
-    pub fn arg<S: AsOsStr + ?Sized>(&mut self, arg: &S) -> &mut Command {
+    pub fn arg<S: AsOsStr>(&mut self, arg: S) -> &mut Command {
         self.inner.arg(arg.as_os_str());
         self
     }
@@ -175,7 +175,7 @@ impl Command {
     /// Note that environment variable names are case-insensitive (but case-preserving) on Windows,
     /// and case-sensitive on all other platforms.
     #[stable(feature = "process", since = "1.0.0")]
-    pub fn env<K: ?Sized, V: ?Sized>(&mut self, key: &K, val: &V) -> &mut Command
+    pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
         where K: AsOsStr, V: AsOsStr
     {
         self.inner.env(key.as_os_str(), val.as_os_str());
@@ -184,7 +184,7 @@ impl Command {
 
     /// Removes an environment variable mapping.
     #[stable(feature = "process", since = "1.0.0")]
-    pub fn env_remove<K: ?Sized + AsOsStr>(&mut self, key: &K) -> &mut Command {
+    pub fn env_remove<K: AsOsStr>(&mut self, key: K) -> &mut Command {
         self.inner.env_remove(key.as_os_str());
         self
     }
@@ -198,7 +198,7 @@ impl Command {
 
     /// Set the working directory for the child process.
     #[stable(feature = "process", since = "1.0.0")]
-    pub fn current_dir<P: AsPath + ?Sized>(&mut self, dir: &P) -> &mut Command {
+    pub fn current_dir<P: AsPath>(&mut self, dir: P) -> &mut Command {
         self.inner.cwd(dir.as_path().as_os_str());
         self
     }
@@ -533,7 +533,7 @@ mod tests {
     use io::prelude::*;
     use prelude::v1::{Ok, Err, drop, Some, Vec};
     use prelude::v1::{String, Clone};
-    use prelude::v1::{SliceExt, Str, StrExt, AsSlice, ToString, GenericPath};
+    use prelude::v1::{Str, AsSlice, ToString, GenericPath};
     use old_path;
     use old_io::fs::PathExtensions;
     use rt::running_on_valgrind;
@@ -573,7 +573,7 @@ mod tests {
     #[cfg(all(unix, not(target_os="android")))]
     #[test]
     fn signal_reported_right() {
-        use os::unix::ExitStatusExt;
+        use os::unix::process::ExitStatusExt;
 
         let p = Command::new("/bin/sh").arg("-c").arg("kill -9 $$").spawn();
         assert!(p.is_ok());
@@ -633,7 +633,7 @@ mod tests {
     #[cfg(all(unix, not(target_os="android")))]
     #[test]
     fn uid_works() {
-        use os::unix::*;
+        use os::unix::prelude::*;
         use libc;
         let mut p = Command::new("/bin/sh")
                             .arg("-c").arg("true")
@@ -646,7 +646,7 @@ mod tests {
     #[cfg(all(unix, not(target_os="android")))]
     #[test]
     fn uid_to_root_fails() {
-        use os::unix::*;
+        use os::unix::prelude::*;
         use libc;
 
         // if we're already root, this isn't a valid test. Most of the bots run
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs
index 6cb3eb4d16e..46e35e0fa8b 100644
--- a/src/libstd/rand/os.rs
+++ b/src/libstd/rand/os.rs
@@ -24,6 +24,7 @@ mod imp {
     use rand::Rng;
     use rand::reader::ReaderRng;
     use result::Result::Ok;
+    #[cfg(stage0)]
     use slice::SliceExt;
     use mem;
     use os::errno;
@@ -193,6 +194,7 @@ mod imp {
     use rand::Rng;
     use result::Result::{Ok};
     use self::libc::{c_int, size_t};
+    #[cfg(stage0)]
     use slice::SliceExt;
 
     /// A random number generator that retrieves randomness straight from
@@ -263,6 +265,7 @@ mod imp {
     use result::Result::{Ok, Err};
     use self::libc::{DWORD, BYTE, LPCSTR, BOOL};
     use self::libc::types::os::arch::extra::{LONG_PTR};
+    #[cfg(stage0)]
     use slice::SliceExt;
 
     type HCRYPTPROV = LONG_PTR;
diff --git a/src/libstd/rand/reader.rs b/src/libstd/rand/reader.rs
index 576bf24d8a3..42c153af036 100644
--- a/src/libstd/rand/reader.rs
+++ b/src/libstd/rand/reader.rs
@@ -13,6 +13,7 @@
 use old_io::Reader;
 use rand::Rng;
 use result::Result::{Ok, Err};
+#[cfg(stage0)]
 use slice::SliceExt;
 
 /// An RNG that reads random bytes straight from a `Reader`. This will
diff --git a/src/libstd/rt/at_exit_imp.rs b/src/libstd/rt/at_exit_imp.rs
index 08755ba829f..f6bb87f011d 100644
--- a/src/libstd/rt/at_exit_imp.rs
+++ b/src/libstd/rt/at_exit_imp.rs
@@ -12,6 +12,7 @@
 //!
 //! Documentation can be found on the `rt::at_exit` function.
 
+#[cfg(stage0)]
 use core::prelude::*;
 
 use boxed;
diff --git a/src/libstd/sys/common/net2.rs b/src/libstd/sys/common/net2.rs
index af5b49a4239..25aeab1b4ff 100644
--- a/src/libstd/sys/common/net2.rs
+++ b/src/libstd/sys/common/net2.rs
@@ -14,7 +14,7 @@ use ffi::CString;
 use io::{self, Error, ErrorKind};
 use libc::{self, c_int, c_char, c_void, socklen_t};
 use mem;
-use net::{IpAddr, SocketAddr, Shutdown};
+use net::{SocketAddr, Shutdown};
 use sys::c;
 use sys::net::{cvt, cvt_r, cvt_gai, Socket, init, wrlen_t};
 use sys_common::{AsInner, FromInner, IntoInner};
@@ -63,15 +63,15 @@ fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
     match storage.ss_family as libc::c_int {
         libc::AF_INET => {
             assert!(len as usize >= mem::size_of::<libc::sockaddr_in>());
-            Ok(FromInner::from_inner(unsafe {
+            Ok(SocketAddr::V4(FromInner::from_inner(unsafe {
                 *(storage as *const _ as *const libc::sockaddr_in)
-            }))
+            })))
         }
         libc::AF_INET6 => {
             assert!(len as usize >= mem::size_of::<libc::sockaddr_in6>());
-            Ok(FromInner::from_inner(unsafe {
+            Ok(SocketAddr::V6(FromInner::from_inner(unsafe {
                 *(storage as *const _ as *const libc::sockaddr_in6)
-            }))
+            })))
         }
         _ => {
             Err(Error::new(ErrorKind::InvalidInput, "invalid argument", None))
@@ -334,39 +334,39 @@ impl UdpSocket {
                    libc::IP_MULTICAST_LOOP, on as c_int)
     }
 
-    pub fn join_multicast(&self, multi: &IpAddr) -> io::Result<()> {
+    pub fn join_multicast(&self, multi: &SocketAddr) -> io::Result<()> {
         match *multi {
-            IpAddr::V4(..) => {
+            SocketAddr::V4(..) => {
                 self.set_membership(multi, libc::IP_ADD_MEMBERSHIP)
             }
-            IpAddr::V6(..) => {
+            SocketAddr::V6(..) => {
                 self.set_membership(multi, libc::IPV6_ADD_MEMBERSHIP)
             }
         }
     }
-    pub fn leave_multicast(&self, multi: &IpAddr) -> io::Result<()> {
+    pub fn leave_multicast(&self, multi: &SocketAddr) -> io::Result<()> {
         match *multi {
-            IpAddr::V4(..) => {
+            SocketAddr::V4(..) => {
                 self.set_membership(multi, libc::IP_DROP_MEMBERSHIP)
             }
-            IpAddr::V6(..) => {
+            SocketAddr::V6(..) => {
                 self.set_membership(multi, libc::IPV6_DROP_MEMBERSHIP)
             }
         }
     }
-    fn set_membership(&self, addr: &IpAddr, opt: c_int) -> io::Result<()> {
+    fn set_membership(&self, addr: &SocketAddr, opt: c_int) -> io::Result<()> {
         match *addr {
-            IpAddr::V4(ref addr) => {
+            SocketAddr::V4(ref addr) => {
                 let mreq = libc::ip_mreq {
-                    imr_multiaddr: *addr.as_inner(),
+                    imr_multiaddr: *addr.ip().as_inner(),
                     // interface == INADDR_ANY
                     imr_interface: libc::in_addr { s_addr: 0x0 },
                 };
                 setsockopt(&self.inner, libc::IPPROTO_IP, opt, mreq)
             }
-            IpAddr::V6(ref addr) => {
+            SocketAddr::V6(ref addr) => {
                 let mreq = libc::ip6_mreq {
-                    ipv6mr_multiaddr: *addr.as_inner(),
+                    ipv6mr_multiaddr: *addr.ip().as_inner(),
                     ipv6mr_interface: 0,
                 };
                 setsockopt(&self.inner, libc::IPPROTO_IPV6, opt, mreq)
diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs
index 6c17f9910ac..dfc88571a82 100644
--- a/src/libstd/sys/common/wtf8.rs
+++ b/src/libstd/sys/common/wtf8.rs
@@ -29,7 +29,6 @@ use core::prelude::*;
 
 use core::char::{encode_utf8_raw, encode_utf16_raw};
 use core::str::{char_range_at_raw, next_code_point};
-use core::raw::Slice as RawSlice;
 
 use ascii::*;
 use borrow::Cow;
@@ -173,6 +172,7 @@ impl Wtf8Buf {
         Wtf8Buf { bytes: string.into_bytes() }
     }
 
+    #[cfg(stage0)]
     /// Create a WTF-8 string from an UTF-8 `&str` slice.
     ///
     /// This copies the content of the slice.
@@ -183,6 +183,17 @@ impl Wtf8Buf {
         Wtf8Buf { bytes: slice::SliceExt::to_vec(str.as_bytes()) }
     }
 
+    #[cfg(not(stage0))]
+    /// Create a WTF-8 string from an UTF-8 `&str` slice.
+    ///
+    /// This copies the content of the slice.
+    ///
+    /// Since WTF-8 is a superset of UTF-8, this always succeeds.
+    #[inline]
+    pub fn from_str(str: &str) -> Wtf8Buf {
+        Wtf8Buf { bytes: <[_]>::to_vec(str.as_bytes()) }
+    }
+
     /// Create a WTF-8 string from a potentially ill-formed UTF-16 slice of 16-bit code units.
     ///
     /// This is lossless: calling `.encode_wide()` on the resulting string
@@ -214,10 +225,10 @@ impl Wtf8Buf {
         unsafe {
             // Attempt to not use an intermediate buffer by just pushing bytes
             // directly onto this string.
-            let slice = RawSlice {
-                data: self.bytes.as_ptr().offset(cur_len as int),
-                len: 4,
-            };
+            let slice = slice::from_raw_parts_mut(
+                self.bytes.as_mut_ptr().offset(cur_len as int),
+                4
+            );
             let used = encode_utf8_raw(code_point.value, mem::transmute(slice))
                 .unwrap_or(0);
             self.bytes.set_len(cur_len + used);
@@ -725,10 +736,11 @@ pub fn is_code_point_boundary(slice: &Wtf8, index: uint) -> bool {
 /// Copied from core::str::raw::slice_unchecked
 #[inline]
 pub unsafe fn slice_unchecked(s: &Wtf8, begin: uint, end: uint) -> &Wtf8 {
-    mem::transmute(RawSlice {
-        data: s.bytes.as_ptr().offset(begin as int),
-        len: end - begin,
-    })
+    // memory layout of an &[u8] and &Wtf8 are the same
+    mem::transmute(slice::from_raw_parts(
+        s.bytes.as_ptr().offset(begin as int),
+        end - begin
+    ))
 }
 
 /// Copied from core::str::raw::slice_error_fail
diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs
index 3fa9f5d07aa..74ab04978cb 100644
--- a/src/libstd/sys/unix/backtrace.rs
+++ b/src/libstd/sys/unix/backtrace.rs
@@ -118,7 +118,7 @@ pub fn write(w: &mut Write) -> io::Result<()> {
     // local, it still displays much nicer backtraces when a
     // couple of tasks panic simultaneously
     static LOCK: StaticMutex = MUTEX_INIT;
-    let _g = unsafe { LOCK.lock() };
+    let _g = LOCK.lock();
 
     try!(writeln!(w, "stack backtrace:"));
     // 100 lines should be enough
diff --git a/src/libstd/sys/unix/ext.rs b/src/libstd/sys/unix/ext.rs
index 3dd05319194..0805949d560 100644
--- a/src/libstd/sys/unix/ext.rs
+++ b/src/libstd/sys/unix/ext.rs
@@ -29,183 +29,206 @@
 //! }
 //! ```
 
-#![unstable(feature = "std_misc")]
-
-use prelude::v1::*;
-
-use ffi::{CString, NulError, OsStr, OsString};
-use fs::{self, Permissions, OpenOptions};
-use net;
-use mem;
-use process;
-use sys;
-use sys::os_str::Buf;
-use sys_common::{AsInner, AsInnerMut, IntoInner, FromInner};
-use libc::{self, gid_t, uid_t};
-
-#[allow(deprecated)] use old_io;
-
-/// Raw file descriptors.
-pub type Fd = libc::c_int;
-
-/// Extract raw file descriptor
-pub trait AsRawFd {
-    /// Extract the raw file descriptor, without taking any ownership.
-    fn as_raw_fd(&self) -> Fd;
-}
+#![stable(feature = "rust1", since = "1.0.0")]
+
+/// Unix-specific extensions to general I/O primitives
+#[unstable(feature = "io_ext",
+           reason = "may want a slightly different organization or a more \
+                     general file descriptor primitive")]
+pub mod io {
+    #[allow(deprecated)] use old_io;
+    use fs;
+    use libc;
+    use net;
+    use sys_common::AsInner;
+
+    /// Raw file descriptors.
+    pub type Fd = libc::c_int;
+
+    /// Extract raw file descriptor
+    pub trait AsRawFd {
+        /// Extract the raw file descriptor, without taking any ownership.
+        fn as_raw_fd(&self) -> Fd;
+    }
 
-#[allow(deprecated)]
-impl AsRawFd for old_io::fs::File {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[allow(deprecated)]
+    impl AsRawFd for old_io::fs::File {
+        fn as_raw_fd(&self) -> Fd {
+            self.as_inner().fd()
+        }
     }
-}
 
-impl AsRawFd for fs::File {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd().raw()
+    impl AsRawFd for fs::File {
+        fn as_raw_fd(&self) -> Fd {
+            self.as_inner().fd().raw()
+        }
     }
-}
 
-#[allow(deprecated)]
-impl AsRawFd for old_io::pipe::PipeStream {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[allow(deprecated)]
+    impl AsRawFd for old_io::pipe::PipeStream {
+        fn as_raw_fd(&self) -> Fd {
+            self.as_inner().fd()
+        }
     }
-}
 
-#[allow(deprecated)]
-impl AsRawFd for old_io::net::pipe::UnixStream {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[allow(deprecated)]
+    impl AsRawFd for old_io::net::pipe::UnixStream {
+        fn as_raw_fd(&self) -> Fd {
+            self.as_inner().fd()
+        }
     }
-}
 
-#[allow(deprecated)]
-impl AsRawFd for old_io::net::pipe::UnixListener {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[allow(deprecated)]
+    impl AsRawFd for old_io::net::pipe::UnixListener {
+        fn as_raw_fd(&self) -> Fd {
+            self.as_inner().fd()
+        }
     }
-}
 
-#[allow(deprecated)]
-impl AsRawFd for old_io::net::pipe::UnixAcceptor {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[allow(deprecated)]
+    impl AsRawFd for old_io::net::pipe::UnixAcceptor {
+        fn as_raw_fd(&self) -> Fd {
+            self.as_inner().fd()
+        }
     }
-}
 
-#[allow(deprecated)]
-impl AsRawFd for old_io::net::tcp::TcpStream {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[allow(deprecated)]
+    impl AsRawFd for old_io::net::tcp::TcpStream {
+        fn as_raw_fd(&self) -> Fd {
+            self.as_inner().fd()
+        }
     }
-}
 
-#[allow(deprecated)]
-impl AsRawFd for old_io::net::tcp::TcpListener {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[allow(deprecated)]
+    impl AsRawFd for old_io::net::tcp::TcpListener {
+        fn as_raw_fd(&self) -> Fd {
+            self.as_inner().fd()
+        }
     }
-}
 
-#[allow(deprecated)]
-impl AsRawFd for old_io::net::tcp::TcpAcceptor {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[allow(deprecated)]
+    impl AsRawFd for old_io::net::tcp::TcpAcceptor {
+        fn as_raw_fd(&self) -> Fd {
+            self.as_inner().fd()
+        }
     }
-}
 
-#[allow(deprecated)]
-impl AsRawFd for old_io::net::udp::UdpSocket {
-    fn as_raw_fd(&self) -> Fd {
-        self.as_inner().fd()
+    #[allow(deprecated)]
+    impl AsRawFd for old_io::net::udp::UdpSocket {
+        fn as_raw_fd(&self) -> Fd {
+            self.as_inner().fd()
+        }
     }
-}
 
-impl AsRawFd for net::TcpStream {
-    fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
-}
-impl AsRawFd for net::TcpListener {
-    fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
-}
-impl AsRawFd for net::UdpSocket {
-    fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
+    impl AsRawFd for net::TcpStream {
+        fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
+    }
+    impl AsRawFd for net::TcpListener {
+        fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
+    }
+    impl AsRawFd for net::UdpSocket {
+        fn as_raw_fd(&self) -> Fd { *self.as_inner().socket().as_inner() }
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // OsString and OsStr
 ////////////////////////////////////////////////////////////////////////////////
 
-/// Unix-specific extensions to `OsString`.
-pub trait OsStringExt {
-    /// Create an `OsString` from a byte vector.
-    fn from_vec(vec: Vec<u8>) -> Self;
-
-    /// Yield the underlying byte vector of this `OsString`.
-    fn into_vec(self) -> Vec<u8>;
-}
-
-impl OsStringExt for OsString {
-    fn from_vec(vec: Vec<u8>) -> OsString {
-        FromInner::from_inner(Buf { inner: vec })
+/// Unix-specific extension to the primitives in the `std::ffi` module
+#[stable(feature = "rust1", since = "1.0.0")]
+pub mod ffi {
+    use ffi::{CString, NulError, OsStr, OsString};
+    use mem;
+    use prelude::v1::*;
+    use sys::os_str::Buf;
+    use sys_common::{FromInner, IntoInner, AsInner};
+
+    /// Unix-specific extensions to `OsString`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub trait OsStringExt {
+        /// Create an `OsString` from a byte vector.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn from_vec(vec: Vec<u8>) -> Self;
+
+        /// Yield the underlying byte vector of this `OsString`.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn into_vec(self) -> Vec<u8>;
     }
 
-    fn into_vec(self) -> Vec<u8> {
-        self.into_inner().inner
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl OsStringExt for OsString {
+        fn from_vec(vec: Vec<u8>) -> OsString {
+            FromInner::from_inner(Buf { inner: vec })
+        }
+        fn into_vec(self) -> Vec<u8> {
+            self.into_inner().inner
+        }
     }
-}
-
-/// Unix-specific extensions to `OsStr`.
-pub trait OsStrExt {
-    fn from_bytes(slice: &[u8]) -> &OsStr;
 
-    /// Get the underlying byte view of the `OsStr` slice.
-    fn as_bytes(&self) -> &[u8];
+    /// Unix-specific extensions to `OsStr`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub trait OsStrExt {
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn from_bytes(slice: &[u8]) -> &Self;
 
-    /// Convert the `OsStr` slice into a `CString`.
-    fn to_cstring(&self) -> Result<CString, NulError>;
-}
+        /// Get the underlying byte view of the `OsStr` slice.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn as_bytes(&self) -> &[u8];
 
-impl OsStrExt for OsStr {
-    fn from_bytes(slice: &[u8]) -> &OsStr {
-        unsafe { mem::transmute(slice) }
-    }
-    fn as_bytes(&self) -> &[u8] {
-        &self.as_inner().inner
+        /// Convert the `OsStr` slice into a `CString`.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn to_cstring(&self) -> Result<CString, NulError>;
     }
 
-    fn to_cstring(&self) -> Result<CString, NulError> {
-        CString::new(self.as_bytes())
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl OsStrExt for OsStr {
+        fn from_bytes(slice: &[u8]) -> &OsStr {
+            unsafe { mem::transmute(slice) }
+        }
+        fn as_bytes(&self) -> &[u8] {
+            &self.as_inner().inner
+        }
+        fn to_cstring(&self) -> Result<CString, NulError> {
+            CString::new(self.as_bytes())
+        }
     }
 }
 
-// Unix-specific extensions to `Permissions`
-pub trait PermissionsExt {
-    fn mode(&self) -> i32;
-    fn set_mode(&mut self, mode: i32);
-}
+/// Unix-specific extensions to primitives in the `std::fs` module.
+#[unstable(feature = "fs_ext",
+           reason = "may want a more useful mode abstraction")]
+pub mod fs {
+    use sys_common::{FromInner, AsInner, AsInnerMut};
+    use fs::{Permissions, OpenOptions};
+
+    /// Unix-specific extensions to `Permissions`
+    pub trait PermissionsExt {
+        fn mode(&self) -> i32;
+        fn set_mode(&mut self, mode: i32);
+    }
 
-impl PermissionsExt for Permissions {
-    fn mode(&self) -> i32 { self.as_inner().mode() }
+    impl PermissionsExt for Permissions {
+        fn mode(&self) -> i32 { self.as_inner().mode() }
 
-    fn set_mode(&mut self, mode: i32) {
-        *self = FromInner::from_inner(FromInner::from_inner(mode));
+        fn set_mode(&mut self, mode: i32) {
+            *self = FromInner::from_inner(FromInner::from_inner(mode));
+        }
     }
-}
 
-// Unix-specific extensions to `OpenOptions`
-pub trait OpenOptionsExt {
-    /// Set the mode bits that a new file will be created with.
-    ///
-    /// If a new file is created as part of a `File::open_opts` call then this
-    /// specified `mode` will be used as the permission bits for the new file.
-    fn mode(&mut self, mode: i32) -> &mut Self;
-}
+    /// Unix-specific extensions to `OpenOptions`
+    pub trait OpenOptionsExt {
+        /// Set the mode bits that a new file will be created with.
+        ///
+        /// If a new file is created as part of a `File::open_opts` call then this
+        /// specified `mode` will be used as the permission bits for the new file.
+        fn mode(&mut self, mode: i32) -> &mut Self;
+    }
 
-impl OpenOptionsExt for OpenOptions {
-    fn mode(&mut self, mode: i32) -> &mut OpenOptions {
-        self.as_inner_mut().mode(mode); self
+    impl OpenOptionsExt for OpenOptions {
+        fn mode(&mut self, mode: i32) -> &mut OpenOptions {
+            self.as_inner_mut().mode(mode); self
+        }
     }
 }
 
@@ -213,41 +236,58 @@ impl OpenOptionsExt for OpenOptions {
 // Process and Command
 ////////////////////////////////////////////////////////////////////////////////
 
-/// Unix-specific extensions to the `std::process::Command` builder
-pub trait CommandExt {
-    /// Sets the child process's user id. This translates to a
-    /// `setuid` call in the child process. Failure in the `setuid`
-    /// call will cause the spawn to fail.
-    fn uid(&mut self, id: uid_t) -> &mut process::Command;
+/// Unix-specific extensions to primitives in the `std::process` module.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub mod process {
+    use prelude::v1::*;
+    use libc::{uid_t, gid_t};
+    use process;
+    use sys;
+    use sys_common::{AsInnerMut, AsInner};
+
+    /// Unix-specific extensions to the `std::process::Command` builder
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub trait CommandExt {
+        /// Sets the child process's user id. This translates to a
+        /// `setuid` call in the child process. Failure in the `setuid`
+        /// call will cause the spawn to fail.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn uid(&mut self, id: uid_t) -> &mut process::Command;
+
+        /// Similar to `uid`, but sets the group id of the child process. This has
+        /// the same semantics as the `uid` field.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn gid(&mut self, id: gid_t) -> &mut process::Command;
+    }
 
-    /// Similar to `uid`, but sets the group id of the child process. This has
-    /// the same semantics as the `uid` field.
-    fn gid(&mut self, id: gid_t) -> &mut process::Command;
-}
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl CommandExt for process::Command {
+        fn uid(&mut self, id: uid_t) -> &mut process::Command {
+            self.as_inner_mut().uid = Some(id);
+            self
+        }
 
-impl CommandExt for process::Command {
-    fn uid(&mut self, id: uid_t) -> &mut process::Command {
-        self.as_inner_mut().uid = Some(id);
-        self
+        fn gid(&mut self, id: gid_t) -> &mut process::Command {
+            self.as_inner_mut().gid = Some(id);
+            self
+        }
     }
 
-    fn gid(&mut self, id: gid_t) -> &mut process::Command {
-        self.as_inner_mut().gid = Some(id);
-        self
+    /// Unix-specific extensions to `std::process::ExitStatus`
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub trait ExitStatusExt {
+        /// If the process was terminated by a signal, returns that signal.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn signal(&self) -> Option<i32>;
     }
-}
-
-/// Unix-specific extensions to `std::process::ExitStatus`
-pub trait ExitStatusExt {
-    /// If the process was terminated by a signal, returns that signal.
-    fn signal(&self) -> Option<i32>;
-}
 
-impl ExitStatusExt for process::ExitStatus {
-    fn signal(&self) -> Option<i32> {
-        match *self.as_inner() {
-            sys::process2::ExitStatus::Signal(s) => Some(s),
-            _ => None
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl ExitStatusExt for process::ExitStatus {
+        fn signal(&self) -> Option<i32> {
+            match *self.as_inner() {
+                sys::process2::ExitStatus::Signal(s) => Some(s),
+                _ => None
+            }
         }
     }
 }
@@ -259,9 +299,14 @@ impl ExitStatusExt for process::ExitStatus {
 /// A prelude for conveniently writing platform-specific code.
 ///
 /// Includes all extension traits, and some important type definitions.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub mod prelude {
     #[doc(no_inline)]
-    pub use super::{Fd, AsRawFd, OsStrExt, OsStringExt, PermissionsExt};
+    pub use super::io::{Fd, AsRawFd};
+    #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
+    pub use super::ffi::{OsStrExt, OsStringExt};
     #[doc(no_inline)]
-    pub use super::{CommandExt, ExitStatusExt};
+    pub use super::fs::{PermissionsExt, OpenOptionsExt};
+    #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
+    pub use super::process::{CommandExt, ExitStatusExt};
 }
diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs
index 83b6a14b78d..b22fa33e562 100644
--- a/src/libstd/sys/unix/net.rs
+++ b/src/libstd/sys/unix/net.rs
@@ -15,7 +15,7 @@ use io;
 use libc::{self, c_int, size_t};
 use str;
 use sys::c;
-use net::{SocketAddr, IpAddr};
+use net::SocketAddr;
 use sys::fd::FileDesc;
 use sys_common::AsInner;
 
@@ -40,9 +40,9 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
 
 impl Socket {
     pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
-        let fam = match addr.ip() {
-            IpAddr::V4(..) => libc::AF_INET,
-            IpAddr::V6(..) => libc::AF_INET6,
+        let fam = match *addr {
+            SocketAddr::V4(..) => libc::AF_INET,
+            SocketAddr::V6(..) => libc::AF_INET6,
         };
         unsafe {
             let fd = try!(cvt(libc::socket(fam, ty, 0)));
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index d332556d188..75aeafe6e3c 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -13,7 +13,7 @@
 #![allow(unused_imports)] // lots of cfg code here
 
 use prelude::v1::*;
-use os::unix::*;
+use os::unix::prelude::*;
 
 use error::Error as StdError;
 use ffi::{CString, CStr, OsString, OsStr, AsOsStr};
@@ -206,7 +206,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
         if err != 0 { return Err(io::Error::last_os_error()); }
         if sz == 0 { return Err(io::Error::last_os_error()); }
         v.set_len(sz as uint - 1); // chop off trailing NUL
-        Ok(PathBuf::new::<OsString>(&OsStringExt::from_vec(v)))
+        Ok(PathBuf::new::<OsString>(OsStringExt::from_vec(v)))
     }
 }
 
@@ -232,7 +232,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
             Err(io::Error::last_os_error())
         } else {
             let vec = CStr::from_ptr(v).to_bytes().to_vec();
-            Ok(PathBuf::new::<OsString>(&OsStringExt::from_vec(vec)))
+            Ok(PathBuf::new::<OsString>(OsStringExt::from_vec(vec)))
         }
     }
 }
@@ -253,7 +253,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
         let err = _NSGetExecutablePath(v.as_mut_ptr() as *mut i8, &mut sz);
         if err != 0 { return Err(io::Error::last_os_error()); }
         v.set_len(sz as uint - 1); // chop off trailing NUL
-        Ok(PathBuf::new::<OsString>(&OsStringExt::from_vec(v)))
+        Ok(PathBuf::new(OsString::from_vec(v)))
     }
 }
 
@@ -286,7 +286,7 @@ pub fn args() -> Args {
     let vec = unsafe {
         let (argc, argv) = (*_NSGetArgc() as isize,
                             *_NSGetArgv() as *const *const c_char);
-        range(0, argc as isize).map(|i| {
+        (0.. argc as isize).map(|i| {
             let bytes = CStr::from_ptr(*argv.offset(i)).to_bytes().to_vec();
             OsStringExt::from_vec(bytes)
         }).collect::<Vec<_>>()
diff --git a/src/libstd/sys/unix/os_str.rs b/src/libstd/sys/unix/os_str.rs
index 89ab3e1981b..99591480752 100644
--- a/src/libstd/sys/unix/os_str.rs
+++ b/src/libstd/sys/unix/os_str.rs
@@ -16,6 +16,7 @@ use core::prelude::*;
 use borrow::Cow;
 use fmt::{self, Debug};
 use vec::Vec;
+#[cfg(stage0)]
 use slice::SliceExt as StdSliceExt;
 use str;
 use string::String;
diff --git a/src/libstd/sys/unix/process2.rs b/src/libstd/sys/unix/process2.rs
index 03b77eb75d7..20c409154b8 100644
--- a/src/libstd/sys/unix/process2.rs
+++ b/src/libstd/sys/unix/process2.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use prelude::v1::*;
+use os::unix::prelude::*;
 
 use collections::HashMap;
 use env;
@@ -17,7 +18,6 @@ use fmt;
 use io::{self, Error, ErrorKind};
 use libc::{self, pid_t, c_void, c_int, gid_t, uid_t};
 use mem;
-use os::unix::OsStrExt;
 use ptr;
 use sys::pipe2::AnonPipe;
 use sys::{self, retry, c, cvt};
diff --git a/src/libstd/sys/unix/tty.rs b/src/libstd/sys/unix/tty.rs
index f607f7c6a2f..e4973a8f9f3 100644
--- a/src/libstd/sys/unix/tty.rs
+++ b/src/libstd/sys/unix/tty.rs
@@ -23,6 +23,8 @@ pub struct TTY {
 }
 
 #[cfg(any(target_os = "macos",
+          target_os = "ios",
+          target_os = "dragonfly",
           target_os = "freebsd",
           target_os = "bitrig",
           target_os = "openbsd"))]
@@ -54,12 +56,6 @@ impl TTY {
         Err(sys_common::unimpl())
     }
 
-    #[cfg(any(target_os = "linux",
-              target_os = "android",
-              target_os = "macos",
-              target_os = "freebsd",
-              target_os = "bitrig",
-              target_os = "openbsd"))]
     pub fn get_winsize(&mut self) -> IoResult<(int, int)> {
         unsafe {
             #[repr(C)]
@@ -82,10 +78,4 @@ impl TTY {
             }
         }
     }
-
-    #[cfg(any(target_os = "ios",
-              target_os = "dragonfly"))]
-    pub fn get_winsize(&mut self) -> IoResult<(int, int)> {
-        Err(sys_common::unimpl())
-    }
 }
diff --git a/src/libstd/sys/windows/ext.rs b/src/libstd/sys/windows/ext.rs
index dc820a4ce45..7955397892b 100644
--- a/src/libstd/sys/windows/ext.rs
+++ b/src/libstd/sys/windows/ext.rs
@@ -14,197 +14,225 @@
 //! descriptors, and sockets, but its functionality will grow over
 //! time.
 
-#![unstable(feature = "std_misc")]
+#![stable(feature = "rust1", since = "1.0.0")]
 
-pub use sys_common::wtf8::{Wtf8Buf, EncodeWide};
+#[unstable(feature = "io_ext",
+           reason = "organization may change slightly and the primitives \
+                     provided may be tweaked")]
+pub mod io {
+    use fs;
+    use libc;
+    use net;
+    use sys_common::AsInner;
 
-use ffi::{OsStr, OsString};
-use fs::{self, OpenOptions};
-use libc;
-use net;
-use sys::os_str::Buf;
-use sys_common::{AsInner, FromInner, AsInnerMut};
+    #[allow(deprecated)]
+    use old_io;
 
-#[allow(deprecated)]
-use old_io;
+    /// Raw HANDLEs.
+    pub type Handle = libc::HANDLE;
 
-/// Raw HANDLEs.
-pub type Handle = libc::HANDLE;
+    /// Raw SOCKETs.
+    pub type Socket = libc::SOCKET;
 
-/// Raw SOCKETs.
-pub type Socket = libc::SOCKET;
+    /// Extract raw handles.
+    pub trait AsRawHandle {
+        /// Extract the raw handle, without taking any ownership.
+        fn as_raw_handle(&self) -> Handle;
+    }
 
-/// Extract raw handles.
-pub trait AsRawHandle {
-    /// Extract the raw handle, without taking any ownership.
-    fn as_raw_handle(&self) -> Handle;
-}
+    #[allow(deprecated)]
+    impl AsRawHandle for old_io::fs::File {
+        fn as_raw_handle(&self) -> Handle {
+            self.as_inner().handle()
+        }
+    }
 
-#[allow(deprecated)]
-impl AsRawHandle for old_io::fs::File {
-    fn as_raw_handle(&self) -> Handle {
-        self.as_inner().handle()
+    impl AsRawHandle for fs::File {
+        fn as_raw_handle(&self) -> Handle {
+            self.as_inner().handle().raw()
+        }
     }
-}
 
-impl AsRawHandle for fs::File {
-    fn as_raw_handle(&self) -> Handle {
-        self.as_inner().handle().raw()
+    #[allow(deprecated)]
+    impl AsRawHandle for old_io::pipe::PipeStream {
+        fn as_raw_handle(&self) -> Handle {
+            self.as_inner().handle()
+        }
     }
-}
 
-#[allow(deprecated)]
-impl AsRawHandle for old_io::pipe::PipeStream {
-    fn as_raw_handle(&self) -> Handle {
-        self.as_inner().handle()
+    #[allow(deprecated)]
+    impl AsRawHandle for old_io::net::pipe::UnixStream {
+        fn as_raw_handle(&self) -> Handle {
+            self.as_inner().handle()
+        }
     }
-}
 
-#[allow(deprecated)]
-impl AsRawHandle for old_io::net::pipe::UnixStream {
-    fn as_raw_handle(&self) -> Handle {
-        self.as_inner().handle()
+    #[allow(deprecated)]
+    impl AsRawHandle for old_io::net::pipe::UnixListener {
+        fn as_raw_handle(&self) -> Handle {
+            self.as_inner().handle()
+        }
     }
-}
 
-#[allow(deprecated)]
-impl AsRawHandle for old_io::net::pipe::UnixListener {
-    fn as_raw_handle(&self) -> Handle {
-        self.as_inner().handle()
+    #[allow(deprecated)]
+    impl AsRawHandle for old_io::net::pipe::UnixAcceptor {
+        fn as_raw_handle(&self) -> Handle {
+            self.as_inner().handle()
+        }
     }
-}
 
-#[allow(deprecated)]
-impl AsRawHandle for old_io::net::pipe::UnixAcceptor {
-    fn as_raw_handle(&self) -> Handle {
-        self.as_inner().handle()
+    /// Extract raw sockets.
+    pub trait AsRawSocket {
+        fn as_raw_socket(&self) -> Socket;
     }
-}
 
-/// Extract raw sockets.
-pub trait AsRawSocket {
-    fn as_raw_socket(&self) -> Socket;
-}
+    #[allow(deprecated)]
+    impl AsRawSocket for old_io::net::tcp::TcpStream {
+        fn as_raw_socket(&self) -> Socket {
+            self.as_inner().fd()
+        }
+    }
 
-#[allow(deprecated)]
-impl AsRawSocket for old_io::net::tcp::TcpStream {
-    fn as_raw_socket(&self) -> Socket {
-        self.as_inner().fd()
+    #[allow(deprecated)]
+    impl AsRawSocket for old_io::net::tcp::TcpListener {
+        fn as_raw_socket(&self) -> Socket {
+            self.as_inner().socket()
+        }
     }
-}
 
-#[allow(deprecated)]
-impl AsRawSocket for old_io::net::tcp::TcpListener {
-    fn as_raw_socket(&self) -> Socket {
-        self.as_inner().socket()
+    #[allow(deprecated)]
+    impl AsRawSocket for old_io::net::tcp::TcpAcceptor {
+        fn as_raw_socket(&self) -> Socket {
+            self.as_inner().socket()
+        }
     }
-}
 
-#[allow(deprecated)]
-impl AsRawSocket for old_io::net::tcp::TcpAcceptor {
-    fn as_raw_socket(&self) -> Socket {
-        self.as_inner().socket()
+    #[allow(deprecated)]
+    impl AsRawSocket for old_io::net::udp::UdpSocket {
+        fn as_raw_socket(&self) -> Socket {
+            self.as_inner().fd()
+        }
     }
-}
 
-#[allow(deprecated)]
-impl AsRawSocket for old_io::net::udp::UdpSocket {
-    fn as_raw_socket(&self) -> Socket {
-        self.as_inner().fd()
+    impl AsRawSocket for net::TcpStream {
+        fn as_raw_socket(&self) -> Socket { *self.as_inner().socket().as_inner() }
+    }
+    impl AsRawSocket for net::TcpListener {
+        fn as_raw_socket(&self) -> Socket { *self.as_inner().socket().as_inner() }
+    }
+    impl AsRawSocket for net::UdpSocket {
+        fn as_raw_socket(&self) -> Socket { *self.as_inner().socket().as_inner() }
     }
 }
 
-impl AsRawSocket for net::TcpStream {
-    fn as_raw_socket(&self) -> Socket { *self.as_inner().socket().as_inner() }
-}
-impl AsRawSocket for net::TcpListener {
-    fn as_raw_socket(&self) -> Socket { *self.as_inner().socket().as_inner() }
-}
-impl AsRawSocket for net::UdpSocket {
-    fn as_raw_socket(&self) -> Socket { *self.as_inner().socket().as_inner() }
-}
+/// Windows-specific extensions to the primitives in the `std::ffi` module.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub mod ffi {
+    use ffi::{OsString, OsStr};
+    use sys::os_str::Buf;
+    use sys_common::wtf8::Wtf8Buf;
+    use sys_common::{FromInner, AsInner};
 
-/// Windows-specific extensions to `OsString`.
-pub trait OsStringExt {
-    /// Create an `OsString` from a potentially ill-formed UTF-16 slice of 16-bit code units.
-    ///
-    /// This is lossless: calling `.encode_wide()` on the resulting string
-    /// will always return the original code units.
-    fn from_wide(wide: &[u16]) -> Self;
-}
+    pub use sys_common::wtf8::EncodeWide;
 
-impl OsStringExt for OsString {
-    fn from_wide(wide: &[u16]) -> OsString {
-        FromInner::from_inner(Buf { inner: Wtf8Buf::from_wide(wide) })
+    /// Windows-specific extensions to `OsString`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub trait OsStringExt {
+        /// Create an `OsString` from a potentially ill-formed UTF-16 slice of
+        /// 16-bit code units.
+        ///
+        /// This is lossless: calling `.encode_wide()` on the resulting string
+        /// will always return the original code units.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn from_wide(wide: &[u16]) -> Self;
     }
-}
 
-/// Windows-specific extensions to `OsStr`.
-pub trait OsStrExt {
-    /// Re-encode an `OsStr` as a wide character sequence,
-    /// i.e. potentially ill-formed UTF-16.
-    ///
-    /// This is lossless. Note that the encoding does not include a final null.
-    fn encode_wide(&self) -> EncodeWide;
-}
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl OsStringExt for OsString {
+        fn from_wide(wide: &[u16]) -> OsString {
+            FromInner::from_inner(Buf { inner: Wtf8Buf::from_wide(wide) })
+        }
+    }
 
-impl OsStrExt for OsStr {
-    fn encode_wide(&self) -> EncodeWide {
-        self.as_inner().inner.encode_wide()
+    /// Windows-specific extensions to `OsStr`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub trait OsStrExt {
+        /// Re-encode an `OsStr` as a wide character sequence,
+        /// i.e. potentially ill-formed UTF-16.
+        ///
+        /// This is lossless. Note that the encoding does not include a final
+        /// null.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        fn encode_wide(&self) -> EncodeWide;
     }
-}
 
-// Windows-specific extensions to `OpenOptions`
-pub trait OpenOptionsExt {
-    /// Override the `dwDesiredAccess` argument to the call to `CreateFile` with
-    /// the specified value.
-    fn desired_access(&mut self, access: i32) -> &mut Self;
-
-    /// Override the `dwCreationDisposition` argument to the call to
-    /// `CreateFile` with the specified value.
-    ///
-    /// This will override any values of the standard `create` flags, for
-    /// example.
-    fn creation_disposition(&mut self, val: i32) -> &mut Self;
-
-    /// Override the `dwFlagsAndAttributes` argument to the call to
-    /// `CreateFile` with the specified value.
-    ///
-    /// This will override any values of the standard flags on the `OpenOptions`
-    /// structure.
-    fn flags_and_attributes(&mut self, val: i32) -> &mut Self;
-
-    /// Override the `dwShareMode` argument to the call to `CreateFile` with the
-    /// specified value.
-    ///
-    /// This will override any values of the standard flags on the `OpenOptions`
-    /// structure.
-    fn share_mode(&mut self, val: i32) -> &mut Self;
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl OsStrExt for OsStr {
+        fn encode_wide(&self) -> EncodeWide {
+            self.as_inner().inner.encode_wide()
+        }
+    }
 }
 
-impl OpenOptionsExt for OpenOptions {
-    fn desired_access(&mut self, access: i32) -> &mut OpenOptions {
-        self.as_inner_mut().desired_access(access); self
-    }
-    fn creation_disposition(&mut self, access: i32) -> &mut OpenOptions {
-        self.as_inner_mut().creation_disposition(access); self
-    }
-    fn flags_and_attributes(&mut self, access: i32) -> &mut OpenOptions {
-        self.as_inner_mut().flags_and_attributes(access); self
-    }
-    fn share_mode(&mut self, access: i32) -> &mut OpenOptions {
-        self.as_inner_mut().share_mode(access); self
+/// Windows-specific extensions for the primitives in `std::fs`
+#[unstable(feature = "fs_ext", reason = "may require more thought/methods")]
+pub mod fs {
+    use fs::OpenOptions;
+    use sys_common::AsInnerMut;
+
+    /// Windows-specific extensions to `OpenOptions`
+    pub trait OpenOptionsExt {
+        /// Override the `dwDesiredAccess` argument to the call to `CreateFile`
+        /// with the specified value.
+        fn desired_access(&mut self, access: i32) -> &mut Self;
+
+        /// Override the `dwCreationDisposition` argument to the call to
+        /// `CreateFile` with the specified value.
+        ///
+        /// This will override any values of the standard `create` flags, for
+        /// example.
+        fn creation_disposition(&mut self, val: i32) -> &mut Self;
+
+        /// Override the `dwFlagsAndAttributes` argument to the call to
+        /// `CreateFile` with the specified value.
+        ///
+        /// This will override any values of the standard flags on the
+        /// `OpenOptions` structure.
+        fn flags_and_attributes(&mut self, val: i32) -> &mut Self;
+
+        /// Override the `dwShareMode` argument to the call to `CreateFile` with
+        /// the specified value.
+        ///
+        /// This will override any values of the standard flags on the
+        /// `OpenOptions` structure.
+        fn share_mode(&mut self, val: i32) -> &mut Self;
+    }
+
+    impl OpenOptionsExt for OpenOptions {
+        fn desired_access(&mut self, access: i32) -> &mut OpenOptions {
+            self.as_inner_mut().desired_access(access); self
+        }
+        fn creation_disposition(&mut self, access: i32) -> &mut OpenOptions {
+            self.as_inner_mut().creation_disposition(access); self
+        }
+        fn flags_and_attributes(&mut self, access: i32) -> &mut OpenOptions {
+            self.as_inner_mut().flags_and_attributes(access); self
+        }
+        fn share_mode(&mut self, access: i32) -> &mut OpenOptions {
+            self.as_inner_mut().share_mode(access); self
+        }
     }
 }
 
 /// A prelude for conveniently writing platform-specific code.
 ///
 /// Includes all extension traits, and some important type definitions.
+#[stable(feature = "rust1", since = "1.0.0")]
 pub mod prelude {
     #[doc(no_inline)]
-    pub use super::{Socket, Handle, AsRawSocket, AsRawHandle};
-    #[doc(no_inline)]
-    pub use super::{OsStrExt, OsStringExt};
+    pub use super::io::{Socket, Handle, AsRawSocket, AsRawHandle};
+    #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
+    pub use super::ffi::{OsStrExt, OsStringExt};
     #[doc(no_inline)]
-    pub use super::OpenOptionsExt;
+    pub use super::fs::OpenOptionsExt;
 }
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index 6b0f6a78c85..d02fe79fcdb 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -20,7 +20,7 @@ use libc;
 use mem;
 use num::Int;
 use old_io::{self, IoResult, IoError};
-use os::windows::{OsStrExt, OsStringExt};
+use os::windows::ffi::{OsStrExt, OsStringExt};
 use path::PathBuf;
 use sync::{Once, ONCE_INIT};
 
diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs
index 6caa4df5dfe..e092faf4935 100644
--- a/src/libstd/sys/windows/net.rs
+++ b/src/libstd/sys/windows/net.rs
@@ -14,7 +14,7 @@ use io;
 use libc::consts::os::extra::INVALID_SOCKET;
 use libc::{self, c_int, c_void};
 use mem;
-use net::{SocketAddr, IpAddr};
+use net::SocketAddr;
 use num::{SignedInt, Int};
 use rt;
 use sync::{Once, ONCE_INIT};
@@ -73,9 +73,9 @@ pub fn cvt_r<T: SignedInt, F>(mut f: F) -> io::Result<T> where F: FnMut() -> T {
 
 impl Socket {
     pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
-        let fam = match addr.ip() {
-            IpAddr::V4(..) => libc::AF_INET,
-            IpAddr::V6(..) => libc::AF_INET6,
+        let fam = match *addr {
+            SocketAddr::V4(..) => libc::AF_INET,
+            SocketAddr::V6(..) => libc::AF_INET6,
         };
         match unsafe { libc::socket(fam, ty, 0) } {
             INVALID_SOCKET => Err(last_error()),
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index ecd538abfb4..4f6c4c9aab3 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -13,7 +13,7 @@
 #![allow(bad_style)]
 
 use prelude::v1::*;
-use os::windows::*;
+use os::windows::prelude::*;
 
 use error::Error as StdError;
 use ffi::{OsString, OsStr, AsOsStr};
@@ -25,6 +25,7 @@ use mem;
 #[allow(deprecated)]
 use old_io::{IoError, IoResult};
 use ops::Range;
+use os::windows::ffi::EncodeWide;
 use path::{self, PathBuf};
 use ptr;
 use slice;
diff --git a/src/libstd/sys/windows/process2.rs b/src/libstd/sys/windows/process2.rs
index 8a6a485cbbe..e3cf5da59f0 100644
--- a/src/libstd/sys/windows/process2.rs
+++ b/src/libstd/sys/windows/process2.rs
@@ -19,7 +19,7 @@ use fmt;
 use fs;
 use io::{self, Error};
 use libc::{self, c_void};
-use os::windows::OsStrExt;
+use os::windows::ffi::OsStrExt;
 use ptr;
 use sync::{StaticMutex, MUTEX_INIT};
 use sys::handle::Handle;
@@ -128,6 +128,7 @@ impl Process {
         use env::split_paths;
         use mem;
         use iter::IteratorExt;
+        #[cfg(stage0)]
         use str::StrExt;
 
         // To have the spawning semantics of unix/windows stay the same, we need to
diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs
index adc3b77407a..a40b26c85be 100644
--- a/src/libstd/thread.rs
+++ b/src/libstd/thread.rs
@@ -402,18 +402,18 @@ pub fn park() {
 /// the specified duration has been reached (may wake spuriously).
 ///
 /// The semantics of this function are equivalent to `park()` except that the
-/// thread will be blocked for roughly no longer than dur. This method
+/// thread will be blocked for roughly no longer than *duration*. This method
 /// should not be used for precise timing due to anomalies such as
 /// preemption or platform differences that may not cause the maximum
-/// amount of time waited to be precisely dur
+/// amount of time waited to be precisely *duration* long.
 ///
 /// See the module doc for more detail.
 #[unstable(feature = "std_misc", reason = "recently introduced, depends on Duration")]
-pub fn park_timeout(dur: Duration) {
+pub fn park_timeout(duration: Duration) {
     let thread = current();
     let mut guard = thread.inner.lock.lock().unwrap();
     if !*guard {
-        let (g, _) = thread.inner.cvar.wait_timeout(guard, dur).unwrap();
+        let (g, _) = thread.inner.cvar.wait_timeout(guard, duration).unwrap();
         guard = g;
     }
     *guard = false;
@@ -502,11 +502,11 @@ impl Thread {
     /// Deprecated: use module-level free function.
     #[deprecated(since = "1.0.0", reason = "use module-level free function")]
     #[unstable(feature = "std_misc", reason = "recently introduced")]
-    pub fn park_timeout(dur: Duration) {
+    pub fn park_timeout(duration: Duration) {
         let thread = current();
         let mut guard = thread.inner.lock.lock().unwrap();
         if !*guard {
-            let (g, _) = thread.inner.cvar.wait_timeout(guard, dur).unwrap();
+            let (g, _) = thread.inner.cvar.wait_timeout(guard, duration).unwrap();
             guard = g;
         }
         *guard = false;
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 48c045ee4f9..c38556b0782 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -361,8 +361,7 @@ pub mod rt {
             parse::parse_stmt_from_source_str("<quote expansion>".to_string(),
                                               s,
                                               self.cfg(),
-                                              Vec::new(),
-                                              self.parse_sess())
+                                              self.parse_sess()).expect("parse error")
         }
 
         fn parse_expr(&self, s: String) -> P<ast::Expr> {
@@ -407,7 +406,7 @@ pub fn expand_quote_expr<'cx>(cx: &'cx mut ExtCtxt,
                               sp: Span,
                               tts: &[ast::TokenTree])
                               -> Box<base::MacResult+'cx> {
-    let expanded = expand_parse_call(cx, sp, "parse_expr", Vec::new(), tts);
+    let expanded = expand_parse_call(cx, sp, "parse_expr", vec!(), tts);
     base::MacEager::expr(expanded)
 }
 
@@ -415,8 +414,7 @@ pub fn expand_quote_item<'cx>(cx: &mut ExtCtxt,
                               sp: Span,
                               tts: &[ast::TokenTree])
                               -> Box<base::MacResult+'cx> {
-    let expanded = expand_parse_call(cx, sp, "parse_item_with_outer_attributes",
-                                    vec!(), tts);
+    let expanded = expand_parse_call(cx, sp, "parse_item", vec!(), tts);
     base::MacEager::expr(expanded)
 }
 
@@ -448,9 +446,7 @@ pub fn expand_quote_stmt(cx: &mut ExtCtxt,
                          sp: Span,
                          tts: &[ast::TokenTree])
                          -> Box<base::MacResult+'static> {
-    let e_attrs = cx.expr_vec_ng(sp);
-    let expanded = expand_parse_call(cx, sp, "parse_stmt",
-                                    vec!(e_attrs), tts);
+    let expanded = expand_parse_call(cx, sp, "parse_stmt", vec!(), tts);
     base::MacEager::expr(expanded)
 }
 
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index eb0daac3ab8..c61aec0069d 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -115,7 +115,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree
                       -> Option<SmallVector<P<ast::Item>>> {
             let mut ret = SmallVector::zero();
             while self.p.token != token::Eof {
-                match self.p.parse_item_with_outer_attributes() {
+                match self.p.parse_item() {
                     Some(item) => ret.push(item),
                     None => self.p.span_fatal(
                         self.p.span,
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index eb15d708232..b7d40a46f3e 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -521,12 +521,15 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
     // check at the beginning and the parser checks after each bump
     p.check_unknown_macro_variable();
     match name {
-      "item" => match p.parse_item(Vec::new()) {
+      "item" => match p.parse_item() {
         Some(i) => token::NtItem(i),
         None => p.fatal("expected an item keyword")
       },
       "block" => token::NtBlock(p.parse_block()),
-      "stmt" => token::NtStmt(p.parse_stmt(Vec::new())),
+      "stmt" => match p.parse_stmt() {
+        Some(s) => token::NtStmt(s),
+        None => p.fatal("expected a statement")
+      },
       "pat" => token::NtPat(p.parse_pat()),
       "expr" => token::NtExpr(p.parse_expr()),
       "ty" => token::NtTy(p.parse_ty()),
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 7575d4b5ecd..7a2ae55e914 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -17,7 +17,6 @@ use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
 use ext::tt::macro_parser::{parse, parse_or_else};
 use parse::lexer::new_tt_reader;
 use parse::parser::Parser;
-use parse::attr::ParserAttr;
 use parse::token::{self, special_idents, gensym_ident, NtTT, Token};
 use parse::token::Token::*;
 use print;
@@ -68,15 +67,8 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
     }
     fn make_items(self: Box<ParserAnyMacro<'a>>) -> Option<SmallVector<P<ast::Item>>> {
         let mut ret = SmallVector::zero();
-        loop {
-            let mut parser = self.parser.borrow_mut();
-            // so... do outer attributes attached to the macro invocation
-            // just disappear? This question applies to make_impl_items, as
-            // well.
-            match parser.parse_item_with_outer_attributes() {
-                Some(item) => ret.push(item),
-                None => break
-            }
+        while let Some(item) = self.parser.borrow_mut().parse_item() {
+            ret.push(item);
         }
         self.ensure_complete_parse(false);
         Some(ret)
@@ -89,7 +81,7 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
             let mut parser = self.parser.borrow_mut();
             match parser.token {
                 token::Eof => break,
-                _ => ret.push(parser.parse_impl_item_with_outer_attributes())
+                _ => ret.push(parser.parse_impl_item())
             }
         }
         self.ensure_complete_parse(false);
@@ -97,10 +89,9 @@ impl<'a> MacResult for ParserAnyMacro<'a> {
     }
 
     fn make_stmt(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Stmt>> {
-        let attrs = self.parser.borrow_mut().parse_outer_attributes();
-        let ret = self.parser.borrow_mut().parse_stmt(attrs);
+        let ret = self.parser.borrow_mut().parse_stmt();
         self.ensure_complete_parse(true);
-        Some(ret)
+        ret
     }
 }
 
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index f60ac8f3f33..b53bb4bc75e 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -37,7 +37,6 @@
 #![feature(staged_api)]
 #![feature(std_misc)]
 #![feature(unicode)]
-#![feature(io)]
 #![feature(path_ext)]
 
 extern crate arena;
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index db5583cf13a..a5dd4f22224 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -19,9 +19,8 @@ use ptr::P;
 /// A parser that can parse attributes.
 pub trait ParserAttr {
     fn parse_outer_attributes(&mut self) -> Vec<ast::Attribute>;
+    fn parse_inner_attributes(&mut self) -> Vec<ast::Attribute>;
     fn parse_attribute(&mut self, permit_inner: bool) -> ast::Attribute;
-    fn parse_inner_attrs_and_next(&mut self)
-                                  -> (Vec<ast::Attribute>, Vec<ast::Attribute>);
     fn parse_meta_item(&mut self) -> P<ast::MetaItem>;
     fn parse_meta_seq(&mut self) -> Vec<P<ast::MetaItem>>;
     fn parse_optional_meta(&mut self) -> Vec<P<ast::MetaItem>>;
@@ -118,45 +117,40 @@ impl<'a> ParserAttr for Parser<'a> {
 
     /// Parse attributes that appear after the opening of an item. These should
     /// be preceded by an exclamation mark, but we accept and warn about one
-    /// terminated by a semicolon. In addition to a vector of inner attributes,
-    /// this function also returns a vector that may contain the first outer
-    /// attribute of the next item (since we can't know whether the attribute
-    /// is an inner attribute of the containing item or an outer attribute of
-    /// the first contained item until we see the semi).
-
-    /// matches inner_attrs* outer_attr?
-    /// you can make the 'next' field an Option, but the result is going to be
-    /// more useful as a vector.
-    fn parse_inner_attrs_and_next(&mut self)
-                                  -> (Vec<ast::Attribute> , Vec<ast::Attribute> ) {
-        let mut inner_attrs: Vec<ast::Attribute> = Vec::new();
-        let mut next_outer_attrs: Vec<ast::Attribute> = Vec::new();
+    /// terminated by a semicolon.
+
+    /// matches inner_attrs*
+    fn parse_inner_attributes(&mut self) -> Vec<ast::Attribute> {
+        let mut attrs: Vec<ast::Attribute> = vec![];
         loop {
-            let attr = match self.token {
+            match self.token {
                 token::Pound => {
-                    self.parse_attribute(true)
+                    // Don't even try to parse if it's not an inner attribute.
+                    if !self.look_ahead(1, |t| t == &token::Not) {
+                        break;
+                    }
+
+                    let attr = self.parse_attribute(true);
+                    assert!(attr.node.style == ast::AttrInner);
+                    attrs.push(attr);
                 }
                 token::DocComment(s) => {
                     // we need to get the position of this token before we bump.
                     let Span { lo, hi, .. } = self.span;
-                    self.bump();
-                    attr::mk_sugared_doc_attr(attr::mk_attr_id(),
-                                              self.id_to_interned_str(s.ident()),
-                                              lo,
-                                              hi)
-                }
-                _ => {
-                    break;
+                    let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(),
+                                                         self.id_to_interned_str(s.ident()),
+                                                         lo, hi);
+                    if attr.node.style == ast::AttrInner {
+                        attrs.push(attr);
+                        self.bump();
+                    } else {
+                        break;
+                    }
                 }
-            };
-            if attr.node.style == ast::AttrInner {
-                inner_attrs.push(attr);
-            } else {
-                next_outer_attrs.push(attr);
-                break;
+                _ => break
             }
         }
-        (inner_attrs, next_outer_attrs)
+        attrs
     }
 
     /// matches meta_item = IDENT
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index f542246705c..82ba873e54b 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -96,9 +96,7 @@ pub fn parse_crate_attrs_from_file(
     cfg: ast::CrateConfig,
     sess: &ParseSess
 ) -> Vec<ast::Attribute> {
-    let mut parser = new_parser_from_file(sess, cfg, input);
-    let (inner, _) = parser.parse_inner_attrs_and_next();
-    inner
+    new_parser_from_file(sess, cfg, input).parse_inner_attributes()
 }
 
 pub fn parse_crate_from_source_str(name: String,
@@ -122,8 +120,7 @@ pub fn parse_crate_attrs_from_source_str(name: String,
                                            cfg,
                                            name,
                                            source);
-    let (inner, _) = maybe_aborted(p.parse_inner_attrs_and_next(),p);
-    inner
+    maybe_aborted(p.parse_inner_attributes(), p)
 }
 
 pub fn parse_expr_from_source_str(name: String,
@@ -141,7 +138,7 @@ pub fn parse_item_from_source_str(name: String,
                                   sess: &ParseSess)
                                   -> Option<P<ast::Item>> {
     let mut p = new_parser_from_source_str(sess, cfg, name, source);
-    maybe_aborted(p.parse_item_with_outer_attributes(),p)
+    maybe_aborted(p.parse_item(),p)
 }
 
 pub fn parse_meta_from_source_str(name: String,
@@ -156,16 +153,15 @@ pub fn parse_meta_from_source_str(name: String,
 pub fn parse_stmt_from_source_str(name: String,
                                   source: String,
                                   cfg: ast::CrateConfig,
-                                  attrs: Vec<ast::Attribute> ,
                                   sess: &ParseSess)
-                                  -> P<ast::Stmt> {
+                                  -> Option<P<ast::Stmt>> {
     let mut p = new_parser_from_source_str(
         sess,
         cfg,
         name,
         source
     );
-    maybe_aborted(p.parse_stmt(attrs),p)
+    maybe_aborted(p.parse_stmt(), p)
 }
 
 // Note: keep in sync with `with_hygiene::parse_tts_from_source_str`
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index ea1c1705514..bf2b2c0afe6 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -39,7 +39,7 @@ use ast::{LitStr, LitInt, Local, LocalLet};
 use ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces};
 use ast::{MutImmutable, MutMutable, Mac_, MacInvocTT, MatchSource};
 use ast::{MutTy, BiMul, Mutability};
-use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, NodeId, UnNot};
+use ast::{MethodImplItem, NamedField, UnNeg, NoReturn, UnNot};
 use ast::{Pat, PatEnum, PatIdent, PatLit, PatRange, PatRegion, PatStruct};
 use ast::{PatTup, PatBox, PatWild, PatWildMulti, PatWildSingle};
 use ast::{PolyTraitRef, QSelf};
@@ -77,8 +77,8 @@ use owned_slice::OwnedSlice;
 
 use std::collections::HashSet;
 use std::io::prelude::*;
-use std::iter;
 use std::mem;
+#[cfg(stage0)]
 use std::num::Float;
 use std::path::{Path, PathBuf};
 use std::rc::Rc;
@@ -117,11 +117,6 @@ pub enum BoundParsingMode {
     Modified,
 }
 
-/// The `Err` case indicates a failure to parse any kind of item.
-/// The attributes are returned.
-type MaybeItem = Result<P<Item>, Vec<Attribute>>;
-
-
 /// Possibly accept an `token::Interpolated` expression (a pre-parsed expression
 /// dropped into the token stream, which happens while parsing the result of
 /// macro expansion). Placement of these is not as complex as I feared it would
@@ -208,7 +203,7 @@ macro_rules! maybe_whole {
             }
         }
     );
-    (Some $p:expr, $constructor:ident) => (
+    (Some deref $p:expr, $constructor:ident) => (
         {
             let found = match ($p).token {
                 token::Interpolated(token::$constructor(_)) => {
@@ -217,7 +212,7 @@ macro_rules! maybe_whole {
                 _ => None
             };
             if let Some(token::Interpolated(token::$constructor(x))) = found {
-                return Some(x.clone());
+                return Some((*x).clone());
             }
         }
     );
@@ -749,7 +744,7 @@ impl<'a> Parser<'a> {
         // would encounter a `>` and stop. This lets the parser handle trailing
         // commas in generic parameters, because it can stop either after
         // parsing a type or after parsing a comma.
-        for i in iter::count(0, 1) {
+        for i in 0.. {
             if self.check(&token::Gt)
                 || self.token == token::BinOp(token::Shr)
                 || self.token == token::Ge
@@ -1240,41 +1235,6 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parses `type Foo;` in a trait declaration only. The `type` keyword has
-    /// already been parsed.
-    fn parse_assoc_ty_in_trait(&mut self, attrs: Vec<Attribute>)
-                               -> P<TraitItem> {
-        let TyParam {id, ident, bounds, default, span} = self.parse_ty_param();
-        self.expect(&token::Semi);
-        P(TraitItem {
-            id: id,
-            ident: ident,
-            attrs: attrs,
-            node: TypeTraitItem(bounds, default),
-            span: span,
-        })
-    }
-
-    /// Parses `type Foo = TYPE;` in an implementation declaration only. The
-    /// `type` keyword has already been parsed.
-    fn parse_assoc_ty_in_impl(&mut self, attrs: Vec<Attribute>, vis: Visibility)
-                              -> P<ImplItem> {
-        let lo = self.span.lo;
-        let ident = self.parse_ident();
-        self.expect(&token::Eq);
-        let typ = self.parse_ty_sum();
-        let hi = self.span.hi;
-        self.expect(&token::Semi);
-        P(ImplItem {
-            id: ast::DUMMY_NODE_ID,
-            span: mk_sp(lo, hi),
-            ident: ident,
-            vis: vis,
-            attrs: attrs,
-            node: TypeImplItem(typ),
-        })
-    }
-
     /// Parse the items in a trait declaration
     pub fn parse_trait_items(&mut self) -> Vec<P<TraitItem>> {
         self.parse_unspanned_seq(
@@ -1282,13 +1242,14 @@ impl<'a> Parser<'a> {
             &token::CloseDelim(token::Brace),
             seq_sep_none(),
             |p| {
+            let lo = p.span.lo;
             let mut attrs = p.parse_outer_attributes();
 
-            if p.eat_keyword(keywords::Type) {
-                p.parse_assoc_ty_in_trait(attrs)
+            let (name, node) = if p.eat_keyword(keywords::Type) {
+                let TyParam {ident, bounds, default, ..} = p.parse_ty_param();
+                p.expect(&token::Semi);
+                (ident, TypeTraitItem(bounds, default))
             } else {
-                let lo = p.span.lo;
-
                 let style = p.parse_unsafety();
                 let abi = if p.eat_keyword(keywords::Extern) {
                     p.parse_opt_abi().unwrap_or(abi::C)
@@ -1316,7 +1277,6 @@ impl<'a> Parser<'a> {
                     explicit_self: explicit_self,
                 };
 
-                let hi = p.last_span.hi;
                 let body = match p.token {
                   token::Semi => {
                     p.bump();
@@ -1337,15 +1297,16 @@ impl<'a> Parser<'a> {
                                        token_str)[..])
                   }
                 };
+                (ident, ast::MethodTraitItem(sig, body))
+            };
 
-                P(TraitItem {
-                    id: ast::DUMMY_NODE_ID,
-                    ident: ident,
-                    attrs: attrs,
-                    node: ast::MethodTraitItem(sig, body),
-                    span: mk_sp(lo, hi),
-                })
-            }
+            P(TraitItem {
+                id: ast::DUMMY_NODE_ID,
+                ident: name,
+                attrs: attrs,
+                node: node,
+                span: mk_sp(lo, p.last_span.hi),
+            })
         })
     }
 
@@ -3647,41 +3608,47 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// Get an expected item after attributes error message.
-    fn expected_item_err(attrs: &[Attribute]) -> &'static str {
-        match attrs.last() {
+    /// Emit an expected item after attributes error.
+    fn expected_item_err(&self, attrs: &[Attribute]) {
+        let message = match attrs.last() {
             Some(&Attribute { node: ast::Attribute_ { is_sugared_doc: true, .. }, .. }) => {
                 "expected item after doc comment"
             }
             _ => "expected item after attributes",
-        }
+        };
+
+        self.span_err(self.last_span, message);
     }
 
     /// Parse a statement. may include decl.
-    /// Precondition: any attributes are parsed already
-    pub fn parse_stmt(&mut self, item_attrs: Vec<Attribute>) -> P<Stmt> {
-        maybe_whole!(self, NtStmt);
+    pub fn parse_stmt(&mut self) -> Option<P<Stmt>> {
+        self.parse_stmt_().map(P)
+    }
+
+    fn parse_stmt_(&mut self) -> Option<Stmt> {
+        maybe_whole!(Some deref self, NtStmt);
 
         fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
             // If we have attributes then we should have an item
             if !attrs.is_empty() {
-                let last_span = p.last_span;
-                p.span_err(last_span, Parser::expected_item_err(attrs));
+                p.expected_item_err(attrs);
             }
         }
 
         let lo = self.span.lo;
-        if self.check_keyword(keywords::Let) {
-            check_expected_item(self, &item_attrs[..]);
+        let attrs = self.parse_outer_attributes();
+
+        Some(if self.check_keyword(keywords::Let) {
+            check_expected_item(self, &attrs);
             self.expect_keyword(keywords::Let);
             let decl = self.parse_let();
-            P(spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
+            spanned(lo, decl.span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID))
         } else if self.token.is_ident()
             && !self.token.is_any_keyword()
             && self.look_ahead(1, |t| *t == token::Not) {
             // it's a macro invocation:
 
-            check_expected_item(self, &item_attrs[..]);
+            check_expected_item(self, &attrs);
 
             // Potential trouble: if we allow macros with paths instead of
             // idents, we'd need to look ahead past the whole path here...
@@ -3728,12 +3695,11 @@ impl<'a> Parser<'a> {
             };
 
             if id.name == token::special_idents::invalid.name {
-                P(spanned(lo,
-                          hi,
-                          StmtMac(P(spanned(lo,
+                spanned(lo, hi,
+                        StmtMac(P(spanned(lo,
                                           hi,
                                           MacInvocTT(pth, tts, EMPTY_CTXT))),
-                                  style)))
+                                  style))
             } else {
                 // if it has a special ident, it's definitely an item
                 //
@@ -3747,35 +3713,38 @@ impl<'a> Parser<'a> {
                                        followed by a semicolon");
                     }
                 }
-                P(spanned(lo, hi, StmtDecl(
+                spanned(lo, hi, StmtDecl(
                     P(spanned(lo, hi, DeclItem(
                         self.mk_item(
                             lo, hi, id /*id is good here*/,
                             ItemMac(spanned(lo, hi, MacInvocTT(pth, tts, EMPTY_CTXT))),
                             Inherited, Vec::new(/*no attrs*/))))),
-                    ast::DUMMY_NODE_ID)))
+                    ast::DUMMY_NODE_ID))
             }
         } else {
-            let found_attrs = !item_attrs.is_empty();
-            let item_err = Parser::expected_item_err(&item_attrs[..]);
-            match self.parse_item_(item_attrs, false) {
-                Ok(i) => {
+            match self.parse_item_(attrs, false) {
+                Some(i) => {
                     let hi = i.span.hi;
                     let decl = P(spanned(lo, hi, DeclItem(i)));
-                    P(spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
+                    spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID))
                 }
-                Err(_) => {
-                    if found_attrs {
-                        let last_span = self.last_span;
-                        self.span_err(last_span, item_err);
+                None => {
+                    // Do not attempt to parse an expression if we're done here.
+                    if self.token == token::Semi {
+                        self.bump();
+                        return None;
+                    }
+
+                    if self.token == token::CloseDelim(token::Brace) {
+                        return None;
                     }
 
                     // Remainder are line-expr stmts.
                     let e = self.parse_expr_res(RESTRICTION_STMT_EXPR);
-                    P(spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID)))
+                    spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID))
                 }
             }
-        }
+        })
     }
 
     /// Is this expression a successfully-parsed statement?
@@ -3798,153 +3767,110 @@ impl<'a> Parser<'a> {
                                  "place this code inside a block");
         }
 
-        return self.parse_block_tail_(lo, DefaultBlock, Vec::new());
+        self.parse_block_tail(lo, DefaultBlock)
     }
 
     /// Parse a block. Inner attrs are allowed.
-    fn parse_inner_attrs_and_block(&mut self)
-        -> (Vec<Attribute> , P<Block>) {
-
+    fn parse_inner_attrs_and_block(&mut self) -> (Vec<Attribute>, P<Block>) {
         maybe_whole!(pair_empty self, NtBlock);
 
         let lo = self.span.lo;
         self.expect(&token::OpenDelim(token::Brace));
-        let (inner, next) = self.parse_inner_attrs_and_next();
-
-        (inner, self.parse_block_tail_(lo, DefaultBlock, next))
+        (self.parse_inner_attributes(),
+         self.parse_block_tail(lo, DefaultBlock))
     }
 
+    /// Parse the rest of a block expression or function body
     /// Precondition: already parsed the '{'.
     fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
-        self.parse_block_tail_(lo, s, Vec::new())
-    }
-
-    /// Parse the rest of a block expression or function body
-    fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
-                         first_item_attrs: Vec<Attribute>) -> P<Block> {
         let mut stmts = vec![];
         let mut expr = None;
-        let mut attributes_box = first_item_attrs;
 
-        while self.token != token::CloseDelim(token::Brace) {
-            // parsing items even when they're not allowed lets us give
-            // better error messages and recover more gracefully.
-            attributes_box.push_all(&self.parse_outer_attributes());
-            match self.token {
-                token::Semi => {
-                    if !attributes_box.is_empty() {
-                        let last_span = self.last_span;
-                        self.span_err(last_span,
-                                      Parser::expected_item_err(&attributes_box[..]));
-                        attributes_box = Vec::new();
-                    }
-                    self.bump(); // empty
-                }
-                token::CloseDelim(token::Brace) => {
-                    // fall through and out.
+        while !self.eat(&token::CloseDelim(token::Brace)) {
+            let Spanned {node, span} = if let Some(s) = self.parse_stmt_() {
+                s
+            } else {
+                // Found only `;` or `}`.
+                continue;
+            };
+            match node {
+                StmtExpr(e, _) => {
+                    self.handle_expression_like_statement(e, span, &mut stmts, &mut expr);
                 }
-                _ => {
-                    let stmt = self.parse_stmt(attributes_box);
-                    attributes_box = Vec::new();
-                    stmt.and_then(|Spanned {node, span}| match node {
-                        StmtExpr(e, stmt_id) => {
-                            self.handle_expression_like_statement(e,
-                                                                  stmt_id,
-                                                                  span,
-                                                                  &mut stmts,
-                                                                  &mut expr);
+                StmtMac(mac, MacStmtWithoutBraces) => {
+                    // statement macro without braces; might be an
+                    // expr depending on whether a semicolon follows
+                    match self.token {
+                        token::Semi => {
+                            stmts.push(P(Spanned {
+                                node: StmtMac(mac, MacStmtWithSemicolon),
+                                span: span,
+                            }));
+                            self.bump();
                         }
-                        StmtMac(mac, MacStmtWithoutBraces) => {
-                            // statement macro without braces; might be an
-                            // expr depending on whether a semicolon follows
-                            match self.token {
-                                token::Semi => {
-                                    stmts.push(P(Spanned {
-                                        node: StmtMac(mac,
-                                                      MacStmtWithSemicolon),
-                                        span: span,
-                                    }));
-                                    self.bump();
-                                }
-                                _ => {
-                                    let e = self.mk_mac_expr(span.lo,
-                                                             span.hi,
-                                                             mac.and_then(|m| m.node));
-                                    let e = self.parse_dot_or_call_expr_with(e);
-                                    let e = self.parse_more_binops(e, 0);
-                                    let e = self.parse_assign_expr_with(e);
-                                    self.handle_expression_like_statement(
-                                        e,
-                                        ast::DUMMY_NODE_ID,
-                                        span,
-                                        &mut stmts,
-                                        &mut expr);
-                                }
-                            }
+                        _ => {
+                            let e = self.mk_mac_expr(span.lo, span.hi,
+                                                     mac.and_then(|m| m.node));
+                            let e = self.parse_dot_or_call_expr_with(e);
+                            let e = self.parse_more_binops(e, 0);
+                            let e = self.parse_assign_expr_with(e);
+                            self.handle_expression_like_statement(
+                                e,
+                                span,
+                                &mut stmts,
+                                &mut expr);
                         }
-                        StmtMac(m, style) => {
-                            // statement macro; might be an expr
-                            match self.token {
-                                token::Semi => {
-                                    stmts.push(P(Spanned {
-                                        node: StmtMac(m,
-                                                      MacStmtWithSemicolon),
-                                        span: span,
-                                    }));
-                                    self.bump();
-                                }
-                                token::CloseDelim(token::Brace) => {
-                                    // if a block ends in `m!(arg)` without
-                                    // a `;`, it must be an expr
-                                    expr = Some(
-                                        self.mk_mac_expr(span.lo,
-                                                         span.hi,
+                    }
+                }
+                StmtMac(m, style) => {
+                    // statement macro; might be an expr
+                    match self.token {
+                        token::Semi => {
+                            stmts.push(P(Spanned {
+                                node: StmtMac(m, MacStmtWithSemicolon),
+                                span: span,
+                            }));
+                            self.bump();
+                        }
+                        token::CloseDelim(token::Brace) => {
+                            // if a block ends in `m!(arg)` without
+                            // a `;`, it must be an expr
+                            expr = Some(self.mk_mac_expr(span.lo, span.hi,
                                                          m.and_then(|x| x.node)));
-                                }
-                                _ => {
-                                    stmts.push(P(Spanned {
-                                        node: StmtMac(m, style),
-                                        span: span
-                                    }));
-                                }
-                            }
                         }
-                        _ => { // all other kinds of statements:
-                            if classify::stmt_ends_with_semi(&node) {
-                                self.commit_stmt_expecting(token::Semi);
-                            }
-
+                        _ => {
                             stmts.push(P(Spanned {
-                                node: node,
+                                node: StmtMac(m, style),
                                 span: span
                             }));
                         }
-                    })
+                    }
                 }
-            }
-        }
+                _ => { // all other kinds of statements:
+                    if classify::stmt_ends_with_semi(&node) {
+                        self.commit_stmt_expecting(token::Semi);
+                    }
 
-        if !attributes_box.is_empty() {
-            let last_span = self.last_span;
-            self.span_err(last_span,
-                          Parser::expected_item_err(&attributes_box[..]));
+                    stmts.push(P(Spanned {
+                        node: node,
+                        span: span
+                    }));
+                }
+            }
         }
 
-        let hi = self.span.hi;
-        self.bump();
         P(ast::Block {
             stmts: stmts,
             expr: expr,
             id: ast::DUMMY_NODE_ID,
             rules: s,
-            span: mk_sp(lo, hi),
+            span: mk_sp(lo, self.last_span.hi),
         })
     }
 
     fn handle_expression_like_statement(
             &mut self,
             e: P<Expr>,
-            stmt_id: NodeId,
             span: Span,
             stmts: &mut Vec<P<Stmt>>,
             last_block_expr: &mut Option<P<Expr>>) {
@@ -3964,14 +3890,14 @@ impl<'a> Parser<'a> {
                     expn_id: span.expn_id,
                 };
                 stmts.push(P(Spanned {
-                    node: StmtSemi(e, stmt_id),
+                    node: StmtSemi(e, ast::DUMMY_NODE_ID),
                     span: span_with_semi,
                 }));
             }
             token::CloseDelim(token::Brace) => *last_block_expr = Some(e),
             _ => {
                 stmts.push(P(Spanned {
-                    node: StmtExpr(e, stmt_id),
+                    node: StmtExpr(e, ast::DUMMY_NODE_ID),
                     span: span
                 }));
             }
@@ -4626,14 +4552,30 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse an impl item.
-    pub fn parse_impl_item_with_outer_attributes(&mut self) -> P<ImplItem> {
-        let attrs = self.parse_outer_attributes();
+    pub fn parse_impl_item(&mut self) -> P<ImplItem> {
+        let lo = self.span.lo;
+        let mut attrs = self.parse_outer_attributes();
         let vis = self.parse_visibility();
-        if self.eat_keyword(keywords::Type) {
-            self.parse_assoc_ty_in_impl(attrs, vis)
+        let (name, node) = if self.eat_keyword(keywords::Type) {
+            let name = self.parse_ident();
+            self.expect(&token::Eq);
+            let typ = self.parse_ty_sum();
+            self.expect(&token::Semi);
+            (name, TypeImplItem(typ))
         } else {
-            self.parse_method(attrs, vis)
-        }
+            let (name, inner_attrs, node) = self.parse_impl_method(vis);
+            attrs.extend(inner_attrs.into_iter());
+            (name, node)
+        };
+
+        P(ImplItem {
+            id: ast::DUMMY_NODE_ID,
+            span: mk_sp(lo, self.last_span.hi),
+            ident: name,
+            vis: vis,
+            attrs: attrs,
+            node: node
+        })
     }
 
     fn complain_if_pub_macro(&mut self, visa: Visibility, span: Span) {
@@ -4647,76 +4589,58 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parse a method in a trait impl, starting with `attrs` attributes.
-    pub fn parse_method(&mut self,
-                        attrs: Vec<Attribute>,
-                        vis: Visibility)
-                        -> P<ImplItem> {
-        let lo = self.span.lo;
-
+    /// Parse a method or a macro invocation in a trait impl.
+    fn parse_impl_method(&mut self, vis: Visibility)
+                         -> (Ident, Vec<ast::Attribute>, ast::ImplItem_) {
         // code copied from parse_macro_use_or_failure... abstraction!
-        let (method_, hi, new_attrs, ident) = {
-            if !self.token.is_any_keyword()
-                && self.look_ahead(1, |t| *t == token::Not)
-                && (self.look_ahead(2, |t| *t == token::OpenDelim(token::Paren))
-                    || self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace))) {
-                // method macro.
+        if !self.token.is_any_keyword()
+            && self.look_ahead(1, |t| *t == token::Not)
+            && (self.look_ahead(2, |t| *t == token::OpenDelim(token::Paren))
+                || self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace))) {
+            // method macro.
 
-                let last_span = self.last_span;
-                self.complain_if_pub_macro(vis, last_span);
-
-                let pth = self.parse_path(NoTypesAllowed);
-                self.expect(&token::Not);
-
-                // eat a matched-delimiter token tree:
-                let delim = self.expect_open_delim();
-                let tts = self.parse_seq_to_end(&token::CloseDelim(delim),
-                                                seq_sep_none(),
-                                                |p| p.parse_token_tree());
-                let m_ = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
-                let m: ast::Mac = codemap::Spanned { node: m_,
-                                                 span: mk_sp(self.span.lo,
-                                                             self.span.hi) };
-                if delim != token::Brace {
-                    self.expect(&token::Semi)
-                }
-                (ast::MacImplItem(m), self.span.hi, attrs,
-                 token::special_idents::invalid)
-            } else {
-                let unsafety = self.parse_unsafety();
-                let abi = if self.eat_keyword(keywords::Extern) {
-                    self.parse_opt_abi().unwrap_or(abi::C)
-                } else {
-                    abi::Rust
-                };
-                self.expect_keyword(keywords::Fn);
-                let ident = self.parse_ident();
-                let mut generics = self.parse_generics();
-                let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
-                        p.parse_arg()
-                    });
-                self.parse_where_clause(&mut generics);
-                let (inner_attrs, body) = self.parse_inner_attrs_and_block();
-                let body_span = body.span;
-                let mut new_attrs = attrs;
-                new_attrs.push_all(&inner_attrs[..]);
-                (MethodImplItem(ast::MethodSig {
-                    generics: generics,
-                    abi: abi,
-                    explicit_self: explicit_self,
-                    unsafety: unsafety,
-                    decl: decl
-                 }, body), body_span.hi, new_attrs, ident)
+            let last_span = self.last_span;
+            self.complain_if_pub_macro(vis, last_span);
+
+            let pth = self.parse_path(NoTypesAllowed);
+            self.expect(&token::Not);
+
+            // eat a matched-delimiter token tree:
+            let delim = self.expect_open_delim();
+            let tts = self.parse_seq_to_end(&token::CloseDelim(delim),
+                                            seq_sep_none(),
+                                            |p| p.parse_token_tree());
+            let m_ = ast::MacInvocTT(pth, tts, EMPTY_CTXT);
+            let m: ast::Mac = codemap::Spanned { node: m_,
+                                                span: mk_sp(self.span.lo,
+                                                            self.span.hi) };
+            if delim != token::Brace {
+                self.expect(&token::Semi)
             }
-        };
-        P(ImplItem {
-            id: ast::DUMMY_NODE_ID,
-            attrs: new_attrs,
-            vis: vis,
-            ident: ident,
-            node: method_,
-            span: mk_sp(lo, hi),
-        })
+            (token::special_idents::invalid, vec![], ast::MacImplItem(m))
+        } else {
+            let unsafety = self.parse_unsafety();
+            let abi = if self.eat_keyword(keywords::Extern) {
+                self.parse_opt_abi().unwrap_or(abi::C)
+            } else {
+                abi::Rust
+            };
+            self.expect_keyword(keywords::Fn);
+            let ident = self.parse_ident();
+            let mut generics = self.parse_generics();
+            let (explicit_self, decl) = self.parse_fn_decl_with_self(|p| {
+                    p.parse_arg()
+                });
+            self.parse_where_clause(&mut generics);
+            let (inner_attrs, body) = self.parse_inner_attrs_and_block();
+            (ident, inner_attrs, MethodImplItem(ast::MethodSig {
+                generics: generics,
+                abi: abi,
+                explicit_self: explicit_self,
+                unsafety: unsafety,
+                decl: decl
+             }, body))
+        }
     }
 
     /// Parse trait Foo { ... }
@@ -4747,28 +4671,6 @@ impl<'a> Parser<'a> {
         (ident, ItemTrait(unsafety, tps, bounds, meths), None)
     }
 
-    fn parse_impl_items(&mut self) -> (Vec<P<ImplItem>>, Vec<Attribute>) {
-        let mut impl_items = Vec::new();
-        self.expect(&token::OpenDelim(token::Brace));
-        let (inner_attrs, mut method_attrs) =
-            self.parse_inner_attrs_and_next();
-        loop {
-            method_attrs.extend(self.parse_outer_attributes().into_iter());
-            if method_attrs.is_empty() && self.eat(&token::CloseDelim(token::Brace)) {
-                break;
-            }
-
-            let vis = self.parse_visibility();
-            impl_items.push(if self.eat_keyword(keywords::Type) {
-                self.parse_assoc_ty_in_impl(method_attrs, vis)
-            } else {
-                self.parse_method(method_attrs, vis)
-            });
-            method_attrs = vec![];
-        }
-        (impl_items, inner_attrs)
-    }
-
     /// Parses items implementations variants
     ///    impl<T> Foo { ... }
     ///    impl<T> ToString for &'static T { ... }
@@ -4835,7 +4737,14 @@ impl<'a> Parser<'a> {
                 ty = self.parse_ty_sum();
             }
             self.parse_where_clause(&mut generics);
-            let (impl_items, attrs) = self.parse_impl_items();
+
+            self.expect(&token::OpenDelim(token::Brace));
+            let attrs = self.parse_inner_attributes();
+
+            let mut impl_items = vec![];
+            while !self.eat(&token::CloseDelim(token::Brace)) {
+                impl_items.push(self.parse_impl_item());
+            }
 
             (ast_util::impl_pretty_name(&opt_trait, Some(&*ty)),
              ItemImpl(unsafety, polarity, generics, opt_trait, ty, impl_items),
@@ -5074,53 +4983,16 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Given a termination token and a vector of already-parsed
-    /// attributes (of length 0 or 1), parse all of the items in a module
-    fn parse_mod_items(&mut self,
-                       term: token::Token,
-                       first_item_attrs: Vec<Attribute>,
-                       inner_lo: BytePos)
-                       -> Mod {
-        // Parse all of the items up to closing or an attribute.
-
-        let mut attrs = first_item_attrs;
-        attrs.push_all(&self.parse_outer_attributes());
+    /// Given a termination token, parse all of the items in a module
+    fn parse_mod_items(&mut self, term: &token::Token, inner_lo: BytePos) -> Mod {
         let mut items = vec![];
-
-        loop {
-            match self.parse_item_(attrs, true) {
-                Err(returned_attrs) => {
-                    attrs = returned_attrs;
-                    break
-                }
-                Ok(item) => {
-                    attrs = self.parse_outer_attributes();
-                    items.push(item)
-                }
-            }
-        }
-
-        // don't think this other loop is even necessary....
-
-        while self.token != term {
-            let mut attrs = mem::replace(&mut attrs, vec![]);
-            attrs.push_all(&self.parse_outer_attributes());
-            debug!("parse_mod_items: parse_item_(attrs={:?})", attrs);
-            match self.parse_item_(attrs, true /* macros allowed */) {
-              Ok(item) => items.push(item),
-              Err(_) => {
-                  let token_str = self.this_token_to_string();
-                  self.fatal(&format!("expected item, found `{}`",
-                                     token_str))
-              }
-            }
+        while let Some(item) = self.parse_item() {
+            items.push(item);
         }
 
-        if !attrs.is_empty() {
-            // We parsed attributes for the first item but didn't find it
-            let last_span = self.last_span;
-            self.span_err(last_span,
-                          Parser::expected_item_err(&attrs[..]));
+        if !self.eat(term) {
+            let token_str = self.this_token_to_string();
+            self.fatal(&format!("expected item, found `{}`", token_str))
         }
 
         ast::Mod {
@@ -5158,12 +5030,11 @@ impl<'a> Parser<'a> {
             let mod_inner_lo = self.span.lo;
             let old_owns_directory = self.owns_directory;
             self.owns_directory = true;
-            let (inner, next) = self.parse_inner_attrs_and_next();
-            let m = self.parse_mod_items(token::CloseDelim(token::Brace), next, mod_inner_lo);
-            self.expect(&token::CloseDelim(token::Brace));
+            let attrs = self.parse_inner_attributes();
+            let m = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo);
             self.owns_directory = old_owns_directory;
             self.pop_mod_path();
-            (id, ItemMod(m), Some(inner))
+            (id, ItemMod(m), Some(attrs))
         }
     }
 
@@ -5290,11 +5161,10 @@ impl<'a> Parser<'a> {
                                      Some(name),
                                      id_sp);
         let mod_inner_lo = p0.span.lo;
-        let (mod_attrs, next) = p0.parse_inner_attrs_and_next();
-        let first_item_outer_attrs = next;
-        let m0 = p0.parse_mod_items(token::Eof, first_item_outer_attrs, mod_inner_lo);
+        let mod_attrs = p0.parse_inner_attributes();
+        let m0 = p0.parse_mod_items(&token::Eof, mod_inner_lo);
         self.sess.included_mod_stack.borrow_mut().pop();
-        return (ast::ItemMod(m0), mod_attrs);
+        (ast::ItemMod(m0), mod_attrs)
     }
 
     /// Parse a function declaration from a foreign module
@@ -5341,20 +5211,6 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// At this point, this is essentially a wrapper for
-    /// parse_foreign_items.
-    fn parse_foreign_mod_items(&mut self,
-                               abi: abi::Abi,
-                               first_item_attrs: Vec<Attribute>)
-                               -> ForeignMod {
-        let foreign_items = self.parse_foreign_items(first_item_attrs);
-        assert!(self.token == token::CloseDelim(token::Brace));
-        ast::ForeignMod {
-            abi: abi,
-            items: foreign_items
-        }
-    }
-
     /// Parse extern crate links
     ///
     /// # Examples
@@ -5433,24 +5289,31 @@ impl<'a> Parser<'a> {
                               lo: BytePos,
                               opt_abi: Option<abi::Abi>,
                               visibility: Visibility,
-                              attrs: Vec<Attribute>)
+                              mut attrs: Vec<Attribute>)
                               -> P<Item> {
-
         self.expect(&token::OpenDelim(token::Brace));
 
         let abi = opt_abi.unwrap_or(abi::C);
 
-        let (inner, next) = self.parse_inner_attrs_and_next();
-        let m = self.parse_foreign_mod_items(abi, next);
+        attrs.extend(self.parse_inner_attributes().into_iter());
+
+        let mut foreign_items = vec![];
+        while let Some(item) = self.parse_foreign_item() {
+            foreign_items.push(item);
+        }
         self.expect(&token::CloseDelim(token::Brace));
 
         let last_span = self.last_span;
+        let m = ast::ForeignMod {
+            abi: abi,
+            items: foreign_items
+        };
         self.mk_item(lo,
                      last_span.hi,
                      special_idents::invalid,
                      ItemForeignMod(m),
                      visibility,
-                     maybe_append(attrs, Some(inner)))
+                     attrs)
     }
 
     /// Parse type Foo = Bar;
@@ -5592,12 +5455,11 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parse one of the items allowed by the flags; on failure,
-    /// return `Err(remaining_attrs)`.
+    /// Parse one of the items allowed by the flags.
     /// NB: this function no longer parses the items inside an
     /// extern crate.
     fn parse_item_(&mut self, attrs: Vec<Attribute>,
-                   macros_allowed: bool) -> MaybeItem {
+                   macros_allowed: bool) -> Option<P<Item>> {
         let nt_item = match self.token {
             token::Interpolated(token::NtItem(ref item)) => {
                 Some((**item).clone())
@@ -5610,7 +5472,7 @@ impl<'a> Parser<'a> {
                 let mut attrs = attrs;
                 mem::swap(&mut item.attrs, &mut attrs);
                 item.attrs.extend(attrs.into_iter());
-                return Ok(P(item));
+                return Some(P(item));
             }
             None => {}
         }
@@ -5631,12 +5493,12 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     attrs);
-            return Ok(item);
+            return Some(item);
         }
 
         if self.eat_keyword(keywords::Extern) {
             if self.eat_keyword(keywords::Crate) {
-                return Ok(self.parse_item_extern_crate(lo, visibility, attrs));
+                return Some(self.parse_item_extern_crate(lo, visibility, attrs));
             }
 
             let opt_abi = self.parse_opt_abi();
@@ -5653,9 +5515,9 @@ impl<'a> Parser<'a> {
                                         item_,
                                         visibility,
                                         maybe_append(attrs, extra_attrs));
-                return Ok(item);
+                return Some(item);
             } else if self.check(&token::OpenDelim(token::Brace)) {
-                return Ok(self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs));
+                return Some(self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs));
             }
 
             let span = self.span;
@@ -5681,7 +5543,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.eat_keyword(keywords::Const) {
             // CONST ITEM
@@ -5698,7 +5560,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.check_keyword(keywords::Unsafe) &&
             self.look_ahead(1, |t| t.is_keyword(keywords::Trait))
@@ -5715,7 +5577,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.check_keyword(keywords::Unsafe) &&
             self.look_ahead(1, |t| t.is_keyword(keywords::Impl))
@@ -5731,7 +5593,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.check_keyword(keywords::Fn) {
             // FUNCTION ITEM
@@ -5745,7 +5607,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.check_keyword(keywords::Unsafe)
             && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) {
@@ -5766,7 +5628,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.eat_keyword(keywords::Mod) {
             // MODULE ITEM
@@ -5779,7 +5641,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.eat_keyword(keywords::Type) {
             // TYPE ITEM
@@ -5791,7 +5653,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.eat_keyword(keywords::Enum) {
             // ENUM ITEM
@@ -5803,7 +5665,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.eat_keyword(keywords::Trait) {
             // TRAIT ITEM
@@ -5816,7 +5678,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.eat_keyword(keywords::Impl) {
             // IMPL ITEM
@@ -5828,7 +5690,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         if self.eat_keyword(keywords::Struct) {
             // STRUCT ITEM
@@ -5840,30 +5702,34 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     maybe_append(attrs, extra_attrs));
-            return Ok(item);
+            return Some(item);
         }
         self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
     }
 
-    /// Parse a foreign item; on failure, return `Err(remaining_attrs)`.
-    fn parse_foreign_item(&mut self, attrs: Vec<Attribute>)
-                          -> Result<P<ForeignItem>, Vec<Attribute>> {
+    /// Parse a foreign item.
+    fn parse_foreign_item(&mut self) -> Option<P<ForeignItem>> {
         let lo = self.span.lo;
 
+        let attrs = self.parse_outer_attributes();
         let visibility = self.parse_visibility();
 
         if self.check_keyword(keywords::Static) {
             // FOREIGN STATIC ITEM
-            return Ok(self.parse_item_foreign_static(visibility, attrs));
+            return Some(self.parse_item_foreign_static(visibility, attrs));
         }
         if self.check_keyword(keywords::Fn) || self.check_keyword(keywords::Unsafe) {
             // FOREIGN FUNCTION ITEM
-            return Ok(self.parse_item_foreign_fn(visibility, attrs));
+            return Some(self.parse_item_foreign_fn(visibility, attrs));
         }
 
         // FIXME #5668: this will occur for a macro invocation:
-        let item = try!(self.parse_macro_use_or_failure(attrs, true, lo, visibility));
-        self.span_fatal(item.span, "macros cannot expand to foreign items");
+        match self.parse_macro_use_or_failure(attrs, true, lo, visibility) {
+            Some(item) => {
+                self.span_fatal(item.span, "macros cannot expand to foreign items");
+            }
+            None => None
+        }
     }
 
     /// This is the fall-through for parsing items.
@@ -5873,7 +5739,7 @@ impl<'a> Parser<'a> {
         macros_allowed: bool,
         lo: BytePos,
         visibility: Visibility
-    ) -> MaybeItem {
+    ) -> Option<P<Item>> {
         if macros_allowed && !self.token.is_any_keyword()
                 && self.look_ahead(1, |t| *t == token::Not)
                 && (self.look_ahead(2, |t| t.is_plain_ident())
@@ -5925,7 +5791,7 @@ impl<'a> Parser<'a> {
                                     item_,
                                     visibility,
                                     attrs);
-            return Ok(item);
+            return Some(item);
         }
 
         // FAILURE TO PARSE ITEM
@@ -5936,16 +5802,22 @@ impl<'a> Parser<'a> {
                 self.span_fatal(last_span, "unmatched visibility `pub`");
             }
         }
-        Err(attrs)
+
+        if !attrs.is_empty() {
+            self.expected_item_err(&attrs);
+        }
+        None
     }
 
+    // HACK(eddyb) staging required for `quote_item!`.
+    #[cfg(stage0)] // SNAP 270a677
     pub fn parse_item_with_outer_attributes(&mut self) -> Option<P<Item>> {
-        let attrs = self.parse_outer_attributes();
-        self.parse_item(attrs)
+        self.parse_item()
     }
 
-    pub fn parse_item(&mut self, attrs: Vec<Attribute>) -> Option<P<Item>> {
-        self.parse_item_(attrs, true).ok()
+    pub fn parse_item(&mut self) -> Option<P<Item>> {
+        let attrs = self.parse_outer_attributes();
+        self.parse_item_(attrs, true)
     }
 
     /// Matches view_path : MOD? non_global_path as IDENT
@@ -6051,52 +5923,13 @@ impl<'a> Parser<'a> {
         P(spanned(lo, self.last_span.hi, ViewPathSimple(rename_to, path)))
     }
 
-    /// Parses a sequence of foreign items. Stops when it finds program
-    /// text that can't be parsed as an item
-    fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute>)
-                           -> Vec<P<ForeignItem>> {
-        let mut attrs = first_item_attrs;
-        attrs.push_all(&self.parse_outer_attributes());
-        let mut foreign_items = Vec::new();
-        loop {
-            match self.parse_foreign_item(attrs) {
-                Ok(foreign_item) => {
-                    foreign_items.push(foreign_item);
-                }
-                Err(returned_attrs) => {
-                    if self.check(&token::CloseDelim(token::Brace)) {
-                        attrs = returned_attrs;
-                        break
-                    }
-                    self.unexpected();
-                }
-            }
-            attrs = self.parse_outer_attributes();
-        }
-
-        if !attrs.is_empty() {
-            let last_span = self.last_span;
-            self.span_err(last_span,
-                          Parser::expected_item_err(&attrs[..]));
-        }
-
-        foreign_items
-    }
-
     /// Parses a source module as a crate. This is the main
     /// entry point for the parser.
     pub fn parse_crate_mod(&mut self) -> Crate {
         let lo = self.span.lo;
-        // parse the crate's inner attrs, maybe (oops) one
-        // of the attrs of an item:
-        let (inner, next) = self.parse_inner_attrs_and_next();
-        let first_item_outer_attrs = next;
-        // parse the items inside the crate:
-        let m = self.parse_mod_items(token::Eof, first_item_outer_attrs, lo);
-
         ast::Crate {
-            module: m,
-            attrs: inner,
+            attrs: self.parse_inner_attributes(),
+            module: self.parse_mod_items(&token::Eof, lo),
             config: self.cfg.clone(),
             span: mk_sp(lo, self.span.lo),
             exported_macros: Vec::new(),
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index 5e858d8a79f..2a47a696b1c 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -121,13 +121,11 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
         debug!("current path: {}",
                ast_util::path_name_i(&self.cx.path));
 
-        if is_test_fn(&self.cx, &*i) || is_bench_fn(&self.cx, &*i) {
+        let i = if is_test_fn(&self.cx, &*i) || is_bench_fn(&self.cx, &*i) {
             match i.node {
                 ast::ItemFn(_, ast::Unsafety::Unsafe, _, _, _) => {
                     let diag = self.cx.span_diagnostic;
-                    diag.span_fatal(i.span,
-                                    "unsafe functions cannot be used for \
-                                     tests");
+                    diag.span_fatal(i.span, "unsafe functions cannot be used for tests");
                 }
                 _ => {
                     debug!("this is a test function");
@@ -142,9 +140,19 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
                     self.tests.push(i.ident);
                     // debug!("have {} test/bench functions",
                     //        cx.testfns.len());
+
+                    // Make all tests public so we can call them from outside
+                    // the module (note that the tests are re-exported and must
+                    // be made public themselves to avoid privacy errors).
+                    i.map(|mut i| {
+                        i.vis = ast::Public;
+                        i
+                    })
                 }
             }
-        }
+        } else {
+            i
+        };
 
         // We don't want to recurse into anything other than mods, since
         // mods or tests inside of functions will break things
diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs
index 89854f5d979..9b570c2b1fe 100644
--- a/src/libsyntax/util/parser_testing.rs
+++ b/src/libsyntax/util/parser_testing.rs
@@ -58,14 +58,14 @@ pub fn string_to_expr (source_str : String) -> P<ast::Expr> {
 /// Parse a string, return an item
 pub fn string_to_item (source_str : String) -> Option<P<ast::Item>> {
     with_error_checking_parse(source_str, |p| {
-        p.parse_item(Vec::new())
+        p.parse_item()
     })
 }
 
 /// Parse a string, return a stmt
 pub fn string_to_stmt(source_str : String) -> P<ast::Stmt> {
     with_error_checking_parse(source_str, |p| {
-        p.parse_stmt(Vec::new())
+        p.parse_stmt().unwrap()
     })
 }
 
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs
index 36225fad221..89960d5d62f 100644
--- a/src/libterm/lib.rs
+++ b/src/libterm/lib.rs
@@ -57,7 +57,6 @@
 #![feature(box_syntax)]
 #![feature(collections)]
 #![feature(int_uint)]
-#![feature(io)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(std_misc)]
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index ca8a60553ab..02ddeea46bf 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -39,13 +39,11 @@
 #![feature(collections)]
 #![feature(core)]
 #![feature(int_uint)]
-#![feature(old_io)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(std_misc)]
-#![feature(io)]
 #![feature(libc)]
-#![feature(set_panic)]
+#![feature(set_stdio)]
 
 extern crate getopts;
 extern crate serialize;
@@ -123,7 +121,6 @@ impl fmt::Display for TestName {
 #[derive(Clone, Copy)]
 enum NamePadding {
     PadNone,
-    #[allow(dead_code)]
     PadOnLeft,
     PadOnRight,
 }
@@ -909,7 +906,6 @@ pub fn run_test(opts: &TestOpts,
         return;
     }
 
-    #[allow(deprecated)] // set_stdout
     fn run_test_inner(desc: TestDesc,
                       monitor_ch: Sender<MonitorMsg>,
                       nocapture: bool,
@@ -921,11 +917,6 @@ pub fn run_test(opts: &TestOpts,
             }
             fn flush(&mut self) -> io::Result<()> { Ok(()) }
         }
-        impl Writer for Sink {
-            fn write_all(&mut self, data: &[u8]) -> std::old_io::IoResult<()> {
-                Writer::write_all(&mut *self.0.lock().unwrap(), data)
-            }
-        }
 
         thread::spawn(move || {
             let data = Arc::new(Mutex::new(Vec::new()));
@@ -937,7 +928,7 @@ pub fn run_test(opts: &TestOpts,
 
             let result_guard = cfg.spawn(move || {
                 if !nocapture {
-                    std::old_io::stdio::set_stdout(box Sink(data2.clone()));
+                    io::set_print(box Sink(data2.clone()));
                     io::set_panic(box Sink(data2));
                 }
                 testfn.invoke(())
diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs
index 42812e1e597..84d86c5746c 100644
--- a/src/libtest/stats.rs
+++ b/src/libtest/stats.rs
@@ -11,9 +11,6 @@
 #![allow(missing_docs)]
 
 use std::cmp::Ordering::{self, Less, Greater, Equal};
-use std::collections::hash_map::Entry::{Occupied, Vacant};
-use std::collections::hash_map;
-use std::hash::Hash;
 use std::mem;
 use std::num::{Float, FromPrimitive};
 
@@ -330,22 +327,6 @@ pub fn winsorize<T: Float + FromPrimitive>(samples: &mut [T], pct: T) {
     }
 }
 
-/// Returns a HashMap with the number of occurrences of every element in the
-/// sequence that the iterator exposes.
-#[cfg(not(stage0))]
-pub fn freq_count<T, U>(iter: T) -> hash_map::HashMap<U, uint>
-  where T: Iterator<Item=U>, U: Eq + Clone + Hash
-{
-    let mut map: hash_map::HashMap<U,uint> = hash_map::HashMap::new();
-    for elem in iter {
-        match map.entry(elem) {
-            Occupied(mut entry) => { *entry.get_mut() += 1; },
-            Vacant(entry) => { entry.insert(1); },
-        }
-    }
-    map
-}
-
 // Test vectors generated from R, using the script src/etc/stat-test-vectors.r.
 
 #[cfg(test)]
diff --git a/src/libunicode/char.rs b/src/libunicode/char.rs
index bcc2820e381..56bc0389b74 100644
--- a/src/libunicode/char.rs
+++ b/src/libunicode/char.rs
@@ -41,6 +41,7 @@ pub use normalize::{decompose_canonical, decompose_compatible, compose};
 pub use tables::normalization::canonical_combining_class;
 pub use tables::UNICODE_VERSION;
 
+#[cfg(stage0)]
 /// Functionality for manipulating `char`.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait CharExt {
@@ -374,6 +375,7 @@ pub trait CharExt {
     fn width(self, is_cjk: bool) -> Option<usize>;
 }
 
+#[cfg(stage0)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl CharExt for char {
     fn is_digit(self, radix: u32) -> bool { C::is_digit(self, radix) }
@@ -467,3 +469,373 @@ impl Iterator for ToUppercase {
     type Item = char;
     fn next(&mut self) -> Option<char> { self.0.take() }
 }
+
+#[cfg(not(stage0))]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[lang = "char"]
+impl char {
+    /// Checks if a `char` parses as a numeric digit in the given radix.
+    ///
+    /// Compared to `is_numeric()`, this function only recognizes the characters
+    /// `0-9`, `a-z` and `A-Z`.
+    ///
+    /// # Return value
+    ///
+    /// Returns `true` if `c` is a valid digit under `radix`, and `false`
+    /// otherwise.
+    ///
+    /// # Panics
+    ///
+    /// Panics if given a radix > 36.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let c = '1';
+    ///
+    /// assert!(c.is_digit(10));
+    ///
+    /// assert!('f'.is_digit(16));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_digit(self, radix: u32) -> bool { C::is_digit(self, radix) }
+
+    /// Converts a character to the corresponding digit.
+    ///
+    /// # Return value
+    ///
+    /// If `c` is between '0' and '9', the corresponding value between 0 and
+    /// 9. If `c` is 'a' or 'A', 10. If `c` is 'b' or 'B', 11, etc. Returns
+    /// none if the character does not refer to a digit in the given radix.
+    ///
+    /// # Panics
+    ///
+    /// Panics if given a radix outside the range [0..36].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let c = '1';
+    ///
+    /// assert_eq!(c.to_digit(10), Some(1));
+    ///
+    /// assert_eq!('f'.to_digit(16), Some(15));
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn to_digit(self, radix: u32) -> Option<u32> { C::to_digit(self, radix) }
+
+    /// Returns an iterator that yields the hexadecimal Unicode escape of a
+    /// character, as `char`s.
+    ///
+    /// All characters are escaped with Rust syntax of the form `\\u{NNNN}`
+    /// where `NNNN` is the shortest hexadecimal representation of the code
+    /// point.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// for i in '❤'.escape_unicode() {
+    ///     println!("{}", i);
+    /// }
+    /// ```
+    ///
+    /// This prints:
+    ///
+    /// ```text
+    /// \
+    /// u
+    /// {
+    /// 2
+    /// 7
+    /// 6
+    /// 4
+    /// }
+    /// ```
+    ///
+    /// Collecting into a `String`:
+    ///
+    /// ```
+    /// let heart: String = '❤'.escape_unicode().collect();
+    ///
+    /// assert_eq!(heart, r"\u{2764}");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn escape_unicode(self) -> EscapeUnicode { C::escape_unicode(self) }
+
+    /// Returns an iterator that yields the 'default' ASCII and
+    /// C++11-like literal escape of a character, as `char`s.
+    ///
+    /// The default is chosen with a bias toward producing literals that are
+    /// legal in a variety of languages, including C++11 and similar C-family
+    /// languages. The exact rules are:
+    ///
+    /// * Tab, CR and LF are escaped as '\t', '\r' and '\n' respectively.
+    /// * Single-quote, double-quote and backslash chars are backslash-
+    ///   escaped.
+    /// * Any other chars in the range [0x20,0x7e] are not escaped.
+    /// * Any other chars are given hex Unicode escapes; see `escape_unicode`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// for i in '"'.escape_default() {
+    ///     println!("{}", i);
+    /// }
+    /// ```
+    ///
+    /// This prints:
+    ///
+    /// ```text
+    /// \
+    /// "
+    /// ```
+    ///
+    /// Collecting into a `String`:
+    ///
+    /// ```
+    /// let quote: String = '"'.escape_default().collect();
+    ///
+    /// assert_eq!(quote, "\\\"");
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn escape_default(self) -> EscapeDefault { C::escape_default(self) }
+
+    /// Returns the number of bytes this character would need if encoded in
+    /// UTF-8.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let n = 'ß'.len_utf8();
+    ///
+    /// assert_eq!(n, 2);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn len_utf8(self) -> usize { C::len_utf8(self) }
+
+    /// Returns the number of 16-bit code units this character would need if
+    /// encoded in UTF-16.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let n = 'ß'.len_utf16();
+    ///
+    /// assert_eq!(n, 1);
+    /// ```
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn len_utf16(self) -> usize { C::len_utf16(self) }
+
+    /// Encodes this character as UTF-8 into the provided byte buffer, and then
+    /// returns the number of bytes written.
+    ///
+    /// If the buffer is not large enough, nothing will be written into it and a
+    /// `None` will be returned. A buffer of length four is large enough to
+    /// encode any `char`.
+    ///
+    /// # Examples
+    ///
+    /// In both of these examples, 'ß' takes two bytes to encode.
+    ///
+    /// ```
+    /// let mut b = [0; 2];
+    ///
+    /// let result = 'ß'.encode_utf8(&mut b);
+    ///
+    /// assert_eq!(result, Some(2));
+    /// ```
+    ///
+    /// A buffer that's too small:
+    ///
+    /// ```
+    /// let mut b = [0; 1];
+    ///
+    /// let result = 'ß'.encode_utf8(&mut b);
+    ///
+    /// assert_eq!(result, None);
+    /// ```
+    #[unstable(feature = "unicode",
+               reason = "pending decision about Iterator/Writer/Reader")]
+    pub fn encode_utf8(self, dst: &mut [u8]) -> Option<usize> { C::encode_utf8(self, dst) }
+
+    /// Encodes this character as UTF-16 into the provided `u16` buffer, and
+    /// then returns the number of `u16`s written.
+    ///
+    /// If the buffer is not large enough, nothing will be written into it and a
+    /// `None` will be returned. A buffer of length 2 is large enough to encode
+    /// any `char`.
+    ///
+    /// # Examples
+    ///
+    /// In both of these examples, 'ß' takes one `u16` to encode.
+    ///
+    /// ```
+    /// let mut b = [0; 1];
+    ///
+    /// let result = 'ß'.encode_utf16(&mut b);
+    ///
+    /// assert_eq!(result, Some(1));
+    /// ```
+    ///
+    /// A buffer that's too small:
+    ///
+    /// ```
+    /// let mut b = [0; 0];
+    ///
+    /// let result = 'ß'.encode_utf8(&mut b);
+    ///
+    /// assert_eq!(result, None);
+    /// ```
+    #[unstable(feature = "unicode",
+               reason = "pending decision about Iterator/Writer/Reader")]
+    pub fn encode_utf16(self, dst: &mut [u16]) -> Option<usize> { C::encode_utf16(self, dst) }
+
+    /// Returns whether the specified character is considered a Unicode
+    /// alphabetic code point.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_alphabetic(self) -> bool {
+        match self {
+            'a' ... 'z' | 'A' ... 'Z' => true,
+            c if c > '\x7f' => derived_property::Alphabetic(c),
+            _ => false
+        }
+    }
+
+    /// Returns whether the specified character satisfies the 'XID_Start'
+    /// Unicode property.
+    ///
+    /// 'XID_Start' is a Unicode Derived Property specified in
+    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+    /// mostly similar to ID_Start but modified for closure under NFKx.
+    #[unstable(feature = "unicode",
+               reason = "mainly needed for compiler internals")]
+    pub fn is_xid_start(self) -> bool { derived_property::XID_Start(self) }
+
+    /// Returns whether the specified `char` satisfies the 'XID_Continue'
+    /// Unicode property.
+    ///
+    /// 'XID_Continue' is a Unicode Derived Property specified in
+    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
+    /// mostly similar to 'ID_Continue' but modified for closure under NFKx.
+    #[unstable(feature = "unicode",
+               reason = "mainly needed for compiler internals")]
+    pub fn is_xid_continue(self) -> bool { derived_property::XID_Continue(self) }
+
+    /// Indicates whether a character is in lowercase.
+    ///
+    /// This is defined according to the terms of the Unicode Derived Core
+    /// Property `Lowercase`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_lowercase(self) -> bool {
+        match self {
+            'a' ... 'z' => true,
+            c if c > '\x7f' => derived_property::Lowercase(c),
+            _ => false
+        }
+    }
+
+    /// Indicates whether a character is in uppercase.
+    ///
+    /// This is defined according to the terms of the Unicode Derived Core
+    /// Property `Uppercase`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_uppercase(self) -> bool {
+        match self {
+            'A' ... 'Z' => true,
+            c if c > '\x7f' => derived_property::Uppercase(c),
+            _ => false
+        }
+    }
+
+    /// Indicates whether a character is whitespace.
+    ///
+    /// Whitespace is defined in terms of the Unicode Property `White_Space`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_whitespace(self) -> bool {
+        match self {
+            ' ' | '\x09' ... '\x0d' => true,
+            c if c > '\x7f' => property::White_Space(c),
+            _ => false
+        }
+    }
+
+    /// Indicates whether a character is alphanumeric.
+    ///
+    /// Alphanumericness is defined in terms of the Unicode General Categories
+    /// 'Nd', 'Nl', 'No' and the Derived Core Property 'Alphabetic'.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_alphanumeric(self) -> bool {
+        self.is_alphabetic() || self.is_numeric()
+    }
+
+    /// Indicates whether a character is a control code point.
+    ///
+    /// Control code points are defined in terms of the Unicode General
+    /// Category `Cc`.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_control(self) -> bool { general_category::Cc(self) }
+
+    /// Indicates whether the character is numeric (Nd, Nl, or No).
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn is_numeric(self) -> bool {
+        match self {
+            '0' ... '9' => true,
+            c if c > '\x7f' => general_category::N(c),
+            _ => false
+        }
+    }
+
+    /// Converts a character to its lowercase equivalent.
+    ///
+    /// The case-folding performed is the common or simple mapping. See
+    /// `to_uppercase()` for references and more information.
+    ///
+    /// # Return value
+    ///
+    /// Returns an iterator which yields the characters corresponding to the
+    /// lowercase equivalent of the character. If no conversion is possible then
+    /// the input character is returned.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn to_lowercase(self) -> ToLowercase {
+        ToLowercase(Some(conversions::to_lower(self)))
+    }
+
+    /// Converts a character to its uppercase equivalent.
+    ///
+    /// The case-folding performed is the common or simple mapping: it maps
+    /// one Unicode codepoint to its uppercase equivalent according to the
+    /// Unicode database [1]. The additional [`SpecialCasing.txt`] is not yet
+    /// considered here, but the iterator returned will soon support this form
+    /// of case folding.
+    ///
+    /// A full reference can be found here [2].
+    ///
+    /// # Return value
+    ///
+    /// Returns an iterator which yields the characters corresponding to the
+    /// uppercase equivalent of the character. If no conversion is possible then
+    /// the input character is returned.
+    ///
+    /// [1]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
+    ///
+    /// [`SpecialCasing`.txt`]: ftp://ftp.unicode.org/Public/UNIDATA/SpecialCasing.txt
+    ///
+    /// [2]: http://www.unicode.org/versions/Unicode4.0.0/ch03.pdf#G33992
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn to_uppercase(self) -> ToUppercase {
+        ToUppercase(Some(conversions::to_upper(self)))
+    }
+
+    /// Returns this character's displayed width in columns, or `None` if it is a
+    /// control character other than `'\x00'`.
+    ///
+    /// `is_cjk` determines behavior for characters in the Ambiguous category:
+    /// if `is_cjk` is `true`, these are 2 columns wide; otherwise, they are 1.
+    /// In CJK contexts, `is_cjk` should be `true`, else it should be `false`.
+    /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/)
+    /// recommends that these characters be treated as 1 column (i.e.,
+    /// `is_cjk` = `false`) if the context cannot be reliably determined.
+    #[unstable(feature = "unicode",
+               reason = "needs expert opinion. is_cjk flag stands out as ugly")]
+    pub fn width(self, is_cjk: bool) -> Option<usize> { charwidth::width(self, is_cjk) }
+}
diff --git a/src/libunicode/lib.rs b/src/libunicode/lib.rs
index fadf91f33bc..a09c0cb3bd6 100644
--- a/src/libunicode/lib.rs
+++ b/src/libunicode/lib.rs
@@ -24,6 +24,7 @@
 #![cfg_attr(stage0, feature(custom_attribute))]
 #![crate_name = "unicode"]
 #![unstable(feature = "unicode")]
+#![feature(lang_items)]
 #![feature(staged_api)]
 #![staged_api]
 #![crate_type = "rlib"]
diff --git a/src/libunicode/u_str.rs b/src/libunicode/u_str.rs
index 6152e057df3..917c2d2dfbe 100644
--- a/src/libunicode/u_str.rs
+++ b/src/libunicode/u_str.rs
@@ -26,6 +26,7 @@ use core::num::Int;
 use core::slice;
 use core::str::Split;
 
+#[cfg(stage0)]
 use char::CharExt as UCharExt; // conflicts with core::prelude::CharExt
 use tables::grapheme::GraphemeCat;
 
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index aaf6d8df29c..9a87c03f1c4 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -14,11 +14,7 @@
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 
-#if LLVM_VERSION_MINOR >= 5
 #include "llvm/IR/CallSite.h"
-#else
-#include "llvm/Support/CallSite.h"
-#endif
 
 //===----------------------------------------------------------------------===
 //
@@ -33,7 +29,6 @@ using namespace llvm::object;
 
 static char *LastError;
 
-#if LLVM_VERSION_MINOR >= 5
 extern "C" LLVMMemoryBufferRef
 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
   ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(Path,
@@ -45,18 +40,6 @@ LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
   }
   return wrap(buf_or.get().release());
 }
-#else
-extern "C" LLVMMemoryBufferRef
-LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
-  OwningPtr<MemoryBuffer> buf;
-  error_code err = MemoryBuffer::getFile(Path, buf, -1, false);
-  if (err) {
-      LLVMRustSetLastError(err.message().c_str());
-      return NULL;
-  }
-  return wrap(buf.take());
-}
-#endif
 
 extern "C" char *LLVMRustGetLastError(void) {
   char *ret = LastError;
@@ -116,7 +99,6 @@ extern "C" void LLVMAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, uin
 }
 
 
-#if LLVM_VERSION_MINOR >= 5
 extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef Instr, unsigned idx, uint64_t b) {
   CallSite Call = CallSite(unwrap<Instruction>(Instr));
   AttrBuilder B;
@@ -126,9 +108,6 @@ extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef Instr, unsigned
                                        AttributeSet::get(Call->getContext(),
                                                          idx, B)));
 }
-#else
-extern "C" void LLVMAddDereferenceableCallSiteAttr(LLVMValueRef, unsigned, uint64_t) {}
-#endif
 
 extern "C" void LLVMAddFunctionAttribute(LLVMValueRef Fn, unsigned index, uint64_t Val) {
   Function *A = unwrap<Function>(Fn);
@@ -137,16 +116,12 @@ extern "C" void LLVMAddFunctionAttribute(LLVMValueRef Fn, unsigned index, uint64
   A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
 }
 
-#if LLVM_VERSION_MINOR >= 5
 extern "C" void LLVMAddDereferenceableAttr(LLVMValueRef Fn, unsigned index, uint64_t bytes) {
   Function *A = unwrap<Function>(Fn);
   AttrBuilder B;
   B.addDereferenceableAttr(bytes);
   A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
 }
-#else
-extern "C" void LLVMAddDereferenceableAttr(LLVMValueRef, unsigned, uint64_t) {}
-#endif
 
 extern "C" void LLVMAddFunctionAttrString(LLVMValueRef Fn, unsigned index, const char *Name) {
   Function *F = unwrap<Function>(Fn);
@@ -199,10 +174,8 @@ extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B,
                                                AtomicOrdering order,
                                                AtomicOrdering failure_order) {
     return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(target), unwrap(old),
-                                               unwrap(source), order
-#if LLVM_VERSION_MINOR >= 5
-                                               , failure_order
-#endif
+                                               unwrap(source), order,
+                                               failure_order
                                                ));
 }
 extern "C" LLVMValueRef LLVMBuildAtomicFence(LLVMBuilderRef B, AtomicOrdering order) {
@@ -247,11 +220,7 @@ DIT unwrapDI(LLVMMetadataRef ref) {
     return DIT(ref ? unwrap<MDNode>(ref) : NULL);
 }
 
-#if LLVM_VERSION_MINOR >= 5
 extern "C" const uint32_t LLVMRustDebugMetadataVersion = DEBUG_METADATA_VERSION;
-#else
-extern "C" const uint32_t LLVMRustDebugMetadataVersion = 1;
-#endif
 
 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
                                       const char *name,
@@ -383,10 +352,8 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateStructType(
         unwrapDI<DIType>(DerivedFrom),
         unwrapDI<DIArray>(Elements),
         RunTimeLang,
-        unwrapDI<DIType>(VTableHolder)
-#if LLVM_VERSION_MINOR >= 4
-        ,UniqueId
-#endif
+        unwrapDI<DIType>(VTableHolder),
+        UniqueId
         ));
 }
 
@@ -465,8 +432,8 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateVariable(
 #if LLVM_VERSION_MINOR < 6
     if (AddrOpsCount > 0) {
         SmallVector<llvm::Value *, 16> addr_ops;
-        llvm::Type *Int64Ty = Type::getInt64Ty(VMContext);
-        for (int i = 0; i < AddrOpsCount; ++i)
+        llvm::Type *Int64Ty = Type::getInt64Ty(unwrap<MDNode>(Scope)->getContext());
+        for (unsigned i = 0; i < AddrOpsCount; ++i)
             addr_ops.push_back(ConstantInt::get(Int64Ty, AddrOps[i]));
 
         return wrap(Builder->createComplexVariable(
@@ -522,7 +489,11 @@ extern "C" LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(
     LLVMMetadataRef* Ptr,
     unsigned Count) {
     return wrap(Builder->getOrCreateArray(
+#if LLVM_VERSION_MINOR >= 6
         ArrayRef<Metadata*>(unwrap(Ptr), Count)));
+#else
+        ArrayRef<Value*>(reinterpret_cast<Value**>(Ptr), Count)));
+#endif
 }
 
 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
@@ -627,19 +598,11 @@ extern "C" LLVMMetadataRef LLVMDIBuilderCreateUnionType(
         AlignInBits,
         Flags,
         unwrapDI<DIArray>(Elements),
-        RunTimeLang
-#if LLVM_VERSION_MINOR >= 4
-        ,UniqueId
-#endif
+        RunTimeLang,
+        UniqueId
         ));
 }
 
-#if LLVM_VERSION_MINOR < 5
-extern "C" void LLVMSetUnnamedAddr(LLVMValueRef Value, LLVMBool Unnamed) {
-    unwrap<GlobalValue>(Value)->setUnnamedAddr(Unnamed);
-}
-#endif
-
 extern "C" LLVMMetadataRef LLVMDIBuilderCreateTemplateTypeParameter(
     DIBuilderRef Builder,
     LLVMMetadataRef Scope,
@@ -730,7 +693,6 @@ extern "C" void LLVMWriteValueToString(LLVMValueRef Value, RustStringRef str) {
     os << ")";
 }
 
-#if LLVM_VERSION_MINOR >= 5
 extern "C" bool
 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
     Module *Dst = unwrap(dst);
@@ -763,28 +725,7 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
     }
     return true;
 }
-#else
-extern "C" bool
-LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
-    Module *Dst = unwrap(dst);
-    MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
-    std::string Err;
-    Module *Src = llvm::getLazyBitcodeModule(buf, Dst->getContext(), &Err);
-    if (!Src) {
-        LLVMRustSetLastError(Err.c_str());
-        delete buf;
-        return false;
-    }
-
-    if (Linker::LinkModules(Dst, Src, Linker::DestroySource, &Err)) {
-        LLVMRustSetLastError(Err.c_str());
-        return false;
-    }
-    return true;
-}
-#endif
 
-#if LLVM_VERSION_MINOR >= 5
 extern "C" void*
 LLVMRustOpenArchive(char *path) {
     ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(path,
@@ -817,23 +758,6 @@ LLVMRustOpenArchive(char *path) {
 
     return ret;
 }
-#else
-extern "C" void*
-LLVMRustOpenArchive(char *path) {
-    OwningPtr<MemoryBuffer> buf;
-    error_code err = MemoryBuffer::getFile(path, buf, -1, false);
-    if (err) {
-        LLVMRustSetLastError(err.message().c_str());
-        return NULL;
-    }
-    Archive *ret = new Archive(buf.take(), err);
-    if (err) {
-        LLVMRustSetLastError(err.message().c_str());
-        return NULL;
-    }
-    return ret;
-}
-#endif
 
 extern "C" const char*
 #if LLVM_VERSION_MINOR >= 6
@@ -844,21 +768,12 @@ LLVMRustArchiveReadSection(OwningBinary<Archive> *ob, char *name, size_t *size)
 LLVMRustArchiveReadSection(Archive *ar, char *name, size_t *size) {
 #endif
 
-#if LLVM_VERSION_MINOR >= 5
     Archive::child_iterator child = ar->child_begin(),
                               end = ar->child_end();
     for (; child != end; ++child) {
         ErrorOr<StringRef> name_or_err = child->getName();
         if (name_or_err.getError()) continue;
         StringRef sect_name = name_or_err.get();
-#else
-    Archive::child_iterator child = ar->begin_children(),
-                              end = ar->end_children();
-    for (; child != end; ++child) {
-        StringRef sect_name;
-        error_code err = child->getName(sect_name);
-        if (err) continue;
-#endif
         if (sect_name.trim(" ") == name) {
             StringRef buf = child->getBuffer();
             *size = buf.size();
@@ -877,18 +792,11 @@ LLVMRustDestroyArchive(Archive *ar) {
     delete ar;
 }
 
-#if LLVM_VERSION_MINOR >= 5
 extern "C" void
 LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) {
     GlobalValue *V = unwrap<GlobalValue>(Value);
     V->setDLLStorageClass(GlobalValue::DLLExportStorageClass);
 }
-#else
-extern "C" void
-LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) {
-    LLVMSetLinkage(Value, LLVMDLLExportLinkage);
-}
-#endif
 
 extern "C" int
 LLVMVersionMinor() {
@@ -918,11 +826,7 @@ inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
 extern "C" int
 LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
     StringRef ret;
-#if LLVM_VERSION_MINOR >= 5
     if (std::error_code ec = (*unwrap(SI))->getName(ret))
-#else
-    if (error_code ec = (*unwrap(SI))->getName(ret))
-#endif
       report_fatal_error(ec.message());
     *ptr = ret.data();
     return ret.size();
diff --git a/src/test/auxiliary/privacy_reexport.rs b/src/test/auxiliary/privacy_reexport.rs
index 266903169c7..e60dbb290b0 100644
--- a/src/test/auxiliary/privacy_reexport.rs
+++ b/src/test/auxiliary/privacy_reexport.rs
@@ -10,6 +10,6 @@
 
 pub use foo as bar;
 
-mod foo {
+pub mod foo {
     pub fn frob() {}
 }
diff --git a/src/test/auxiliary/pub_static_array.rs b/src/test/auxiliary/pub_static_array.rs
new file mode 100644
index 00000000000..4419a5ae83c
--- /dev/null
+++ b/src/test/auxiliary/pub_static_array.rs
@@ -0,0 +1,11 @@
+// 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.
+
+pub static ARRAY: &'static [u8] = &[1];
diff --git a/src/test/compile-fail/associated-types-eq-expr-path.rs b/src/test/compile-fail/associated-types-eq-expr-path.rs
index c48f9972ebc..0d68b960f31 100644
--- a/src/test/compile-fail/associated-types-eq-expr-path.rs
+++ b/src/test/compile-fail/associated-types-eq-expr-path.rs
@@ -22,5 +22,5 @@ impl Foo for isize {
 
 pub fn main() {
     let x: isize = Foo::<A=usize>::bar();
-    //~^ERROR unexpected binding of associated item in expression path
+    //~^ ERROR unexpected binding of associated item in expression path
 }
diff --git a/src/test/compile-fail/integral-indexing.rs b/src/test/compile-fail/integral-indexing.rs
index e8998dd7a9d..e2fb0fa4f2f 100644
--- a/src/test/compile-fail/integral-indexing.rs
+++ b/src/test/compile-fail/integral-indexing.rs
@@ -24,11 +24,11 @@ pub fn main() {
     s.as_bytes()[3_usize];
     s.as_bytes()[3];
     s.as_bytes()[3u8];  //~ERROR the trait `core::ops::Index<u8>` is not implemented
-    //~^ERROR the trait `core::ops::Index<u8>` is not implemented
+    //~^ ERROR the trait `core::ops::Index<u8>` is not implemented
     s.as_bytes()[3i8];  //~ERROR the trait `core::ops::Index<i8>` is not implemented
-    //~^ERROR the trait `core::ops::Index<i8>` is not implemented
+    //~^ ERROR the trait `core::ops::Index<i8>` is not implemented
     s.as_bytes()[3u32]; //~ERROR the trait `core::ops::Index<u32>` is not implemented
-    //~^ERROR the trait `core::ops::Index<u32>` is not implemented
+    //~^ ERROR the trait `core::ops::Index<u32>` is not implemented
     s.as_bytes()[3i32]; //~ERROR the trait `core::ops::Index<i32>` is not implemented
-    //~^ERROR the trait `core::ops::Index<i32>` is not implemented
+    //~^ ERROR the trait `core::ops::Index<i32>` is not implemented
 }
diff --git a/src/test/compile-fail/issue-13407.rs b/src/test/compile-fail/issue-13407.rs
new file mode 100644
index 00000000000..f845eba4060
--- /dev/null
+++ b/src/test/compile-fail/issue-13407.rs
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+mod A {
+    struct C;
+}
+
+fn main() {
+    A::C = 1;
+    //~^ ERROR: illegal left-hand side expression
+    //~| ERROR: mismatched types
+}
diff --git a/src/test/compile-fail/issue-16922.rs b/src/test/compile-fail/issue-16922.rs
new file mode 100644
index 00000000000..b525d5f64fc
--- /dev/null
+++ b/src/test/compile-fail/issue-16922.rs
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+use std::any::Any;
+
+fn foo<T: Any>(value: &T) -> Box<Any> {
+    Box::new(value) as Box<Any>
+    //~^ ERROR: cannot infer an appropriate lifetime
+}
+
+fn main() {
+    let _ = foo(&5);
+}
diff --git a/src/test/compile-fail/issue-18919.rs b/src/test/compile-fail/issue-18919.rs
new file mode 100644
index 00000000000..8c2c52e6fad
--- /dev/null
+++ b/src/test/compile-fail/issue-18919.rs
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+type FuncType<'f> = Fn(&isize) -> isize + 'f;
+
+fn ho_func(f: Option<FuncType>) {
+    //~^ ERROR: the trait `core::marker::Sized` is not implemented for the type
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-19982.rs b/src/test/compile-fail/issue-19982.rs
new file mode 100644
index 00000000000..9dbca997341
--- /dev/null
+++ b/src/test/compile-fail/issue-19982.rs
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+#![feature(unboxed_closures)]
+
+struct Foo;
+
+impl Fn<(&(),)> for Foo { } //~ ERROR missing lifetime specifier
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-20225.rs b/src/test/compile-fail/issue-20225.rs
new file mode 100644
index 00000000000..e4bedbbb7e1
--- /dev/null
+++ b/src/test/compile-fail/issue-20225.rs
@@ -0,0 +1,22 @@
+// Copyright 2015 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.
+
+#![feature(unboxed_closures)]
+
+struct Foo;
+
+impl<'a, T> Fn<(&'a T,)> for Foo {
+  type Output = ();
+
+  extern "rust-call" fn call(&self, (_,): (T,)) {}
+  //~^ ERROR: has an incompatible type for trait: expected &-ptr
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-20261.rs b/src/test/compile-fail/issue-20261.rs
new file mode 100644
index 00000000000..33e00f9a823
--- /dev/null
+++ b/src/test/compile-fail/issue-20261.rs
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+fn main() {
+    for (ref i,) in [].iter() { //~ ERROR: type mismatch resolving
+        i.clone();
+        //~^ ERROR: the type of this value must be known in this context
+        //~| ERROR: reached the recursion limit while auto-dereferencing
+    }
+}
diff --git a/src/test/compile-fail/issue-20714.rs b/src/test/compile-fail/issue-20714.rs
new file mode 100644
index 00000000000..cb322f00723
--- /dev/null
+++ b/src/test/compile-fail/issue-20714.rs
@@ -0,0 +1,15 @@
+// Copyright 2015 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.
+
+struct G;
+
+fn main() {
+    let g = G(); //~ ERROR: expected function, found `G`
+}
diff --git a/src/test/compile-fail/issue-7950.rs b/src/test/compile-fail/issue-7950.rs
new file mode 100644
index 00000000000..01b90f5680f
--- /dev/null
+++ b/src/test/compile-fail/issue-7950.rs
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+// tests the good error message, not "missing module Foo" or something else unexpected
+
+struct Foo;
+
+fn main() {
+    Foo::bar(); //~ ERROR type `Foo` does not implement any method in scope named `bar`
+}
diff --git a/src/test/compile-fail/lint-dead-code-3.rs b/src/test/compile-fail/lint-dead-code-3.rs
index f60c39ba020..13ee3f16361 100644
--- a/src/test/compile-fail/lint-dead-code-3.rs
+++ b/src/test/compile-fail/lint-dead-code-3.rs
@@ -19,7 +19,7 @@ extern crate libc;
 
 pub use extern_foo as x;
 extern {
-    fn extern_foo();
+    pub fn extern_foo();
 }
 
 struct Foo; //~ ERROR: struct is never used
diff --git a/src/test/compile-fail/lint-non-camel-case-types.rs b/src/test/compile-fail/lint-non-camel-case-types.rs
index 9f58d5791cb..f6d3d62d0bf 100644
--- a/src/test/compile-fail/lint-non-camel-case-types.rs
+++ b/src/test/compile-fail/lint-non-camel-case-types.rs
@@ -11,6 +11,9 @@
 #![forbid(non_camel_case_types)]
 #![allow(dead_code)]
 
+struct ONE_TWO_THREE;
+//~^ ERROR type `ONE_TWO_THREE` should have a camel case name such as `OneTwoThree`
+
 struct foo { //~ ERROR type `foo` should have a camel case name such as `Foo`
     bar: isize,
 }
diff --git a/src/test/compile-fail/manual-link-bad-search-path.rs b/src/test/compile-fail/manual-link-bad-search-path.rs
new file mode 100644
index 00000000000..2bf61cbe24c
--- /dev/null
+++ b/src/test/compile-fail/manual-link-bad-search-path.rs
@@ -0,0 +1,15 @@
+// Copyright 2015 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.
+
+// compile-flags:-L native=
+// error-pattern: empty search path given via `-L`
+
+fn main() {
+}
diff --git a/src/test/compile-fail/lint-dead-code-variant.rs b/src/test/compile-fail/match-ref-ice.rs
index 6146be65e38..d0f7c7ca986 100644
--- a/src/test/compile-fail/lint-dead-code-variant.rs
+++ b/src/test/compile-fail/match-ref-ice.rs
@@ -8,35 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(dead_code)]
-
-#[derive(Copy)]
-enum Enum {
-    Variant1, //~ ERROR: variant is never used
-    Variant2,
-    Variant3,
-}
+// The arity of `ref x` is always 1. If the pattern is compared to some non-structural type whose
+// arity is always 0, an ICE occurs.
+//
+// Related issue: #23009
 
-fn copy(e: Enum) -> Enum {
-    use Enum::*;
-    match e {
-        Variant1 => Variant1,
-        Variant2 => Variant2,
-        Variant3 => Variant3,
-    }
-}
+fn main() {
+    let homura = [1, 2, 3];
 
-fn max(e: Enum) -> Enum {
-    use Enum::*;
-    match e {
-        Variant1 => Variant3,
-        Variant2 => Variant3,
-        Variant3 => Variant3,
+    match homura {
+        [1, ref madoka, 3] => (),
+        [1, 2, 3] => (), //~ ERROR unreachable pattern
+        [_, _, _] => (),
     }
 }
-
-fn main() {
-    let e = Enum::Variant2;
-    copy(e);
-    max(e);
-}
diff --git a/src/test/compile-fail/method-suggestion-no-duplication.rs b/src/test/compile-fail/method-suggestion-no-duplication.rs
index e807d2b9448..1d0c4254eda 100644
--- a/src/test/compile-fail/method-suggestion-no-duplication.rs
+++ b/src/test/compile-fail/method-suggestion-no-duplication.rs
@@ -19,6 +19,4 @@ fn main() {
     //~^ ERROR does not implement any method
     //~^^ HELP #1: `core::slice::SliceExt`
     //~^^^ HELP #2: `core::str::StrExt`
-    //~^^^^ HELP #3: `collections::slice::SliceExt`
-    //~^^^^^ HELP #4: `collections::str::StrExt`
 }
diff --git a/src/test/compile-fail/privacy1.rs b/src/test/compile-fail/privacy1.rs
index 1ae79adbad7..67dccb4c93e 100644
--- a/src/test/compile-fail/privacy1.rs
+++ b/src/test/compile-fail/privacy1.rs
@@ -27,10 +27,6 @@ mod bar {
 
     // can't publicly re-export private items
     pub use self::baz::{foo, bar};
-    //~^ ERROR: function `bar` is private
-
-    pub use self::private::ppriv;
-    //~^ ERROR: function `ppriv` is private
 
     pub struct A;
     impl A {
@@ -61,10 +57,8 @@ mod bar {
             fn bar2(&self) {}
         }
 
-        // both of these are re-exported by `bar`, but only one should be
-        // validly re-exported
         pub fn foo() {}
-        fn bar() {}
+        pub fn bar() {}
     }
 
     extern {
@@ -92,10 +86,6 @@ mod bar {
         pub fn gpub() {}
         fn gpriv() {}
     }
-
-    mod private {
-        fn ppriv() {}
-    }
 }
 
 pub fn gpub() {}
@@ -142,13 +132,13 @@ mod foo {
 
         ::bar::baz::foo(); //~ ERROR: function `foo` is inaccessible
                            //~^ NOTE: module `baz` is private
-        ::bar::baz::bar(); //~ ERROR: function `bar` is private
+        ::bar::baz::bar(); //~ ERROR: function `bar` is inaccessible
     }
 
     fn test2() {
         use bar::baz::{foo, bar};
         //~^ ERROR: function `foo` is inaccessible
-        //~^^ ERROR: function `bar` is private
+        //~^^ ERROR: function `bar` is inaccessible
         foo();
         bar();
     }
diff --git a/src/test/compile-fail/single-primitive-inherent-impl.rs b/src/test/compile-fail/single-primitive-inherent-impl.rs
new file mode 100644
index 00000000000..b2cfcfab78b
--- /dev/null
+++ b/src/test/compile-fail/single-primitive-inherent-impl.rs
@@ -0,0 +1,24 @@
+// Copyright 2015 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.
+
+// ignore-tidy-linelength
+
+#![crate_type = "lib"]
+#![feature(lang_items)]
+#![feature(no_std)]
+#![no_std]
+
+// OK
+#[lang = "char"]
+impl char {}
+
+impl char {
+//~^ error: only a single inherent implementation marked with `#[lang = "char"]` is allowed for the `char` primitive
+}
diff --git a/src/test/compile-fail/static-array-across-crate.rs b/src/test/compile-fail/static-array-across-crate.rs
new file mode 100644
index 00000000000..422cf630429
--- /dev/null
+++ b/src/test/compile-fail/static-array-across-crate.rs
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+// aux-build:pub_static_array.rs
+
+extern crate "pub_static_array" as array;
+
+use array::ARRAY;
+
+static X: &'static u8 = &ARRAY[0];
+//~^ ERROR: cannot refer to the interior of another static, use a constant
+
+pub fn main() {}
diff --git a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
index 448b186f6a5..e126a3040e9 100644
--- a/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
+++ b/src/test/compile-fail/trait-bounds-not-on-bare-trait.rs
@@ -15,7 +15,7 @@ trait Foo {
 // This should emit the less confusing error, not the more confusing one.
 
 fn foo(_x: Foo + Send) {
-    //~^ERROR the trait `core::marker::Sized` is not implemented
+    //~^ ERROR the trait `core::marker::Sized` is not implemented
 }
 
 fn main() { }
diff --git a/src/test/parse-fail/column-offset-1-based.rs b/src/test/parse-fail/column-offset-1-based.rs
index 621b480fe77..a00ded61758 100644
--- a/src/test/parse-fail/column-offset-1-based.rs
+++ b/src/test/parse-fail/column-offset-1-based.rs
@@ -8,4 +8,4 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-# //~ ERROR 11:1: 11:2 error: expected one of `!` or `[`, found `<eof>`
+# //~ ERROR 11:1: 11:2 error: expected `[`, found `<eof>`
diff --git a/src/test/parse-fail/issue-1655.rs b/src/test/parse-fail/issue-1655.rs
index a8704f7545f..6bdcf5c5edc 100644
--- a/src/test/parse-fail/issue-1655.rs
+++ b/src/test/parse-fail/issue-1655.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:expected one of `!` or `[`, found `vec`
+// error-pattern:expected `[`, found `vec`
 mod blade_runner {
     #vec[doc(
         brief = "Blade Runner is probably the best movie ever",
diff --git a/src/test/run-fail/issue-23354-2.rs b/src/test/run-fail/issue-23354-2.rs
new file mode 100644
index 00000000000..b120d3222fa
--- /dev/null
+++ b/src/test/run-fail/issue-23354-2.rs
@@ -0,0 +1,17 @@
+// Copyright 2015 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.
+
+// error-pattern:panic evaluated
+
+#[allow(unused_variables)]
+fn main() {
+    // This used to trigger an LLVM assertion during compilation
+    let x = [panic!("panic evaluated"); 2];
+}
diff --git a/src/test/run-fail/issue-23354.rs b/src/test/run-fail/issue-23354.rs
new file mode 100644
index 00000000000..f6b937c8259
--- /dev/null
+++ b/src/test/run-fail/issue-23354.rs
@@ -0,0 +1,16 @@
+// Copyright 2015 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.
+
+// error-pattern:panic evaluated
+
+#[allow(unused_variables)]
+fn main() {
+    let x = [panic!("panic evaluated"); 0];
+}
diff --git a/src/test/run-pass-fulldeps/quote-tokens.rs b/src/test/run-pass-fulldeps/quote-tokens.rs
index 7f7ed586878..020f5f562d2 100644
--- a/src/test/run-pass-fulldeps/quote-tokens.rs
+++ b/src/test/run-pass-fulldeps/quote-tokens.rs
@@ -25,7 +25,7 @@ fn syntax_extension(cx: &ExtCtxt) {
     let a: P<syntax::ast::Expr> = quote_expr!(cx, 1 + 2);
     let _b: Option<P<syntax::ast::Item>> = quote_item!(cx, static foo : int = $e_toks; );
     let _c: P<syntax::ast::Pat> = quote_pat!(cx, (x, 1 .. 4, *) );
-    let _d: P<syntax::ast::Stmt> = quote_stmt!(cx, let x = $a; );
+    let _d: Option<P<syntax::ast::Stmt>> = quote_stmt!(cx, let x = $a; );
     let _d: syntax::ast::Arm = quote_arm!(cx, (ref x, ref y) = (x, y) );
     let _e: P<syntax::ast::Expr> = quote_expr!(cx, match foo { $p_toks => 10 } );
 
diff --git a/src/test/run-pass/issue-11820.rs b/src/test/run-pass/issue-11820.rs
new file mode 100644
index 00000000000..f7aaf495377
--- /dev/null
+++ b/src/test/run-pass/issue-11820.rs
@@ -0,0 +1,19 @@
+// Copyright 2015 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.
+
+struct NoClone;
+
+fn main() {
+  let rnc = &NoClone;
+  let rsnc = &Some(NoClone);
+
+  let _: &NoClone = rnc.clone();
+  let _: &Option<NoClone> = rsnc.clone();
+}
diff --git a/src/test/run-pass/issue-16597.rs b/src/test/run-pass/issue-16597.rs
index 72e948e613b..d074095dbde 100644
--- a/src/test/run-pass/issue-16597.rs
+++ b/src/test/run-pass/issue-16597.rs
@@ -15,5 +15,5 @@ mod test {
     use super::*;
 
     #[test]
-    fn test(){}
+    pub fn test(){}
 }
diff --git a/src/test/run-pass/issue-16922.rs b/src/test/run-pass/issue-16922.rs
new file mode 100644
index 00000000000..25909bcbfe9
--- /dev/null
+++ b/src/test/run-pass/issue-16922.rs
@@ -0,0 +1,18 @@
+// Copyright 2015 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.
+
+use std::any::Any;
+
+fn foo(_: &u8) {
+}
+
+fn main() {
+    let _ = &foo as &Any;
+}
diff --git a/src/test/run-pass/issue-19982.rs b/src/test/run-pass/issue-19982.rs
new file mode 100644
index 00000000000..3082fc27a7d
--- /dev/null
+++ b/src/test/run-pass/issue-19982.rs
@@ -0,0 +1,22 @@
+// Copyright 2015 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.
+
+#![feature(core,unboxed_closures)]
+
+#[allow(dead_code)]
+struct Foo;
+
+impl<'a> Fn<(&'a (),)> for Foo {
+    type Output = ();
+
+    extern "rust-call" fn call(&self, (_,): (&(),)) {}
+}
+
+fn main() {}
diff --git a/src/test/run-pass/issue-20396.rs b/src/test/run-pass/issue-20396.rs
new file mode 100644
index 00000000000..63a88988162
--- /dev/null
+++ b/src/test/run-pass/issue-20396.rs
@@ -0,0 +1,23 @@
+// Copyright 2015 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.
+
+#![allow(dead_code)]
+
+trait Foo<T> {
+    fn noop(&self, _: T);
+}
+
+enum Bar<T> { Bla(T) }
+
+struct Baz<'a> {
+    inner: for<'b> Foo<Bar<&'b ()>> + 'a,
+}
+
+fn main() {}
diff --git a/src/test/run-pass/issue-20823.rs b/src/test/run-pass/issue-20823.rs
index 561b6195476..c297998b649 100644
--- a/src/test/run-pass/issue-20823.rs
+++ b/src/test/run-pass/issue-20823.rs
@@ -14,4 +14,4 @@
 #![deny(unstable)]
 
 #[test]
-fn foo() {}
+pub fn foo() {}
diff --git a/src/test/run-pass/issue-22577.rs b/src/test/run-pass/issue-22577.rs
index 1ecdd39ca7a..f668cae66c6 100644
--- a/src/test/run-pass/issue-22577.rs
+++ b/src/test/run-pass/issue-22577.rs
@@ -25,5 +25,8 @@ fn main() {
     assert_both::<net::TcpListener>();
     assert_both::<net::UdpSocket>();
     assert_both::<net::SocketAddr>();
-    assert_both::<net::IpAddr>();
+    assert_both::<net::SocketAddrV4>();
+    assert_both::<net::SocketAddrV6>();
+    assert_both::<net::Ipv4Addr>();
+    assert_both::<net::Ipv6Addr>();
 }
diff --git a/src/test/run-pass/issue-5950.rs b/src/test/run-pass/issue-5950.rs
index c9413258e0f..88bbba44bbe 100644
--- a/src/test/run-pass/issue-5950.rs
+++ b/src/test/run-pass/issue-5950.rs
@@ -11,6 +11,6 @@
 
 pub use local as local_alias;
 
-mod local { }
+pub mod local { }
 
 pub fn main() {}
diff --git a/src/test/run-pass/issue-9951.rs b/src/test/run-pass/issue-9951.rs
new file mode 100644
index 00000000000..210f647e5be
--- /dev/null
+++ b/src/test/run-pass/issue-9951.rs
@@ -0,0 +1,28 @@
+// Copyright 2015 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.
+
+#![allow(unused_variables)]
+
+trait Bar {
+  fn noop(&self);
+}
+impl Bar for u8 {
+  fn noop(&self) {}
+}
+
+fn main() {
+    let (a, b) = (&5u8 as &Bar, &9u8 as &Bar);
+    let (c, d): (&Bar, &Bar) = (a, b);
+
+    let (a, b) = (Box::new(5u8) as Box<Bar>, Box::new(9u8) as Box<Bar>);
+    let (c, d): (&Bar, &Bar) = (&*a, &*b);
+
+    let (c, d): (&Bar, &Bar) = (&5, &9);
+}
diff --git a/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs b/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs
index 3ffac98418a..f1d41a0f422 100644
--- a/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs
+++ b/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs
@@ -12,7 +12,6 @@
 // type is `&mut [u8]`, passes in a pointer to the lvalue and not a
 // temporary. Issue #19147.
 
-use std::raw;
 use std::mem;
 use std::slice;
 use std::old_io::IoResult;
@@ -27,10 +26,10 @@ impl<'a> MyWriter for &'a mut [u8] {
 
         let write_len = buf.len();
         unsafe {
-            *self = mem::transmute(raw::Slice {
-                data: self.as_ptr().offset(write_len as int),
-                len: self.len() - write_len,
-            });
+            *self = slice::from_raw_parts_mut(
+                self.as_mut_ptr().offset(write_len as isize),
+                self.len() - write_len
+            );
         }
 
         Ok(())
diff --git a/src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs b/src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs
index 7c99c968e35..f7985efbc31 100644
--- a/src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs
+++ b/src/test/run-pass/test-fn-signature-verification-for-explicit-return-type.rs
@@ -13,8 +13,8 @@
 extern crate test;
 
 #[bench]
-fn bench_explicit_return_type(_: &mut ::test::Bencher) -> () {}
+pub fn bench_explicit_return_type(_: &mut ::test::Bencher) -> () {}
 
 #[test]
-fn test_explicit_return_type() -> () {}
+pub fn test_explicit_return_type() -> () {}
 
diff --git a/src/test/run-pass/test-should-fail-good-message.rs b/src/test/run-pass/test-should-fail-good-message.rs
index b8e05b4d35a..94d20f703a0 100644
--- a/src/test/run-pass/test-should-fail-good-message.rs
+++ b/src/test/run-pass/test-should-fail-good-message.rs
@@ -13,13 +13,13 @@
 
 #[test]
 #[should_panic(expected = "foo")]
-fn test_foo() {
+pub fn test_foo() {
     panic!("foo bar")
 }
 
 #[test]
 #[should_panic(expected = "foo")]
-fn test_foo_dynamic() {
+pub fn test_foo_dynamic() {
     panic!("{} bar", "foo")
 }
 
diff --git a/src/test/run-pass/unsized3.rs b/src/test/run-pass/unsized3.rs
index 5bd76d093d4..f9185cd2642 100644
--- a/src/test/run-pass/unsized3.rs
+++ b/src/test/run-pass/unsized3.rs
@@ -15,31 +15,32 @@
 
 use std::mem;
 use std::raw;
+use std::slice;
 
 struct Foo<T> {
     f: [T],
 }
 
 struct Bar {
-    f1: uint,
-    f2: [uint],
+    f1: usize,
+    f2: [usize],
 }
 
 struct Baz {
-    f1: uint,
+    f1: usize,
     f2: str,
 }
 
 trait Tr {
-    fn foo(&self) -> uint;
+    fn foo(&self) -> usize;
 }
 
 struct St {
-    f: uint
+    f: usize
 }
 
 impl Tr for St {
-    fn foo(&self) -> uint {
+    fn foo(&self) -> usize {
         self.f
     }
 }
@@ -67,18 +68,18 @@ pub fn main() {
         }
 
         let data: Box<Foo_<i32>> = box Foo_{f: [1, 2, 3] };
-        let x: &Foo<i32> = mem::transmute(raw::Slice { len: 3, data: &*data });
+        let x: &Foo<i32> = mem::transmute(slice::from_raw_parts(&*data, 3));
         assert!(x.f.len() == 3);
         assert!(x.f[0] == 1);
 
         struct Baz_ {
-            f1: uint,
+            f1: usize,
             f2: [u8; 5],
         }
 
         let data: Box<_> = box Baz_ {
             f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] };
-        let x: &Baz = mem::transmute( raw::Slice { len: 5, data: &*data } );
+        let x: &Baz = mem::transmute(slice::from_raw_parts(&*data, 5));
         assert!(x.f1 == 42);
         let chs: Vec<char> = x.f2.chars().collect();
         assert!(chs.len() == 5);