]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #41090 - rap2hpoutre:patch-2, r=steveklabnik
authorCorey Farwell <coreyf@rwell.org>
Thu, 6 Apr 2017 18:55:05 +0000 (14:55 -0400)
committerGitHub <noreply@github.com>
Thu, 6 Apr 2017 18:55:05 +0000 (14:55 -0400)
Add example to std::process::abort

This is a second step in order to complete this issue: https://github.com/rust-lang/rust/issues/29370
I submitted this PR with the help of @steveklabnik again. Thanks to him! More info here: https://github.com/rust-lang/rust/issues/29370#issuecomment-290653877

261 files changed:
.travis.yml
appveyor.yml
cargo
src/bootstrap/bootstrap.py
src/bootstrap/clean.rs
src/bootstrap/flags.rs
src/bootstrap/install.rs
src/bootstrap/step.rs
src/ci/docker/armhf-gnu/Dockerfile
src/ci/docker/cross/Dockerfile
src/ci/docker/dist-aarch64-linux/Dockerfile
src/ci/docker/dist-android/Dockerfile
src/ci/docker/dist-arm-linux/Dockerfile
src/ci/docker/dist-armhf-linux/Dockerfile
src/ci/docker/dist-armv7-linux/Dockerfile
src/ci/docker/dist-fuchsia/Dockerfile
src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile
src/ci/docker/dist-i586-gnu-i686-musl/build-musl.sh
src/ci/docker/dist-i686-freebsd/Dockerfile
src/ci/docker/dist-i686-linux/Dockerfile
src/ci/docker/dist-mips-linux/Dockerfile
src/ci/docker/dist-mips64-linux/Dockerfile
src/ci/docker/dist-mips64el-linux/Dockerfile
src/ci/docker/dist-mipsel-linux/Dockerfile
src/ci/docker/dist-powerpc-linux/Dockerfile
src/ci/docker/dist-powerpc64-linux/Dockerfile
src/ci/docker/dist-powerpc64le-linux/Dockerfile
src/ci/docker/dist-s390x-linux/Dockerfile
src/ci/docker/dist-x86_64-freebsd/Dockerfile
src/ci/docker/dist-x86_64-linux/Dockerfile
src/ci/docker/dist-x86_64-musl/Dockerfile
src/ci/docker/dist-x86_64-musl/build-musl.sh
src/ci/docker/dist-x86_64-netbsd/Dockerfile
src/ci/docker/emscripten/Dockerfile
src/ci/docker/i686-gnu-nopt/Dockerfile
src/ci/docker/i686-gnu/Dockerfile
src/ci/docker/x86_64-gnu-aux/Dockerfile
src/ci/docker/x86_64-gnu-debug/Dockerfile
src/ci/docker/x86_64-gnu-distcheck/Dockerfile
src/ci/docker/x86_64-gnu-full-bootstrap/Dockerfile
src/ci/docker/x86_64-gnu-incremental/Dockerfile
src/ci/docker/x86_64-gnu-llvm-3.7/Dockerfile
src/ci/docker/x86_64-gnu-nopt/Dockerfile
src/ci/docker/x86_64-gnu/Dockerfile
src/doc/unstable-book/src/SUMMARY.md
src/doc/unstable-book/src/offset-to.md [new file with mode: 0644]
src/doc/unstable-book/src/slice-rsplit.md [new file with mode: 0644]
src/doc/unstable-book/src/windows-subsystem.md [deleted file]
src/etc/char_private.py
src/etc/make-win-dist.py
src/libcollections/Cargo.toml
src/libcollections/lib.rs
src/libcollections/linked_list.rs
src/libcollections/slice.rs
src/libcollections/tests/binary_heap.rs [new file with mode: 0644]
src/libcollections/tests/btree/map.rs [new file with mode: 0644]
src/libcollections/tests/btree/mod.rs [new file with mode: 0644]
src/libcollections/tests/btree/set.rs [new file with mode: 0644]
src/libcollections/tests/cow_str.rs [new file with mode: 0644]
src/libcollections/tests/fmt.rs [new file with mode: 0644]
src/libcollections/tests/lib.rs [new file with mode: 0644]
src/libcollections/tests/linked_list.rs [new file with mode: 0644]
src/libcollections/tests/slice.rs [new file with mode: 0644]
src/libcollections/tests/str.rs [new file with mode: 0644]
src/libcollections/tests/string.rs [new file with mode: 0644]
src/libcollections/tests/vec.rs [new file with mode: 0644]
src/libcollections/tests/vec_deque.rs [new file with mode: 0644]
src/libcollections/vec.rs
src/libcollections/vec_deque.rs
src/libcollectionstest/binary_heap.rs [deleted file]
src/libcollectionstest/btree/map.rs [deleted file]
src/libcollectionstest/btree/mod.rs [deleted file]
src/libcollectionstest/btree/set.rs [deleted file]
src/libcollectionstest/cow_str.rs [deleted file]
src/libcollectionstest/fmt.rs [deleted file]
src/libcollectionstest/lib.rs [deleted file]
src/libcollectionstest/linked_list.rs [deleted file]
src/libcollectionstest/slice.rs [deleted file]
src/libcollectionstest/str.rs [deleted file]
src/libcollectionstest/string.rs [deleted file]
src/libcollectionstest/vec.rs [deleted file]
src/libcollectionstest/vec_deque.rs [deleted file]
src/libcore/Cargo.toml
src/libcore/char_private.rs
src/libcore/intrinsics.rs
src/libcore/iter/mod.rs
src/libcore/iter/traits.rs
src/libcore/num/bignum.rs
src/libcore/num/dec2flt/rawfp.rs
src/libcore/num/diy_float.rs
src/libcore/num/flt2dec/mod.rs
src/libcore/num/mod.rs
src/libcore/option.rs
src/libcore/ptr.rs
src/libcore/slice/mod.rs
src/libcore/str/mod.rs
src/libcore/sync/atomic.rs
src/libcore/tests/any.rs [new file with mode: 0644]
src/libcore/tests/array.rs [new file with mode: 0644]
src/libcore/tests/atomic.rs [new file with mode: 0644]
src/libcore/tests/cell.rs [new file with mode: 0644]
src/libcore/tests/char.rs [new file with mode: 0644]
src/libcore/tests/clone.rs [new file with mode: 0644]
src/libcore/tests/cmp.rs [new file with mode: 0644]
src/libcore/tests/fmt/builders.rs [new file with mode: 0644]
src/libcore/tests/fmt/float.rs [new file with mode: 0644]
src/libcore/tests/fmt/mod.rs [new file with mode: 0644]
src/libcore/tests/fmt/num.rs [new file with mode: 0644]
src/libcore/tests/hash/mod.rs [new file with mode: 0644]
src/libcore/tests/hash/sip.rs [new file with mode: 0644]
src/libcore/tests/intrinsics.rs [new file with mode: 0644]
src/libcore/tests/iter.rs [new file with mode: 0644]
src/libcore/tests/lib.rs [new file with mode: 0644]
src/libcore/tests/mem.rs [new file with mode: 0644]
src/libcore/tests/nonzero.rs [new file with mode: 0644]
src/libcore/tests/num/bignum.rs [new file with mode: 0644]
src/libcore/tests/num/dec2flt/mod.rs [new file with mode: 0644]
src/libcore/tests/num/dec2flt/parse.rs [new file with mode: 0644]
src/libcore/tests/num/dec2flt/rawfp.rs [new file with mode: 0644]
src/libcore/tests/num/flt2dec/estimator.rs [new file with mode: 0644]
src/libcore/tests/num/flt2dec/mod.rs [new file with mode: 0644]
src/libcore/tests/num/flt2dec/strategy/dragon.rs [new file with mode: 0644]
src/libcore/tests/num/flt2dec/strategy/grisu.rs [new file with mode: 0644]
src/libcore/tests/num/i16.rs [new file with mode: 0644]
src/libcore/tests/num/i32.rs [new file with mode: 0644]
src/libcore/tests/num/i64.rs [new file with mode: 0644]
src/libcore/tests/num/i8.rs [new file with mode: 0644]
src/libcore/tests/num/int_macros.rs [new file with mode: 0644]
src/libcore/tests/num/mod.rs [new file with mode: 0644]
src/libcore/tests/num/u16.rs [new file with mode: 0644]
src/libcore/tests/num/u32.rs [new file with mode: 0644]
src/libcore/tests/num/u64.rs [new file with mode: 0644]
src/libcore/tests/num/u8.rs [new file with mode: 0644]
src/libcore/tests/num/uint_macros.rs [new file with mode: 0644]
src/libcore/tests/ops.rs [new file with mode: 0644]
src/libcore/tests/option.rs [new file with mode: 0644]
src/libcore/tests/ptr.rs [new file with mode: 0644]
src/libcore/tests/result.rs [new file with mode: 0644]
src/libcore/tests/slice.rs [new file with mode: 0644]
src/libcore/tests/str.rs [new file with mode: 0644]
src/libcore/tests/tuple.rs [new file with mode: 0644]
src/libcoretest/any.rs [deleted file]
src/libcoretest/array.rs [deleted file]
src/libcoretest/atomic.rs [deleted file]
src/libcoretest/cell.rs [deleted file]
src/libcoretest/char.rs [deleted file]
src/libcoretest/clone.rs [deleted file]
src/libcoretest/cmp.rs [deleted file]
src/libcoretest/fmt/builders.rs [deleted file]
src/libcoretest/fmt/float.rs [deleted file]
src/libcoretest/fmt/mod.rs [deleted file]
src/libcoretest/fmt/num.rs [deleted file]
src/libcoretest/hash/mod.rs [deleted file]
src/libcoretest/hash/sip.rs [deleted file]
src/libcoretest/intrinsics.rs [deleted file]
src/libcoretest/iter.rs [deleted file]
src/libcoretest/lib.rs [deleted file]
src/libcoretest/mem.rs [deleted file]
src/libcoretest/nonzero.rs [deleted file]
src/libcoretest/num/bignum.rs [deleted file]
src/libcoretest/num/dec2flt/mod.rs [deleted file]
src/libcoretest/num/dec2flt/parse.rs [deleted file]
src/libcoretest/num/dec2flt/rawfp.rs [deleted file]
src/libcoretest/num/flt2dec/estimator.rs [deleted file]
src/libcoretest/num/flt2dec/mod.rs [deleted file]
src/libcoretest/num/flt2dec/strategy/dragon.rs [deleted file]
src/libcoretest/num/flt2dec/strategy/grisu.rs [deleted file]
src/libcoretest/num/i16.rs [deleted file]
src/libcoretest/num/i32.rs [deleted file]
src/libcoretest/num/i64.rs [deleted file]
src/libcoretest/num/i8.rs [deleted file]
src/libcoretest/num/int_macros.rs [deleted file]
src/libcoretest/num/mod.rs [deleted file]
src/libcoretest/num/u16.rs [deleted file]
src/libcoretest/num/u32.rs [deleted file]
src/libcoretest/num/u64.rs [deleted file]
src/libcoretest/num/u8.rs [deleted file]
src/libcoretest/num/uint_macros.rs [deleted file]
src/libcoretest/ops.rs [deleted file]
src/libcoretest/option.rs [deleted file]
src/libcoretest/ptr.rs [deleted file]
src/libcoretest/result.rs [deleted file]
src/libcoretest/slice.rs [deleted file]
src/libcoretest/str.rs [deleted file]
src/libcoretest/tuple.rs [deleted file]
src/librustc/hir/map/definitions.rs
src/librustc/ich/hcx.rs [new file with mode: 0644]
src/librustc/ich/impls_const_math.rs [new file with mode: 0644]
src/librustc/ich/impls_hir.rs [new file with mode: 0644]
src/librustc/ich/impls_mir.rs [new file with mode: 0644]
src/librustc/ich/impls_syntax.rs [new file with mode: 0644]
src/librustc/ich/impls_ty.rs [new file with mode: 0644]
src/librustc/ich/mod.rs
src/librustc/lib.rs
src/librustc/macros.rs
src/librustc/mir/cache.rs
src/librustc/mir/mod.rs
src/librustc/ty/layout.rs
src/librustc/ty/mod.rs
src/librustc_const_eval/eval.rs
src/librustc_data_structures/lib.rs
src/librustc_data_structures/stable_hasher.rs
src/librustc_driver/driver.rs
src/librustc_incremental/calculate_svh/mod.rs
src/librustc_incremental/calculate_svh/svh_visitor.rs [deleted file]
src/librustc_incremental/lib.rs
src/librustc_llvm/build.rs
src/librustc_llvm/ffi.rs
src/librustc_mir/build/cfg.rs
src/librustc_resolve/macros.rs
src/librustc_save_analysis/dump_visitor.rs
src/librustc_save_analysis/lib.rs
src/librustc_trans/assert_module_sources.rs
src/librustc_trans/back/link.rs
src/librustc_trans/back/linker.rs
src/librustc_trans/mir/block.rs
src/librustc_typeck/check/method/suggest.rs
src/librustc_typeck/coherence/inherent_impls_overlap.rs
src/librustdoc/html/markdown.rs
src/libstd/ascii.rs
src/libstd/collections/hash/map.rs
src/libstd/collections/hash/table.rs
src/libstd/fs.rs
src/libstd/sync/barrier.rs
src/libstd/sync/mpsc/mod.rs
src/libstd/sync/mutex.rs
src/libstd/sys/unix/ext/io.rs
src/libstd/sys/unix/mod.rs
src/libstd/sys/unix/pipe.rs
src/libstd/thread/mod.rs
src/libsyntax/ext/derive.rs
src/libsyntax/feature_gate.rs
src/libsyntax/parse/parser.rs
src/libsyntax/ptr.rs
src/libsyntax/util/rc_slice.rs
src/libsyntax_pos/lib.rs
src/libtest/stats.rs
src/libunwind/build.rs
src/libunwind/lib.rs
src/test/codegen/personality_lifetimes.rs [new file with mode: 0644]
src/test/compile-fail/coherence-overlapping-inherent-impl-trait.rs [deleted file]
src/test/compile-fail/inherent-overlap.rs [deleted file]
src/test/compile-fail/windows-subsystem-gated.rs [deleted file]
src/test/compile-fail/windows-subsystem-invalid.rs
src/test/run-make/multiple-emits/Makefile [new file with mode: 0644]
src/test/run-make/multiple-emits/foo.rs [new file with mode: 0644]
src/test/run-make/save-analysis-fail/foo.rs
src/test/run-make/windows-subsystem/console.rs
src/test/run-make/windows-subsystem/windows.rs
src/test/run-pass/const-err.rs
src/test/run-pass/issue-40962.rs [new file with mode: 0644]
src/test/rustdoc/test-lists.rs [new file with mode: 0644]
src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.rs [new file with mode: 0644]
src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr [new file with mode: 0644]
src/test/ui/codemap_tests/overlapping_inherent_impls.rs [new file with mode: 0644]
src/test/ui/codemap_tests/overlapping_inherent_impls.stderr [new file with mode: 0644]
src/test/ui/did_you_mean/issue-40006.rs [new file with mode: 0644]
src/test/ui/did_you_mean/issue-40006.stderr [new file with mode: 0644]
src/test/ui/suggestions/confuse-field-and-method/private-field.rs [new file with mode: 0644]
src/test/ui/suggestions/confuse-field-and-method/private-field.stderr [new file with mode: 0644]
src/tools/tidy/src/pal.rs

index e5b57a389ecbed702f88bf2c8b9ab32f5f95002a..0ffba70d2ef4401b85060756e1324316867370ff 100644 (file)
@@ -63,7 +63,7 @@ matrix:
       os: osx
       osx_image: xcode8.2
       install: &osx_install_sccache >
-        travis_retry curl -o /usr/local/bin/sccache https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-apple-darwin &&
+        travis_retry curl -o /usr/local/bin/sccache https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-apple-darwin &&
           chmod +x /usr/local/bin/sccache &&
         travis_retry curl -o /usr/local/bin/stamp https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-17-stamp-x86_64-apple-darwin &&
           chmod +x /usr/local/bin/stamp
index 68b2a239aff1babc31c622fd0631dd4abaac9c78..83cfea0dd834e519c67f143398eb655380b0d33a 100644 (file)
@@ -115,8 +115,8 @@ install:
   - set PATH=C:\Python27;%PATH%
 
   # Download and install sccache
-  - appveyor-retry appveyor DownloadFile https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-pc-windows-msvc
-  - mv 2017-03-24-sccache-x86_64-pc-windows-msvc sccache.exe
+  - appveyor-retry appveyor DownloadFile https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-pc-windows-msvc
+  - mv 2017-04-04-sccache-x86_64-pc-windows-msvc sccache.exe
   - set PATH=%PATH%;%CD%
 
   # Download and install ninja
diff --git a/cargo b/cargo
index 4e95c6b41eca3388f54dd5f7787366ad2df637b5..4729175045b41b688ab903120860866ce7a22ba9 160000 (submodule)
--- a/cargo
+++ b/cargo
@@ -1 +1 @@
-Subproject commit 4e95c6b41eca3388f54dd5f7787366ad2df637b5
+Subproject commit 4729175045b41b688ab903120860866ce7a22ba9
index d5bc6127a1e7fe31d9db5b50a7c0f597b0d17456..526beb41aae5b6dc3a63e13173dd247a6c9058bd 100644 (file)
@@ -163,12 +163,13 @@ class RustBuild(object):
         if not os.path.exists(rustc_cache):
             os.makedirs(rustc_cache)
 
+        channel = self.stage0_rustc_channel()
+
         if self.rustc().startswith(self.bin_root()) and \
                 (not os.path.exists(self.rustc()) or self.rustc_out_of_date()):
             self.print_what_it_means_to_bootstrap()
             if os.path.exists(self.bin_root()):
                 shutil.rmtree(self.bin_root())
-            channel = self.stage0_rustc_channel()
             filename = "rust-std-{}-{}.tar.gz".format(channel, self.build)
             url = "https://static.rust-lang.org/dist/" + self.stage0_rustc_date()
             tarball = os.path.join(rustc_cache, filename)
@@ -189,6 +190,14 @@ class RustBuild(object):
             with open(self.rustc_stamp(), 'w') as f:
                 f.write(self.stage0_rustc_date())
 
+            if "pc-windows-gnu" in self.build:
+                filename = "rust-mingw-{}-{}.tar.gz".format(channel, self.build)
+                url = "https://static.rust-lang.org/dist/" + self.stage0_rustc_date()
+                tarball = os.path.join(rustc_cache, filename)
+                if not os.path.exists(tarball):
+                    get("{}/{}".format(url, filename), tarball, verbose=self.verbose)
+                unpack(tarball, self.bin_root(), match="rust-mingw", verbose=self.verbose)
+
         if self.cargo().startswith(self.bin_root()) and \
                 (not os.path.exists(self.cargo()) or self.cargo_out_of_date()):
             self.print_what_it_means_to_bootstrap()
@@ -591,16 +600,19 @@ def bootstrap():
 
 def main():
     start_time = time()
+    help_triggered = ('-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1)
     try:
         bootstrap()
-        print("Build completed successfully in %s" % format_build_time(time() - start_time))
+        if not help_triggered:
+            print("Build completed successfully in %s" % format_build_time(time() - start_time))
     except (SystemExit, KeyboardInterrupt) as e:
         if hasattr(e, 'code') and isinstance(e.code, int):
             exit_code = e.code
         else:
             exit_code = 1
             print(e)
-        print("Build completed unsuccessfully in %s" % format_build_time(time() - start_time))
+        if not help_triggered:
+            print("Build completed unsuccessfully in %s" % format_build_time(time() - start_time))
         sys.exit(exit_code)
 
 if __name__ == '__main__':
index e9547ee42d0771c8be57a92eb67cec822ad154c9..308a0ab3076dd5421f90d17efe36562364214b8d 100644 (file)
@@ -44,26 +44,25 @@ pub fn clean(build: &Build) {
 }
 
 fn rm_rf(path: &Path) {
-    if !path.exists() {
-        return
-    }
-    if path.is_file() {
-        return do_op(path, "remove file", |p| fs::remove_file(p));
-    }
-
-    for file in t!(fs::read_dir(path)) {
-        let file = t!(file).path();
+    match path.symlink_metadata() {
+        Err(e) => {
+            if e.kind() == ErrorKind::NotFound {
+                return;
+            }
+            panic!("failed to get metadata for file {}: {}", path.display(), e);
+        },
+        Ok(metadata) => {
+            if metadata.file_type().is_file() || metadata.file_type().is_symlink() {
+                do_op(path, "remove file", |p| fs::remove_file(p));
+                return;
+            }
 
-        if file.is_dir() {
-            rm_rf(&file);
-        } else {
-            // On windows we can't remove a readonly file, and git will
-            // often clone files as readonly. As a result, we have some
-            // special logic to remove readonly files on windows.
-            do_op(&file, "remove file", |p| fs::remove_file(p));
-        }
-    }
-    do_op(path, "remove dir", |p| fs::remove_dir(p));
+            for file in t!(fs::read_dir(path)) {
+                rm_rf(&t!(file).path());
+            }
+            do_op(path, "remove dir", |p| fs::remove_dir(p));
+        },
+    };
 }
 
 fn do_op<F>(path: &Path, desc: &str, mut f: F)
@@ -71,9 +70,12 @@ fn do_op<F>(path: &Path, desc: &str, mut f: F)
 {
     match f(path) {
         Ok(()) => {}
+        // On windows we can't remove a readonly file, and git will often clone files as readonly.
+        // As a result, we have some special logic to remove readonly files on windows.
+        // This is also the reason that we can't use things like fs::remove_dir_all().
         Err(ref e) if cfg!(windows) &&
                       e.kind() == ErrorKind::PermissionDenied => {
-            let mut p = t!(path.metadata()).permissions();
+            let mut p = t!(path.symlink_metadata()).permissions();
             p.set_readonly(false);
             t!(fs::set_permissions(path, p));
             f(path).unwrap_or_else(|e| {
index b55f3d710ca7bfcee4643dd40d4e6836dc495503..a1466d68a135aa4950b13eb9771c182626c162a8 100644 (file)
@@ -18,7 +18,7 @@
 use std::path::PathBuf;
 use std::process;
 
-use getopts::{Matches, Options};
+use getopts::Options;
 
 use Build;
 use config::Config;
@@ -75,7 +75,22 @@ pub enum Subcommand {
 
 impl Flags {
     pub fn parse(args: &[String]) -> Flags {
+        let mut extra_help = String::new();
+        let mut subcommand_help = format!("\
+Usage: x.py <subcommand> [options] [<paths>...]
+
+Subcommands:
+    build       Compile either the compiler or libraries
+    test        Build and run some test suites
+    bench       Build and run some benchmarks
+    doc         Build documentation
+    clean       Clean out build directories
+    dist        Build and/or install distribution artifacts
+
+To learn more about a subcommand, run `./x.py <subcommand> -h`");
+
         let mut opts = Options::new();
+        // Options common to all subcommands
         opts.optflagmulti("v", "verbose", "use verbose output (-vv for very verbose)");
         opts.optflag("i", "incremental", "use incremental compilation");
         opts.optopt("", "config", "TOML configuration file for build", "FILE");
@@ -89,21 +104,83 @@ pub fn parse(args: &[String]) -> Flags {
         opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS");
         opts.optflag("h", "help", "print this help message");
 
-        let usage = |n, opts: &Options| -> ! {
-            let command = args.get(0).map(|s| &**s);
-            let brief = format!("Usage: x.py {} [options] [<args>...]",
-                                command.unwrap_or("<command>"));
+        // fn usage()
+        let usage = |exit_code: i32, opts: &Options, subcommand_help: &str, extra_help: &str| -> ! {
+            println!("{}", opts.usage(subcommand_help));
+            if !extra_help.is_empty() {
+                println!("{}", extra_help);
+            }
+            process::exit(exit_code);
+        };
+
+        // We can't use getopt to parse the options until we have completed specifying which
+        // options are valid, but under the current implementation, some options are conditional on
+        // the subcommand. Therefore we must manually identify the subcommand first, so that we can
+        // complete the definition of the options.  Then we can use the getopt::Matches object from
+        // there on out.
+        let mut possible_subcommands = args.iter().collect::<Vec<_>>();
+        possible_subcommands.retain(|&s|
+                                           (s == "build")
+                                        || (s == "test")
+                                        || (s == "bench")
+                                        || (s == "doc")
+                                        || (s == "clean")
+                                        || (s == "dist"));
+        let subcommand = match possible_subcommands.first() {
+            Some(s) => s,
+            None => {
+                // No subcommand -- show the general usage and subcommand help
+                println!("{}\n", subcommand_help);
+                process::exit(0);
+            }
+        };
 
-            println!("{}", opts.usage(&brief));
-            match command {
-                Some("build") => {
-                    println!("\
+        // Some subcommands get extra options
+        match subcommand.as_str() {
+            "test"  => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
+            "bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
+            "dist"  => { opts.optflag("", "install", "run installer as well"); },
+            _ => { },
+        };
+
+        // Done specifying what options are possible, so do the getopts parsing
+        let matches = opts.parse(&args[..]).unwrap_or_else(|e| {
+            // Invalid argument/option format
+            println!("\n{}\n", e);
+            usage(1, &opts, &subcommand_help, &extra_help);
+        });
+        // Extra sanity check to make sure we didn't hit this crazy corner case:
+        //
+        //     ./x.py --frobulate clean build
+        //            ^-- option  ^     ^- actual subcommand
+        //                        \_ arg to option could be mistaken as subcommand
+        let mut pass_sanity_check = true;
+        match matches.free.get(0) {
+            Some(check_subcommand) => {
+                if &check_subcommand != subcommand {
+                    pass_sanity_check = false;
+                }
+            },
+            None => {
+                pass_sanity_check = false;
+            }
+        }
+        if !pass_sanity_check {
+            println!("{}\n", subcommand_help);
+            println!("Sorry, I couldn't figure out which subcommand you were trying to specify.\n\
+                      You may need to move some options to after the subcommand.\n");
+            process::exit(1);
+        }
+        // Extra help text for some commands
+        match subcommand.as_str() {
+            "build" => {
+                subcommand_help.push_str("\n
 Arguments:
-    This subcommand accepts a number of positional arguments of directories to
-    the crates and/or artifacts to compile. For example:
+    This subcommand accepts a number of paths to directories to the crates
+    and/or artifacts to compile. For example:
 
         ./x.py build src/libcore
-        ./x.py build src/libproc_macro
+        ./x.py build src/libcore src/libproc_macro
         ./x.py build src/libstd --stage 1
 
     If no arguments are passed then the complete artifacts for that stage are
@@ -114,15 +191,13 @@ pub fn parse(args: &[String]) -> Flags {
 
     For a quick build with a usable compile, you can pass:
 
-        ./x.py build --stage 1 src/libtest
-");
-                }
-
-                Some("test") => {
-                    println!("\
+        ./x.py build --stage 1 src/libtest");
+            }
+            "test" => {
+                subcommand_help.push_str("\n
 Arguments:
-    This subcommand accepts a number of positional arguments of directories to
-    tests that should be compiled and run. For example:
+    This subcommand accepts a number of paths to directories to tests that
+    should be compiled and run. For example:
 
         ./x.py test src/test/run-pass
         ./x.py test src/libstd --test-args hash_map
@@ -132,139 +207,90 @@ pub fn parse(args: &[String]) -> Flags {
     compiled and tested.
 
         ./x.py test
-        ./x.py test --stage 1
-");
-                }
-
-                Some("doc") => {
-                    println!("\
+        ./x.py test --stage 1");
+            }
+            "doc" => {
+                subcommand_help.push_str("\n
 Arguments:
-    This subcommand accepts a number of positional arguments of directories of
-    documentation to build. For example:
+    This subcommand accepts a number of paths to directories of documentation
+    to build. For example:
 
         ./x.py doc src/doc/book
         ./x.py doc src/doc/nomicon
-        ./x.py doc src/libstd
+        ./x.py doc src/doc/book src/libstd
 
     If no arguments are passed then everything is documented:
 
         ./x.py doc
-        ./x.py doc --stage 1
-");
-                }
-
-                _ => {}
+        ./x.py doc --stage 1");
             }
-
-            if let Some(command) = command {
-                if command == "build" ||
-                   command == "dist" ||
-                   command == "doc" ||
-                   command == "test" ||
-                   command == "bench" ||
-                   command == "clean"  {
-                    println!("Available invocations:");
-                    if args.iter().any(|a| a == "-v") {
-                        let flags = Flags::parse(&["build".to_string()]);
-                        let mut config = Config::default();
-                        config.build = flags.build.clone();
-                        let mut build = Build::new(flags, config);
-                        metadata::build(&mut build);
-                        step::build_rules(&build).print_help(command);
-                    } else {
-                        println!("    ... elided, run `./x.py {} -h -v` to see",
-                                 command);
-                    }
-
-                    println!("");
-                }
-            }
-
-println!("\
-Subcommands:
-    build       Compile either the compiler or libraries
-    test        Build and run some test suites
-    bench       Build and run some benchmarks
-    doc         Build documentation
-    clean       Clean out build directories
-    dist        Build and/or install distribution artifacts
-
-To learn more about a subcommand, run `./x.py <command> -h`
-");
-
-            process::exit(n);
+            _ => { }
         };
-        if args.len() == 0 {
-            println!("a command must be passed");
-            usage(1, &opts);
-        }
-        let parse = |opts: &Options| {
-            let m = opts.parse(&args[1..]).unwrap_or_else(|e| {
-                println!("failed to parse options: {}", e);
-                usage(1, opts);
-            });
-            if m.opt_present("h") {
-                usage(0, opts);
+        // Get any optional paths which occur after the subcommand
+        let cwd = t!(env::current_dir());
+        let paths = matches.free[1..].iter().map(|p| cwd.join(p)).collect::<Vec<_>>();
+
+
+        // All subcommands can have an optional "Available paths" section
+        if matches.opt_present("verbose") {
+            let flags = Flags::parse(&["build".to_string()]);
+            let mut config = Config::default();
+            config.build = flags.build.clone();
+            let mut build = Build::new(flags, config);
+            metadata::build(&mut build);
+            let maybe_rules_help = step::build_rules(&build).get_help(subcommand);
+            if maybe_rules_help.is_some() {
+                extra_help.push_str(maybe_rules_help.unwrap().as_str());
             }
-            return m
-        };
+        } else {
+            extra_help.push_str(format!("Run `./x.py {} -h -v` to see a list of available paths.",
+                     subcommand).as_str());
+        }
 
-        let cwd = t!(env::current_dir());
-        let remaining_as_path = |m: &Matches| {
-            m.free.iter().map(|p| cwd.join(p)).collect::<Vec<_>>()
-        };
+        // User passed in -h/--help?
+        if matches.opt_present("help") {
+            usage(0, &opts, &subcommand_help, &extra_help);
+        }
 
-        let m: Matches;
-        let cmd = match &args[0][..] {
+        let cmd = match subcommand.as_str() {
             "build" => {
-                m = parse(&opts);
-                Subcommand::Build { paths: remaining_as_path(&m) }
-            }
-            "doc" => {
-                m = parse(&opts);
-                Subcommand::Doc { paths: remaining_as_path(&m) }
+                Subcommand::Build { paths: paths }
             }
             "test" => {
-                opts.optmulti("", "test-args", "extra arguments", "ARGS");
-                m = parse(&opts);
                 Subcommand::Test {
-                    paths: remaining_as_path(&m),
-                    test_args: m.opt_strs("test-args"),
+                    paths: paths,
+                    test_args: matches.opt_strs("test-args"),
                 }
             }
             "bench" => {
-                opts.optmulti("", "test-args", "extra arguments", "ARGS");
-                m = parse(&opts);
                 Subcommand::Bench {
-                    paths: remaining_as_path(&m),
-                    test_args: m.opt_strs("test-args"),
+                    paths: paths,
+                    test_args: matches.opt_strs("test-args"),
                 }
             }
+            "doc" => {
+                Subcommand::Doc { paths: paths }
+            }
             "clean" => {
-                m = parse(&opts);
-                if m.free.len() > 0 {
-                    println!("clean takes no arguments");
-                    usage(1, &opts);
+                if paths.len() > 0 {
+                    println!("\nclean takes no arguments\n");
+                    usage(1, &opts, &subcommand_help, &extra_help);
                 }
                 Subcommand::Clean
             }
             "dist" => {
-                opts.optflag("", "install", "run installer as well");
-                m = parse(&opts);
                 Subcommand::Dist {
-                    paths: remaining_as_path(&m),
-                    install: m.opt_present("install"),
+                    paths: paths,
+                    install: matches.opt_present("install"),
                 }
             }
-            "--help" => usage(0, &opts),
-            cmd => {
-                println!("unknown command: {}", cmd);
-                usage(1, &opts);
+            _ => {
+                usage(1, &opts, &subcommand_help, &extra_help);
             }
         };
 
 
-        let cfg_file = m.opt_str("config").map(PathBuf::from).or_else(|| {
+        let cfg_file = matches.opt_str("config").map(PathBuf::from).or_else(|| {
             if fs::metadata("config.toml").is_ok() {
                 Some(PathBuf::from("config.toml"))
             } else {
@@ -272,31 +298,29 @@ pub fn parse(args: &[String]) -> Flags {
             }
         });
 
-        let mut stage = m.opt_str("stage").map(|j| j.parse().unwrap());
-
-        let incremental = m.opt_present("i");
+        let mut stage = matches.opt_str("stage").map(|j| j.parse().unwrap());
 
-        if incremental {
+        if matches.opt_present("incremental") {
             if stage.is_none() {
                 stage = Some(1);
             }
         }
 
         Flags {
-            verbose: m.opt_count("v"),
+            verbose: matches.opt_count("verbose"),
             stage: stage,
-            on_fail: m.opt_str("on-fail"),
-            keep_stage: m.opt_str("keep-stage").map(|j| j.parse().unwrap()),
-            build: m.opt_str("build").unwrap_or_else(|| {
+            on_fail: matches.opt_str("on-fail"),
+            keep_stage: matches.opt_str("keep-stage").map(|j| j.parse().unwrap()),
+            build: matches.opt_str("build").unwrap_or_else(|| {
                 env::var("BUILD").unwrap()
             }),
-            host: split(m.opt_strs("host")),
-            target: split(m.opt_strs("target")),
+            host: split(matches.opt_strs("host")),
+            target: split(matches.opt_strs("target")),
             config: cfg_file,
-            src: m.opt_str("src").map(PathBuf::from),
-            jobs: m.opt_str("jobs").map(|j| j.parse().unwrap()),
+            src: matches.opt_str("src").map(PathBuf::from),
+            jobs: matches.opt_str("jobs").map(|j| j.parse().unwrap()),
             cmd: cmd,
-            incremental: incremental,
+            incremental: matches.opt_present("incremental"),
         }
     }
 }
index 249f241a151bbd446dc3fc5c92661b954ceba9e2..25082e3a9d095645d68c8528c1a1fb915d62ddcc 100644 (file)
@@ -49,12 +49,17 @@ pub fn install(build: &Build, stage: u32, host: &str) {
         install_sh(&build, "docs", "rust-docs", stage, host, &prefix,
                    &docdir, &libdir, &mandir, &empty_dir);
     }
+
+    for target in build.config.target.iter() {
+        install_sh(&build, "std", "rust-std", stage, target, &prefix,
+                   &docdir, &libdir, &mandir, &empty_dir);
+    }
+
     if build.config.rust_save_analysis {
         install_sh(&build, "analysis", "rust-analysis", stage, host, &prefix,
                    &docdir, &libdir, &mandir, &empty_dir);
     }
-    install_sh(&build, "std", "rust-std", stage, host, &prefix,
-               &docdir, &libdir, &mandir, &empty_dir);
+
     install_sh(&build, "rustc", "rustc", stage, host, &prefix,
                &docdir, &libdir, &mandir, &empty_dir);
     t!(fs::remove_dir_all(&empty_dir));
index 6eb12fed5abb2d402a61cccc89b0412ecf1d3eb8..5560b5b0333c862b3c7b64bb23c00e7fcfb5f6c5 100644 (file)
@@ -978,26 +978,25 @@ fn verify(&self) {
         }
     }
 
-    pub fn print_help(&self, command: &str) {
+    pub fn get_help(&self, command: &str) -> Option<String> {
         let kind = match command {
             "build" => Kind::Build,
             "doc" => Kind::Doc,
             "test" => Kind::Test,
             "bench" => Kind::Bench,
             "dist" => Kind::Dist,
-            _ => return,
+            _ => return None,
         };
         let rules = self.rules.values().filter(|r| r.kind == kind);
         let rules = rules.filter(|r| !r.path.contains("nowhere"));
         let mut rules = rules.collect::<Vec<_>>();
         rules.sort_by_key(|r| r.path);
 
-        println!("Available paths:\n");
+        let mut help_string = String::from("Available paths:\n");
         for rule in rules {
-            print!("    ./x.py {} {}", command, rule.path);
-
-            println!("");
+            help_string.push_str(format!("    ./x.py {} {}\n", command, rule.path).as_str());
         }
+        Some(help_string)
     }
 
     /// Construct the top-level build steps that we're going to be executing,
index 933562c79e5821837b8fae00fa23bc908d750900..d42b35d488c3d5be27afee72e36174a513ec5e47 100644 (file)
@@ -74,7 +74,7 @@ RUN arm-linux-gnueabihf-gcc addentropy.c -o rootfs/addentropy -static
 RUN curl -O http://ftp.nl.debian.org/debian/dists/jessie/main/installer-armhf/current/images/device-tree/vexpress-v2p-ca15-tc1.dtb
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 8dc02ab522c21bf9604a500048734714fc33faa6..7c1984410078f990c969c74e836638c4a248ddce 100644 (file)
@@ -22,7 +22,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index c468a689a0565c40921d15bb00132817a182e9bf..d9a5429d2b8e894b8b3dbff2b06f09015ea7406f 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-toolchains.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/aarch64-unknown-linux-gnueabi/bin
index 44d6863bf0bbdc8430f7cab91cd0c289f41e63a6..31f4b8b777be5be44967e61694dbea67144ff069 100644 (file)
@@ -32,7 +32,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV TARGETS=arm-linux-androideabi
index 1e448dd43fd5f3c1aba60d4a6408074afca5b4fb..7162aa0efc0cfa1eae6ca5d1bc3608f6603692be 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-toolchains.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/arm-unknown-linux-gnueabi/bin
index cad96b4bde48051c140b195a3a8bb21a044ec02c..8fa1cbe492fac67ab03ed1365a57909b3ebcf482 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-toolchains.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/arm-unknown-linux-gnueabihf/bin
index d5be52eba5c2e3c75eaa2a2c7e1232f172de6841..9fcd827fc9962cda2f27ef26033fc831618f354d 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-toolchains.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/armv7-unknown-linux-gnueabihf/bin
index ed37a9e842e227a9219599bf00b70e947a8c90d5..bfffd9637fcee5049405354f8152739bf11f00e4 100644 (file)
@@ -29,7 +29,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV \
index d88ec7aab34643da663133c818c5bfadf58f7f1c..d2727cbdb3508b35a5a8cc223597397fbed9bacd 100644 (file)
@@ -26,7 +26,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV RUST_CONFIGURE_ARGS \
index a50a25c7913481cabe1bd288988c3f80f24a993c..ad285a57a84a3f56891012099ae498dab2503b9b 100644 (file)
@@ -15,11 +15,14 @@ set -ex
 export CFLAGS="-fPIC -Wa,-mrelax-relocations=no"
 export CXXFLAGS="-Wa,-mrelax-relocations=no"
 
-MUSL=musl-1.1.14
+MUSL=musl-1.1.16
 curl https://www.musl-libc.org/releases/$MUSL.tar.gz | tar xzf -
 cd $MUSL
-CFLAGS="$CFLAGS -m32" ./configure --prefix=/musl-i686 --disable-shared --target=i686
-make -j10
+CC=gcc \
+  CFLAGS="$CFLAGS -m32" \
+  ./configure --prefix=/musl-i686 --disable-shared \
+    --target=i686
+make AR=ar RANLIB=ranlib -j10
 make install
 cd ..
 
index beda2512741e936231a302d130c264e23a226f8c..3b81216c6431edc91ec7e3148b7329d9cbf38c58 100644 (file)
@@ -25,7 +25,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV \
index 8a01934deda30c3f8e7bfeaf086c4808648d51b7..b322f56f0d0480aade00539c8795aec18ddfb23f 100644 (file)
@@ -82,7 +82,7 @@ RUN curl -Lo /rustroot/dumb-init \
 ENTRYPOINT ["/rustroot/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV HOSTS=i686-unknown-linux-gnu
index e3df1cc7192d814b0a457f3f0204ae7f30ae4b4d..33cca061103a333406ddf9d648c1db9cf5ed36b2 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index e4b3bc378c89aecdf807c59c6c37b96381e60be7..157de83abb783bc5e9cf608a3c7b75f4050dc754 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 06f42397a3ea543c70aa895f794c52b004c4c746..739d5ff6ac4aaddcce445c4f3ba8c414bdf81d2e 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 17f9913b5aec2d560c8224ec808092cfca382f1f..9339063bc19ebb91c4a84f1d3c30a88141170bc0 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index c1e5e863ae06c3b710900cdc6f03d81dbb9d4596..92342caed2a9540da682ce3dab052b27e2e3c26d 100644 (file)
@@ -63,7 +63,7 @@ RUN ./build-powerpc-toolchain.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/powerpc-unknown-linux-gnu/bin
index 7c143b414d464df6e7683b6bf8453526f49d17cd..182dfd93cc76fea34780f15c11cc62050de6977b 100644 (file)
@@ -63,7 +63,7 @@ RUN ./build-powerpc64-toolchain.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/powerpc64-unknown-linux-gnu/bin
index 19b0d625d361686701502d4227bd22a2180b2f16..6b9f964d5a38379f12e58d09e80c7bd0156bcda3 100644 (file)
@@ -63,7 +63,7 @@ COPY shared.sh build-powerpc64le-toolchain.sh /tmp/
 RUN ./build-powerpc64le-toolchain.sh
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV \
index 0d218771cf1c6d81beae94bfa9dac0fad31f23ec..7c94f713e18759a7b55fb83e7c6440f13495dd49 100644 (file)
@@ -63,7 +63,7 @@ RUN ./build-s390x-toolchain.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/s390x-ibm-linux-gnu/bin
index 14444d69d2a8cefd2a700f06462b427c33cf385e..a2939c8c48591065be4515e3840d0d2e3a90aa1c 100644 (file)
@@ -25,7 +25,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV \
index bd36c75f9f06ac70e5787785beae7ad122f93f84..cbe5f5936a506a404004fb5eeef0c29c342fb03a 100644 (file)
@@ -82,7 +82,7 @@ RUN curl -Lo /rustroot/dumb-init \
 ENTRYPOINT ["/rustroot/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV HOSTS=x86_64-unknown-linux-gnu
index 085aa351659905c2af0da4113bd96c7d4a19207f..a41c0cca3b5f0e5b086b2da1243faadce941bd9b 100644 (file)
@@ -26,7 +26,7 @@ RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-ini
 ENTRYPOINT ["/usr/bin/dumb-init", "--"]
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV RUST_CONFIGURE_ARGS \
index 86bb259c8549a6b46bd8941f670aa3da384259e1..776da0093974c0c68c9b59ca84f9fd55eec26059 100644 (file)
@@ -15,7 +15,7 @@ set -ex
 export CFLAGS="-fPIC -Wa,-mrelax-relocations=no"
 export CXXFLAGS="-Wa,-mrelax-relocations=no"
 
-MUSL=musl-1.1.14
+MUSL=musl-1.1.16
 curl https://www.musl-libc.org/releases/$MUSL.tar.gz | tar xzf -
 cd $MUSL
 ./configure --prefix=/musl-x86_64 --disable-shared
index 053300b9c1688a4cc1eefb3c887681e43c6188e1..a1dd9a3724a882004e62f8038a8c993aeb3f7f50 100644 (file)
@@ -62,7 +62,7 @@ RUN ./build-netbsd-toolchain.sh
 USER root
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 ENV PATH=$PATH:/x-tools/x86_64-unknown-netbsd/bin
index 77cf54a19a7fd9ee510066f3a9ed19a9aa0f4b16..ffdb1d18a94ef8dd122222dc335bde25bc789a5e 100644 (file)
@@ -15,7 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   lib32stdc++6
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index c84cf56e4e858bdaf788b30371b8fc00a672099b..34d0567a440f9debc694a256a4b54aeaf7149b9f 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index f4bb9083b85827ece5f152af18aaa1a4009761f7..960a0fa7a385f9aec3dd05e9111065fe5e54323d 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 68184c65cf17ffcf75ac8728c2d4de0a5889f279..9871df90e00d509e55f22ad9a8c4050e5bb56cb2 100644 (file)
@@ -15,7 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 6320a806fc301d3b7d9b7afd29d409ec46fcfc6e..197b0ec9b9bb64bbe041682cdfb7771997c50004 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 180f53ec33f31f173ebd1dcd230ebf44272cda40..60af302791a74406e67923bbc71c7bb1c25aa943 100644 (file)
@@ -16,7 +16,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   pkg-config
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 4500fc0f642deec293c20ca4c7e68e6514a1a9ca..4ec0b5c152575951bd6022d423670db169330af9 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index ad1227fa581f9ca745e74752d23333ab8b3b65eb..6448f88950f0df30e7bee4b02f6b348b695294c7 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index f1240201805718819fed02848b084ba7debbb263..c00667fe1dd00020f22007714fd98d71c9872684 100644 (file)
@@ -17,7 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index fa9707d1a7352c9f54d1b7bcd91acf4ba79639a0..7284d231b844bd67c8b3bc3abbdac29cb8a49231 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index e5d89034dbe4268b6e46dcdf6dae3d914bbd591e..1dce84bc5fd73e61eda10ef6f4440151e1fba357 100644 (file)
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   xz-utils
 
 RUN curl -o /usr/local/bin/sccache \
-      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-03-24-sccache-x86_64-unknown-linux-musl && \
+      https://s3.amazonaws.com/rust-lang-ci/rust-ci-mirror/2017-04-04-sccache-x86_64-unknown-linux-musl && \
       chmod +x /usr/local/bin/sccache
 
 RUN curl -OL https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64.deb && \
index 292f5a1ec816af92e6569d03e0084ee4b0c957b5..9ce097e78a4e530a6afd1979b2b4eb30ba43e09c 100644 (file)
 - [no_debug](no-debug.md)
 - [non_ascii_idents](non-ascii-idents.md)
 - [nonzero](nonzero.md)
+- [offset_to](offset-to.md)
 - [omit_gdb_pretty_printer_section](omit-gdb-pretty-printer-section.md)
 - [on_unimplemented](on-unimplemented.md)
 - [once_poison](once-poison.md)
 - [slice_concat_ext](slice-concat-ext.md)
 - [slice_get_slice](slice-get-slice.md)
 - [slice_patterns](slice-patterns.md)
+- [slice_rsplit](slice-rsplit.md)
 - [sort_internals](sort-internals.md)
 - [sort_unstable](sort-unstable.md)
 - [specialization](specialization.md)
 - [windows_handle](windows-handle.md)
 - [windows_net](windows-net.md)
 - [windows_stdio](windows-stdio.md)
-- [windows_subsystem](windows-subsystem.md)
 - [zero_one](zero-one.md)
diff --git a/src/doc/unstable-book/src/offset-to.md b/src/doc/unstable-book/src/offset-to.md
new file mode 100644 (file)
index 0000000..03d990e
--- /dev/null
@@ -0,0 +1,7 @@
+# `offset_to`
+
+The tracking issue for this feature is: [#41079]
+
+[#41079]: https://github.com/rust-lang/rust/issues/41079
+
+------------------------
diff --git a/src/doc/unstable-book/src/slice-rsplit.md b/src/doc/unstable-book/src/slice-rsplit.md
new file mode 100644 (file)
index 0000000..8c2954f
--- /dev/null
@@ -0,0 +1,10 @@
+# `slice_rsplit`
+
+The tracking issue for this feature is: [#41020]
+
+[#41020]: https://github.com/rust-lang/rust/issues/41020
+
+------------------------
+
+The `slice_rsplit` feature enables two methods on slices:
+`slice.rsplit(predicate)` and `slice.rsplit_mut(predicate)`.
diff --git a/src/doc/unstable-book/src/windows-subsystem.md b/src/doc/unstable-book/src/windows-subsystem.md
deleted file mode 100644 (file)
index 8058335..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# `windows_subsystem`
-
-The tracking issue for this feature is: [#37499]
-
-[#37499]: https://github.com/rust-lang/rust/issues/37499
-
-------------------------
-
-
-
index 9d15f98e06709eaadf5d61d4ef235bc1e65f1b0c..75ab3f1a17be43f4e3669d6eb347ce6e7c56e4cb 100644 (file)
@@ -76,6 +76,66 @@ def get_codepoints(f):
     for c in range(prev_codepoint + 1, NUM_CODEPOINTS):
         yield Codepoint(c, None)
 
+def compress_singletons(singletons):
+    uppers = [] # (upper, # items in lowers)
+    lowers = []
+
+    for i in singletons:
+        upper = i >> 8
+        lower = i & 0xff
+        if len(uppers) == 0 or uppers[-1][0] != upper:
+            uppers.append((upper, 1))
+        else:
+            upper, count = uppers[-1]
+            uppers[-1] = upper, count + 1
+        lowers.append(lower)
+
+    return uppers, lowers
+
+def compress_normal(normal):
+    # lengths 0x00..0x7f are encoded as 00, 01, ..., 7e, 7f
+    # lengths 0x80..0x7fff are encoded as 80 80, 80 81, ..., ff fe, ff ff
+    compressed = [] # [truelen, (truelenaux), falselen, (falselenaux)]
+
+    prev_start = 0
+    for start, count in normal:
+        truelen = start - prev_start
+        falselen = count
+        prev_start = start + count
+
+        assert truelen < 0x8000 and falselen < 0x8000
+        entry = []
+        if truelen > 0x7f:
+            entry.append(0x80 | (truelen >> 8))
+            entry.append(truelen & 0xff)
+        else:
+            entry.append(truelen & 0x7f)
+        if falselen > 0x7f:
+            entry.append(0x80 | (falselen >> 8))
+            entry.append(falselen & 0xff)
+        else:
+            entry.append(falselen & 0x7f)
+
+        compressed.append(entry)
+
+    return compressed
+
+def print_singletons(uppers, lowers, uppersname, lowersname):
+    print("const {}: &'static [(u8, u8)] = &[".format(uppersname))
+    for u, c in uppers:
+        print("    ({:#04x}, {}),".format(u, c))
+    print("];")
+    print("const {}: &'static [u8] = &[".format(lowersname))
+    for i in range(0, len(lowers), 8):
+        print("    {}".format(" ".join("{:#04x},".format(l) for l in lowers[i:i+8])))
+    print("];")
+
+def print_normal(normal, normalname):
+    print("const {}: &'static [u8] = &[".format(normalname))
+    for v in normal:
+        print("    {}".format(" ".join("{:#04x},".format(i) for i in v)))
+    print("];")
+
 def main():
     file = get_file("http://www.unicode.org/Public/UNIDATA/UnicodeData.txt")
 
@@ -111,6 +171,11 @@ def main():
             else:
                 normal0.append((a, b - a))
 
+    singletons0u, singletons0l = compress_singletons(singletons0)
+    singletons1u, singletons1l = compress_singletons(singletons1)
+    normal0 = compress_normal(normal0)
+    normal1 = compress_normal(normal1)
+
     print("""\
 // Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
@@ -125,38 +190,49 @@ def main():
 // NOTE: The following code was generated by "src/etc/char_private.py",
 //       do not edit directly!
 
-use slice::SliceExt;
-
-fn check(x: u16, singletons: &[u16], normal: &[u16]) -> bool {
-    for &s in singletons {
-        if x == s {
-            return false;
-        } else if x < s {
+fn check(x: u16, singletonuppers: &[(u8, u8)], singletonlowers: &[u8],
+         normal: &[u8]) -> bool {
+    let xupper = (x >> 8) as u8;
+    let mut lowerstart = 0;
+    for &(upper, lowercount) in singletonuppers {
+        let lowerend = lowerstart + lowercount as usize;
+        if xupper == upper {
+            for &lower in &singletonlowers[lowerstart..lowerend] {
+                if lower == x as u8 {
+                    return false;
+                }
+            }
+        } else if xupper < upper {
             break;
         }
+        lowerstart = lowerend;
     }
-    for w in normal.chunks(2) {
-        let start = w[0];
-        let len = w[1];
-        let difference = (x as i32) - (start as i32);
-        if 0 <= difference {
-            if difference < len as i32 {
-                return false;
-            }
+
+    let mut x = x as i32;
+    let mut normal = normal.iter().cloned();
+    let mut current = true;
+    while let Some(v) = normal.next() {
+        let len = if v & 0x80 != 0 {
+            ((v & 0x7f) as i32) << 8 | normal.next().unwrap() as i32
         } else {
+            v as i32
+        };
+        x -= len;
+        if x < 0 {
             break;
         }
+        current = !current;
     }
-    true
+    current
 }
 
 pub fn is_printable(x: char) -> bool {
     let x = x as u32;
     let lower = x as u16;
     if x < 0x10000 {
-        check(lower, SINGLETONS0, NORMAL0)
+        check(lower, SINGLETONS0U, SINGLETONS0L, NORMAL0)
     } else if x < 0x20000 {
-        check(lower, SINGLETONS1, NORMAL1)
+        check(lower, SINGLETONS1U, SINGLETONS1L, NORMAL1)
     } else {\
 """)
     for a, b in extra:
@@ -169,22 +245,10 @@ pub fn is_printable(x: char) -> bool {
 }\
 """)
     print()
-    print("const SINGLETONS0: &'static [u16] = &[")
-    for s in singletons0:
-        print("    0x{:x},".format(s))
-    print("];")
-    print("const SINGLETONS1: &'static [u16] = &[")
-    for s in singletons1:
-        print("    0x{:x},".format(s))
-    print("];")
-    print("const NORMAL0: &'static [u16] = &[")
-    for a, b in normal0:
-        print("    0x{:x}, 0x{:x},".format(a, b))
-    print("];")
-    print("const NORMAL1: &'static [u16] = &[")
-    for a, b in normal1:
-        print("    0x{:x}, 0x{:x},".format(a, b))
-    print("];")
+    print_singletons(singletons0u, singletons0l, 'SINGLETONS0U', 'SINGLETONS0L')
+    print_singletons(singletons1u, singletons1l, 'SINGLETONS1U', 'SINGLETONS1L')
+    print_normal(normal0, 'NORMAL0')
+    print_normal(normal1, 'NORMAL1')
 
 if __name__ == '__main__':
     main()
index eda5f85408574afcdff4771940a9c53fe81db52a..394ff97d84533872d535b598db50de8b8158de34 100644 (file)
@@ -51,7 +51,7 @@ def make_win_dist(rust_root, plat_root, target_triple):
 
     target_tools = ["gcc.exe", "ld.exe", "ar.exe", "dlltool.exe"]
 
-    rustc_dlls = ["libstdc++-6.dll"]
+    rustc_dlls = ["libstdc++-6.dll", "libwinpthread-1.dll"]
     if target_triple.startswith("i686-"):
         rustc_dlls.append("libgcc_s_dw2-1.dll")
     else:
@@ -67,6 +67,7 @@ def make_win_dist(rust_root, plat_root, target_triple):
                     "libstdc++.a",
                     "libiconv.a",
                     "libmoldname.a",
+                    "libpthread.a",
                     # Windows import libs
                     "libadvapi32.a",
                     "libbcrypt.a",
index 02b2171a224d0ae2b0111a5445f83b54fc88c9c3..7e92404bc0d6f3dce905231c980c41af9d7ec228 100644 (file)
@@ -13,8 +13,8 @@ core = { path = "../libcore" }
 std_unicode = { path = "../libstd_unicode" }
 
 [[test]]
-name = "collectionstest"
-path = "../libcollectionstest/lib.rs"
+name = "collectionstests"
+path = "../libcollections/tests/lib.rs"
 
 [[bench]]
 name = "collectionsbenches"
index 00448b6abb2cf3937ab36f2c8416bea36f1e31ca..248c15e96f8f65f3b432fbe7db9dc7645823c1d5 100644 (file)
@@ -52,6 +52,7 @@
 #![feature(shared)]
 #![feature(slice_get_slice)]
 #![feature(slice_patterns)]
+#![feature(slice_rsplit)]
 #![cfg_attr(not(test), feature(sort_unstable))]
 #![feature(specialization)]
 #![feature(staged_api)]
@@ -62,6 +63,7 @@
 #![feature(untagged_unions)]
 #![cfg_attr(not(test), feature(str_checked_slicing))]
 #![cfg_attr(test, feature(rand, test))]
+#![feature(offset_to)]
 
 #![no_std]
 
index 8f0488f69369e5d905c18c906e1cfa5c459e34f0..1b3eeb837d909aba3257b66c3680bbc7b59faaef 100644 (file)
@@ -697,8 +697,8 @@ pub fn split_off(&mut self, at: usize) -> LinkedList<T> {
 
     /// Returns a place for insertion at the front of the list.
     ///
-    /// Using this method with placement syntax is equivalent to [`push_front`]
-    /// (#method.push_front), but may be more efficient.
+    /// Using this method with placement syntax is equivalent to
+    /// [`push_front`](#method.push_front), but may be more efficient.
     ///
     /// # Examples
     ///
index 6f8843c2374bc1b1cb9c0bdf52bded19948b3529..6cff315a6ccd9eb28083d2b1f5b2afa9e8dc2430 100644 (file)
 pub use core::slice::{SplitMut, ChunksMut, Split};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+pub use core::slice::{RSplit, RSplitMut};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::slice::{from_raw_parts, from_raw_parts_mut};
 #[unstable(feature = "slice_get_slice", issue = "35729")]
@@ -779,6 +781,72 @@ pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<T, F>
         core_slice::SliceExt::split_mut(self, pred)
     }
 
+    /// Returns an iterator over subslices separated by elements that match
+    /// `pred`, starting at the end of the slice and working backwards.
+    /// The matched element is not contained in the subslices.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(slice_rsplit)]
+    ///
+    /// let slice = [11, 22, 33, 0, 44, 55];
+    /// let mut iter = slice.rsplit(|num| *num == 0);
+    ///
+    /// assert_eq!(iter.next().unwrap(), &[44, 55]);
+    /// assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+    /// assert_eq!(iter.next(), None);
+    /// ```
+    ///
+    /// As with `split()`, if the first or last element is matched, an empty
+    /// slice will be the first (or last) item returned by the iterator.
+    ///
+    /// ```
+    /// #![feature(slice_rsplit)]
+    ///
+    /// let v = &[0, 1, 1, 2, 3, 5, 8];
+    /// let mut it = v.rsplit(|n| *n % 2 == 0);
+    /// assert_eq!(it.next().unwrap(), &[]);
+    /// assert_eq!(it.next().unwrap(), &[3, 5]);
+    /// assert_eq!(it.next().unwrap(), &[1, 1]);
+    /// assert_eq!(it.next().unwrap(), &[]);
+    /// assert_eq!(it.next(), None);
+    /// ```
+    #[unstable(feature = "slice_rsplit", issue = "41020")]
+    #[inline]
+    pub fn rsplit<F>(&self, pred: F) -> RSplit<T, F>
+        where F: FnMut(&T) -> bool
+    {
+        core_slice::SliceExt::rsplit(self, pred)
+    }
+
+    /// Returns an iterator over mutable subslices separated by elements that
+    /// match `pred`, starting at the end of the slice and working
+    /// backwards. The matched element is not contained in the subslices.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(slice_rsplit)]
+    ///
+    /// let mut v = [100, 400, 300, 200, 600, 500];
+    ///
+    /// let mut count = 0;
+    /// for group in v.rsplit_mut(|num| *num % 3 == 0) {
+    ///     count += 1;
+    ///     group[0] = count;
+    /// }
+    /// assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+    /// ```
+    ///
+    #[unstable(feature = "slice_rsplit", issue = "41020")]
+    #[inline]
+    pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<T, F>
+        where F: FnMut(&T) -> bool
+    {
+        core_slice::SliceExt::rsplit_mut(self, pred)
+    }
+
     /// Returns an iterator over subslices separated by elements that match
     /// `pred`, limited to returning at most `n` items. The matched element is
     /// not contained in the subslices.
diff --git a/src/libcollections/tests/binary_heap.rs b/src/libcollections/tests/binary_heap.rs
new file mode 100644 (file)
index 0000000..d284937
--- /dev/null
@@ -0,0 +1,339 @@
+// 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::panic;
+use std::collections::BinaryHeap;
+use std::collections::binary_heap::{Drain, PeekMut};
+
+#[test]
+fn test_iterator() {
+    let data = vec![5, 9, 3];
+    let iterout = [9, 5, 3];
+    let heap = BinaryHeap::from(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(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(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(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(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(data);
+    while !heap.is_empty() {
+        assert_eq!(heap.peek().unwrap(), sorted.last().unwrap());
+        assert_eq!(heap.pop().unwrap(), sorted.pop().unwrap());
+    }
+}
+
+#[test]
+fn test_peek_mut() {
+    let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
+    let mut heap = BinaryHeap::from(data);
+    assert_eq!(heap.peek(), Some(&10));
+    {
+        let mut top = heap.peek_mut().unwrap();
+        *top -= 2;
+    }
+    assert_eq!(heap.peek(), Some(&9));
+}
+
+#[test]
+fn test_peek_mut_pop() {
+    let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
+    let mut heap = BinaryHeap::from(data);
+    assert_eq!(heap.peek(), Some(&10));
+    {
+        let mut top = heap.peek_mut().unwrap();
+        *top -= 2;
+        assert_eq!(PeekMut::pop(top), 8);
+    }
+    assert_eq!(heap.peek(), Some(&9));
+}
+
+#[test]
+fn test_push() {
+    let mut heap = BinaryHeap::from(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![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]
+#[allow(deprecated)]
+fn test_push_pop() {
+    let mut heap = BinaryHeap::from(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]
+#[allow(deprecated)]
+fn test_replace() {
+    let mut heap = BinaryHeap::from(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(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_peek_mut() {
+    let mut empty = BinaryHeap::<i32>::new();
+    assert!(empty.peek_mut().is_none());
+}
+
+#[test]
+#[allow(deprecated)]
+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());
+}
+
+#[test]
+fn test_extend_ref() {
+    let mut a = BinaryHeap::new();
+    a.push(1);
+    a.push(2);
+
+    a.extend(&[3, 4, 5]);
+
+    assert_eq!(a.len(), 5);
+    assert_eq!(a.into_sorted_vec(), [1, 2, 3, 4, 5]);
+
+    let mut a = BinaryHeap::new();
+    a.push(1);
+    a.push(2);
+    let mut b = BinaryHeap::new();
+    b.push(3);
+    b.push(4);
+    b.push(5);
+
+    a.extend(&b);
+
+    assert_eq!(a.len(), 5);
+    assert_eq!(a.into_sorted_vec(), [1, 2, 3, 4, 5]);
+}
+
+#[test]
+fn test_append() {
+    let mut a = BinaryHeap::from(vec![-10, 1, 2, 3, 3]);
+    let mut b = BinaryHeap::from(vec![-20, 5, 43]);
+
+    a.append(&mut b);
+
+    assert_eq!(a.into_sorted_vec(), [-20, -10, 1, 2, 3, 3, 5, 43]);
+    assert!(b.is_empty());
+}
+
+#[test]
+fn test_append_to_empty() {
+    let mut a = BinaryHeap::new();
+    let mut b = BinaryHeap::from(vec![-20, 5, 43]);
+
+    a.append(&mut b);
+
+    assert_eq!(a.into_sorted_vec(), [-20, 5, 43]);
+    assert!(b.is_empty());
+}
+
+#[test]
+fn test_extend_specialization() {
+    let mut a = BinaryHeap::from(vec![-10, 1, 2, 3, 3]);
+    let b = BinaryHeap::from(vec![-20, 5, 43]);
+
+    a.extend(b);
+
+    assert_eq!(a.into_sorted_vec(), [-20, -10, 1, 2, 3, 3, 5, 43]);
+}
+
+#[test]
+fn test_placement() {
+    let mut a = BinaryHeap::new();
+    &mut a <- 2;
+    &mut a <- 4;
+    &mut a <- 3;
+    assert_eq!(a.peek(), Some(&4));
+    assert_eq!(a.len(), 3);
+    &mut a <- 1;
+    assert_eq!(a.into_sorted_vec(), vec![1, 2, 3, 4]);
+}
+
+#[test]
+fn test_placement_panic() {
+    let mut heap = BinaryHeap::from(vec![1, 2, 3]);
+    fn mkpanic() -> usize { panic!() }
+    let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { &mut heap <- mkpanic(); }));
+    assert_eq!(heap.len(), 3);
+}
+
+#[allow(dead_code)]
+fn assert_covariance() {
+    fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
+        d
+    }
+}
diff --git a/src/libcollections/tests/btree/map.rs b/src/libcollections/tests/btree/map.rs
new file mode 100644 (file)
index 0000000..2c899d9
--- /dev/null
@@ -0,0 +1,687 @@
+// 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::{self, Excluded, Included, Unbounded};
+use std::collections::btree_map::Entry::{Occupied, Vacant};
+use std::rc::Rc;
+
+use std::iter::FromIterator;
+use super::DeterministicRng;
+
+#[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_values_mut() {
+    let mut a = BTreeMap::new();
+    a.insert(1, String::from("hello"));
+    a.insert(2, String::from("goodbye"));
+
+    for value in a.values_mut() {
+        value.push_str("!");
+    }
+
+    let values: Vec<String> = a.values().cloned().collect();
+    assert_eq!(values, [String::from("hello!"), String::from("goodbye!")]);
+}
+
+#[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(2..).zip(2..size) {
+        assert_eq!(k, i);
+        assert_eq!(v, i);
+        j += 1;
+    }
+    assert_eq!(j, size - 2);
+}
+
+#[test]
+fn test_range_inclusive() {
+    let size = 500;
+
+    let map: BTreeMap<_, _> = (0...size).map(|i| (i, i)).collect();
+
+    fn check<'a, L, R>(lhs: L, rhs: R)
+        where L: IntoIterator<Item=(&'a i32, &'a i32)>,
+              R: IntoIterator<Item=(&'a i32, &'a i32)>,
+    {
+        let lhs: Vec<_> = lhs.into_iter().collect();
+        let rhs: Vec<_> = rhs.into_iter().collect();
+        assert_eq!(lhs, rhs);
+    }
+
+    check(map.range(size + 1...size + 1), vec![]);
+    check(map.range(size...size), vec![(&size, &size)]);
+    check(map.range(size...size + 1), vec![(&size, &size)]);
+    check(map.range(0...0), vec![(&0, &0)]);
+    check(map.range(0...size - 1), map.range(..size));
+    check(map.range(-1...-1), vec![]);
+    check(map.range(-1...size), map.range(..));
+    check(map.range(...size), map.range(..));
+    check(map.range(...200), map.range(..201));
+    check(map.range(5...8), vec![(&5, &5), (&6, &6), (&7, &7), (&8, &8)]);
+    check(map.range(-1...0), vec![(&0, &0)]);
+    check(map.range(-1...2), vec![(&0, &0), (&1, &1), (&2, &2)]);
+}
+
+#[test]
+fn test_range_inclusive_max_value() {
+    let max = ::std::usize::MAX;
+    let map: BTreeMap<_, _> = vec![(max, 0)].into_iter().collect();
+
+    assert_eq!(map.range(max...max).collect::<Vec<_>>(), &[(&max, &0)]);
+}
+
+#[test]
+fn test_range_equal_empty_cases() {
+    let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
+    assert_eq!(map.range((Included(2), Excluded(2))).next(), None);
+    assert_eq!(map.range((Excluded(2), Included(2))).next(), None);
+}
+
+#[test]
+#[should_panic]
+fn test_range_equal_excluded() {
+    let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
+    map.range((Excluded(2), Excluded(2)));
+}
+
+#[test]
+#[should_panic]
+fn test_range_backwards_1() {
+    let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
+    map.range((Included(3), Included(2)));
+}
+
+#[test]
+#[should_panic]
+fn test_range_backwards_2() {
+    let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
+    map.range((Included(3), Excluded(2)));
+}
+
+#[test]
+#[should_panic]
+fn test_range_backwards_3() {
+    let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
+    map.range((Excluded(3), Included(2)));
+}
+
+#[test]
+#[should_panic]
+fn test_range_backwards_4() {
+    let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
+    map.range((Excluded(3), Excluded(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_borrowed_key() {
+    let mut map = BTreeMap::new();
+    map.insert("aardvark".to_string(), 1);
+    map.insert("baboon".to_string(), 2);
+    map.insert("coyote".to_string(), 3);
+    map.insert("dingo".to_string(), 4);
+    // NOTE: would like to use simply "b".."d" here...
+    let mut iter = map.range::<str, _>((Included("b"),Excluded("d")));
+    assert_eq!(iter.next(), Some((&"baboon".to_string(), &2)));
+    assert_eq!(iter.next(), Some((&"coyote".to_string(), &3)));
+    assert_eq!(iter.next(), None);
+}
+
+#[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 = (i..j + 1).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_range_mut() {
+    let size = 200;
+    let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
+
+    for i in 0..size {
+        for j in i..size {
+            let mut kvs = map.range_mut((Included(&i), Included(&j))).map(|(&k, &mut v)| (k, v));
+            let mut pairs = (i..j + 1).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_borrow() {
+    // make sure these compile -- using the Borrow trait
+    {
+        let mut map = BTreeMap::new();
+        map.insert("0".to_string(), 1);
+        assert_eq!(map["0"], 1);
+    }
+
+    {
+        let mut map = BTreeMap::new();
+        map.insert(Box::new(0), 1);
+        assert_eq!(map[&0], 1);
+    }
+
+    {
+        let mut map = BTreeMap::new();
+        map.insert(Box::new([0, 1]) as Box<[i32]>, 1);
+        assert_eq!(map[&[0, 1][..]], 1);
+    }
+
+    {
+        let mut map = BTreeMap::new();
+        map.insert(Rc::new(0), 1);
+        assert_eq!(map[&0], 1);
+    }
+}
+
+#[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);
+}
+
+#[test]
+fn test_extend_ref() {
+    let mut a = BTreeMap::new();
+    a.insert(1, "one");
+    let mut b = BTreeMap::new();
+    b.insert(2, "two");
+    b.insert(3, "three");
+
+    a.extend(&b);
+
+    assert_eq!(a.len(), 3);
+    assert_eq!(a[&1], "one");
+    assert_eq!(a[&2], "two");
+    assert_eq!(a[&3], "three");
+}
+
+#[test]
+fn test_zst() {
+    let mut m = BTreeMap::new();
+    assert_eq!(m.len(), 0);
+
+    assert_eq!(m.insert((), ()), None);
+    assert_eq!(m.len(), 1);
+
+    assert_eq!(m.insert((), ()), Some(()));
+    assert_eq!(m.len(), 1);
+    assert_eq!(m.iter().count(), 1);
+
+    m.clear();
+    assert_eq!(m.len(), 0);
+
+    for _ in 0..100 {
+        m.insert((), ());
+    }
+
+    assert_eq!(m.len(), 1);
+    assert_eq!(m.iter().count(), 1);
+}
+
+// This test's only purpose is to ensure that zero-sized keys with nonsensical orderings
+// do not cause segfaults when used with zero-sized values. All other map behavior is
+// undefined.
+#[test]
+fn test_bad_zst() {
+    use std::cmp::Ordering;
+
+    struct Bad;
+
+    impl PartialEq for Bad {
+        fn eq(&self, _: &Self) -> bool {
+            false
+        }
+    }
+
+    impl Eq for Bad {}
+
+    impl PartialOrd for Bad {
+        fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
+            Some(Ordering::Less)
+        }
+    }
+
+    impl Ord for Bad {
+        fn cmp(&self, _: &Self) -> Ordering {
+            Ordering::Less
+        }
+    }
+
+    let mut m = BTreeMap::new();
+
+    for _ in 0..100 {
+        m.insert(Bad, Bad);
+    }
+}
+
+#[test]
+fn test_clone() {
+    let mut map = BTreeMap::new();
+    let size = 100;
+    assert_eq!(map.len(), 0);
+
+    for i in 0..size {
+        assert_eq!(map.insert(i, 10 * i), None);
+        assert_eq!(map.len(), i + 1);
+        assert_eq!(map, map.clone());
+    }
+
+    for i in 0..size {
+        assert_eq!(map.insert(i, 100 * i), Some(10 * i));
+        assert_eq!(map.len(), size);
+        assert_eq!(map, map.clone());
+    }
+
+    for i in 0..size / 2 {
+        assert_eq!(map.remove(&(i * 2)), Some(i * 200));
+        assert_eq!(map.len(), size - i - 1);
+        assert_eq!(map, map.clone());
+    }
+
+    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);
+        assert_eq!(map, map.clone());
+    }
+}
+
+#[test]
+#[allow(dead_code)]
+fn test_variance() {
+    use std::collections::btree_map::{Iter, IntoIter, Range, Keys, Values};
+
+    fn map_key<'new>(v: BTreeMap<&'static str, ()>) -> BTreeMap<&'new str, ()> {
+        v
+    }
+    fn map_val<'new>(v: BTreeMap<(), &'static str>) -> BTreeMap<(), &'new str> {
+        v
+    }
+    fn iter_key<'a, 'new>(v: Iter<'a, &'static str, ()>) -> Iter<'a, &'new str, ()> {
+        v
+    }
+    fn iter_val<'a, 'new>(v: Iter<'a, (), &'static str>) -> Iter<'a, (), &'new str> {
+        v
+    }
+    fn into_iter_key<'new>(v: IntoIter<&'static str, ()>) -> IntoIter<&'new str, ()> {
+        v
+    }
+    fn into_iter_val<'new>(v: IntoIter<(), &'static str>) -> IntoIter<(), &'new str> {
+        v
+    }
+    fn range_key<'a, 'new>(v: Range<'a, &'static str, ()>) -> Range<'a, &'new str, ()> {
+        v
+    }
+    fn range_val<'a, 'new>(v: Range<'a, (), &'static str>) -> Range<'a, (), &'new str> {
+        v
+    }
+    fn keys<'a, 'new>(v: Keys<'a, &'static str, ()>) -> Keys<'a, &'new str, ()> {
+        v
+    }
+    fn vals<'a, 'new>(v: Values<'a, (), &'static str>) -> Values<'a, (), &'new str> {
+        v
+    }
+}
+
+#[test]
+fn test_occupied_entry_key() {
+    let mut a = BTreeMap::new();
+    let key = "hello there";
+    let value = "value goes here";
+    assert!(a.is_empty());
+    a.insert(key.clone(), value.clone());
+    assert_eq!(a.len(), 1);
+    assert_eq!(a[key], value);
+
+    match a.entry(key.clone()) {
+        Vacant(_) => panic!(),
+        Occupied(e) => assert_eq!(key, *e.key()),
+    }
+    assert_eq!(a.len(), 1);
+    assert_eq!(a[key], value);
+}
+
+#[test]
+fn test_vacant_entry_key() {
+    let mut a = BTreeMap::new();
+    let key = "hello there";
+    let value = "value goes here";
+
+    assert!(a.is_empty());
+    match a.entry(key.clone()) {
+        Occupied(_) => panic!(),
+        Vacant(e) => {
+            assert_eq!(key, *e.key());
+            e.insert(value.clone());
+        }
+    }
+    assert_eq!(a.len(), 1);
+    assert_eq!(a[key], value);
+}
+
+macro_rules! create_append_test {
+    ($name:ident, $len:expr) => {
+        #[test]
+        fn $name() {
+            let mut a = BTreeMap::new();
+            for i in 0..8 {
+                a.insert(i, i);
+            }
+
+            let mut b = BTreeMap::new();
+            for i in 5..$len {
+                b.insert(i, 2*i);
+            }
+
+            a.append(&mut b);
+
+            assert_eq!(a.len(), $len);
+            assert_eq!(b.len(), 0);
+
+            for i in 0..$len {
+                if i < 5 {
+                    assert_eq!(a[&i], i);
+                } else {
+                    assert_eq!(a[&i], 2*i);
+                }
+            }
+
+            assert_eq!(a.remove(&($len-1)), Some(2*($len-1)));
+            assert_eq!(a.insert($len-1, 20), None);
+        }
+    };
+}
+
+// These are mostly for testing the algorithm that "fixes" the right edge after insertion.
+// Single node.
+create_append_test!(test_append_9, 9);
+// Two leafs that don't need fixing.
+create_append_test!(test_append_17, 17);
+// Two leafs where the second one ends up underfull and needs stealing at the end.
+create_append_test!(test_append_14, 14);
+// Two leafs where the second one ends up empty because the insertion finished at the root.
+create_append_test!(test_append_12, 12);
+// Three levels; insertion finished at the root.
+create_append_test!(test_append_144, 144);
+// Three levels; insertion finished at leaf while there is an empty node on the second level.
+create_append_test!(test_append_145, 145);
+// Tests for several randomly chosen sizes.
+create_append_test!(test_append_170, 170);
+create_append_test!(test_append_181, 181);
+create_append_test!(test_append_239, 239);
+create_append_test!(test_append_1700, 1700);
+
+fn rand_data(len: usize) -> Vec<(u32, u32)> {
+    let mut rng = DeterministicRng::new();
+    Vec::from_iter((0..len).map(|_| (rng.next(), rng.next())))
+}
+
+#[test]
+fn test_split_off_empty_right() {
+    let mut data = rand_data(173);
+
+    let mut map = BTreeMap::from_iter(data.clone());
+    let right = map.split_off(&(data.iter().max().unwrap().0 + 1));
+
+    data.sort();
+    assert!(map.into_iter().eq(data));
+    assert!(right.into_iter().eq(None));
+}
+
+#[test]
+fn test_split_off_empty_left() {
+    let mut data = rand_data(314);
+
+    let mut map = BTreeMap::from_iter(data.clone());
+    let right = map.split_off(&data.iter().min().unwrap().0);
+
+    data.sort();
+    assert!(map.into_iter().eq(None));
+    assert!(right.into_iter().eq(data));
+}
+
+#[test]
+fn test_split_off_large_random_sorted() {
+    let mut data = rand_data(1529);
+    // special case with maximum height.
+    data.sort();
+
+    let mut map = BTreeMap::from_iter(data.clone());
+    let key = data[data.len() / 2].0;
+    let right = map.split_off(&key);
+
+    assert!(map.into_iter().eq(data.clone().into_iter().filter(|x| x.0 < key)));
+    assert!(right.into_iter().eq(data.into_iter().filter(|x| x.0 >= key)));
+}
diff --git a/src/libcollections/tests/btree/mod.rs b/src/libcollections/tests/btree/mod.rs
new file mode 100644 (file)
index 0000000..ae8b18d
--- /dev/null
@@ -0,0 +1,42 @@
+// 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;
+
+/// XorShiftRng
+struct DeterministicRng {
+    x: u32,
+    y: u32,
+    z: u32,
+    w: u32,
+}
+
+impl DeterministicRng {
+    fn new() -> Self {
+        DeterministicRng {
+            x: 0x193a6754,
+            y: 0xa8a7d469,
+            z: 0x97830e05,
+            w: 0x113ba7bb,
+        }
+    }
+
+    fn next(&mut self) -> u32 {
+        let x = self.x;
+        let t = x ^ (x << 11);
+        self.x = self.y;
+        self.y = self.z;
+        self.z = self.w;
+        let w_ = self.w;
+        self.w = w_ ^ (w_ >> 19) ^ (t ^ (t >> 8));
+        self.w
+    }
+}
diff --git a/src/libcollections/tests/btree/set.rs b/src/libcollections/tests/btree/set.rs
new file mode 100644 (file)
index 0000000..6171b8b
--- /dev/null
@@ -0,0 +1,331 @@
+// 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::iter::FromIterator;
+use super::DeterministicRng;
+
+#[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(&x) == ::hash(&y));
+}
+
+fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F)
+    where F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, &mut FnMut(&i32) -> bool) -> 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,
+      &mut |&x| {
+          assert_eq!(x, expected[i]);
+          i += 1;
+          true
+      });
+    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);
+
+    assert_eq!(z.next().unwrap(), (&5, &("bar")));
+    assert_eq!(z.next().unwrap(), (&11, &("foo")));
+    assert!(z.next().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), "{}");
+}
+
+#[test]
+fn test_extend_ref() {
+    let mut a = BTreeSet::new();
+    a.insert(1);
+
+    a.extend(&[2, 3, 4]);
+
+    assert_eq!(a.len(), 4);
+    assert!(a.contains(&1));
+    assert!(a.contains(&2));
+    assert!(a.contains(&3));
+    assert!(a.contains(&4));
+
+    let mut b = BTreeSet::new();
+    b.insert(5);
+    b.insert(6);
+
+    a.extend(&b);
+
+    assert_eq!(a.len(), 6);
+    assert!(a.contains(&1));
+    assert!(a.contains(&2));
+    assert!(a.contains(&3));
+    assert!(a.contains(&4));
+    assert!(a.contains(&5));
+    assert!(a.contains(&6));
+}
+
+#[test]
+fn test_recovery() {
+    use std::cmp::Ordering;
+
+    #[derive(Debug)]
+    struct Foo(&'static str, i32);
+
+    impl PartialEq for Foo {
+        fn eq(&self, other: &Self) -> bool {
+            self.0 == other.0
+        }
+    }
+
+    impl Eq for Foo {}
+
+    impl PartialOrd for Foo {
+        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+            self.0.partial_cmp(&other.0)
+        }
+    }
+
+    impl Ord for Foo {
+        fn cmp(&self, other: &Self) -> Ordering {
+            self.0.cmp(&other.0)
+        }
+    }
+
+    let mut s = BTreeSet::new();
+    assert_eq!(s.replace(Foo("a", 1)), None);
+    assert_eq!(s.len(), 1);
+    assert_eq!(s.replace(Foo("a", 2)), Some(Foo("a", 1)));
+    assert_eq!(s.len(), 1);
+
+    {
+        let mut it = s.iter();
+        assert_eq!(it.next(), Some(&Foo("a", 2)));
+        assert_eq!(it.next(), None);
+    }
+
+    assert_eq!(s.get(&Foo("a", 1)), Some(&Foo("a", 2)));
+    assert_eq!(s.take(&Foo("a", 1)), Some(Foo("a", 2)));
+    assert_eq!(s.len(), 0);
+
+    assert_eq!(s.get(&Foo("a", 1)), None);
+    assert_eq!(s.take(&Foo("a", 1)), None);
+
+    assert_eq!(s.iter().next(), None);
+}
+
+#[test]
+#[allow(dead_code)]
+fn test_variance() {
+    use std::collections::btree_set::{IntoIter, Iter, Range};
+
+    fn set<'new>(v: BTreeSet<&'static str>) -> BTreeSet<&'new str> {
+        v
+    }
+    fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> {
+        v
+    }
+    fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> {
+        v
+    }
+    fn range<'a, 'new>(v: Range<'a, &'static str>) -> Range<'a, &'new str> {
+        v
+    }
+}
+
+#[test]
+fn test_append() {
+    let mut a = BTreeSet::new();
+    a.insert(1);
+    a.insert(2);
+    a.insert(3);
+
+    let mut b = BTreeSet::new();
+    b.insert(3);
+    b.insert(4);
+    b.insert(5);
+
+    a.append(&mut b);
+
+    assert_eq!(a.len(), 5);
+    assert_eq!(b.len(), 0);
+
+    assert_eq!(a.contains(&1), true);
+    assert_eq!(a.contains(&2), true);
+    assert_eq!(a.contains(&3), true);
+    assert_eq!(a.contains(&4), true);
+    assert_eq!(a.contains(&5), true);
+}
+
+fn rand_data(len: usize) -> Vec<u32> {
+    let mut rng = DeterministicRng::new();
+    Vec::from_iter((0..len).map(|_| rng.next()))
+}
+
+#[test]
+fn test_split_off_empty_right() {
+    let mut data = rand_data(173);
+
+    let mut set = BTreeSet::from_iter(data.clone());
+    let right = set.split_off(&(data.iter().max().unwrap() + 1));
+
+    data.sort();
+    assert!(set.into_iter().eq(data));
+    assert!(right.into_iter().eq(None));
+}
+
+#[test]
+fn test_split_off_empty_left() {
+    let mut data = rand_data(314);
+
+    let mut set = BTreeSet::from_iter(data.clone());
+    let right = set.split_off(data.iter().min().unwrap());
+
+    data.sort();
+    assert!(set.into_iter().eq(None));
+    assert!(right.into_iter().eq(data));
+}
+
+#[test]
+fn test_split_off_large_random_sorted() {
+    let mut data = rand_data(1529);
+    // special case with maximum height.
+    data.sort();
+
+    let mut set = BTreeSet::from_iter(data.clone());
+    let key = data[data.len() / 2];
+    let right = set.split_off(&key);
+
+    assert!(set.into_iter().eq(data.clone().into_iter().filter(|x| *x < key)));
+    assert!(right.into_iter().eq(data.into_iter().filter(|x| *x >= key)));
+}
diff --git a/src/libcollections/tests/cow_str.rs b/src/libcollections/tests/cow_str.rs
new file mode 100644 (file)
index 0000000..b292451
--- /dev/null
@@ -0,0 +1,141 @@
+// Copyright 2016 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::Cow;
+
+// check that Cow<'a, str> implements addition
+#[test]
+fn check_cow_add_cow() {
+    let borrowed1 = Cow::Borrowed("Hello, ");
+    let borrowed2 = Cow::Borrowed("World!");
+    let borrow_empty = Cow::Borrowed("");
+
+    let owned1: Cow<str> = Cow::Owned(String::from("Hi, "));
+    let owned2: Cow<str> = Cow::Owned(String::from("Rustaceans!"));
+    let owned_empty: Cow<str> = Cow::Owned(String::new());
+
+    assert_eq!("Hello, World!", borrowed1.clone() + borrowed2.clone());
+    assert_eq!("Hello, Rustaceans!", borrowed1.clone() + owned2.clone());
+
+    assert_eq!("Hi, World!", owned1.clone() + borrowed2.clone());
+    assert_eq!("Hi, Rustaceans!", owned1.clone() + owned2.clone());
+
+    if let Cow::Owned(_) = borrowed1.clone() + borrow_empty.clone() {
+        panic!("Adding empty strings to a borrow should note allocate");
+    }
+    if let Cow::Owned(_) = borrow_empty.clone() + borrowed1.clone() {
+        panic!("Adding empty strings to a borrow should note allocate");
+    }
+    if let Cow::Owned(_) = borrowed1.clone() + owned_empty.clone() {
+        panic!("Adding empty strings to a borrow should note allocate");
+    }
+    if let Cow::Owned(_) = owned_empty.clone() + borrowed1.clone() {
+        panic!("Adding empty strings to a borrow should note allocate");
+    }
+}
+
+#[test]
+fn check_cow_add_str() {
+    let borrowed = Cow::Borrowed("Hello, ");
+    let borrow_empty = Cow::Borrowed("");
+
+    let owned: Cow<str> = Cow::Owned(String::from("Hi, "));
+    let owned_empty: Cow<str> = Cow::Owned(String::new());
+
+    assert_eq!("Hello, World!", borrowed.clone() + "World!");
+
+    assert_eq!("Hi, World!", owned.clone() + "World!");
+
+    if let Cow::Owned(_) = borrowed.clone() + "" {
+        panic!("Adding empty strings to a borrow should note allocate");
+    }
+    if let Cow::Owned(_) = borrow_empty.clone() + "Hello, " {
+        panic!("Adding empty strings to a borrow should note allocate");
+    }
+    if let Cow::Owned(_) = owned_empty.clone() + "Hello, " {
+        panic!("Adding empty strings to a borrow should note allocate");
+    }
+}
+
+#[test]
+fn check_cow_add_assign_cow() {
+    let mut borrowed1 = Cow::Borrowed("Hello, ");
+    let borrowed2 = Cow::Borrowed("World!");
+    let borrow_empty = Cow::Borrowed("");
+
+    let mut owned1: Cow<str> = Cow::Owned(String::from("Hi, "));
+    let owned2: Cow<str> = Cow::Owned(String::from("Rustaceans!"));
+    let owned_empty: Cow<str> = Cow::Owned(String::new());
+
+    let mut s = borrowed1.clone();
+    s += borrow_empty.clone();
+    assert_eq!("Hello, ", s);
+    if let Cow::Owned(_) = s {
+        panic!("Adding empty strings to a borrow should note allocate");
+    }
+    let mut s = borrow_empty.clone();
+    s += borrowed1.clone();
+    assert_eq!("Hello, ", s);
+    if let Cow::Owned(_) = s {
+        panic!("Adding empty strings to a borrow should note allocate");
+    }
+    let mut s = borrowed1.clone();
+    s += owned_empty.clone();
+    assert_eq!("Hello, ", s);
+    if let Cow::Owned(_) = s {
+        panic!("Adding empty strings to a borrow should note allocate");
+    }
+    let mut s = owned_empty.clone();
+    s += borrowed1.clone();
+    assert_eq!("Hello, ", s);
+    if let Cow::Owned(_) = s {
+        panic!("Adding empty strings to a borrow should note allocate");
+    }
+
+    owned1 += borrowed2;
+    borrowed1 += owned2;
+
+    assert_eq!("Hi, World!", owned1);
+    assert_eq!("Hello, Rustaceans!", borrowed1);
+}
+
+#[test]
+fn check_cow_add_assign_str() {
+    let mut borrowed = Cow::Borrowed("Hello, ");
+    let borrow_empty = Cow::Borrowed("");
+
+    let mut owned: Cow<str> = Cow::Owned(String::from("Hi, "));
+    let owned_empty: Cow<str> = Cow::Owned(String::new());
+
+    let mut s = borrowed.clone();
+    s += "";
+    assert_eq!("Hello, ", s);
+    if let Cow::Owned(_) = s {
+        panic!("Adding empty strings to a borrow should note allocate");
+    }
+    let mut s = borrow_empty.clone();
+    s += "World!";
+    assert_eq!("World!", s);
+    if let Cow::Owned(_) = s {
+        panic!("Adding empty strings to a borrow should note allocate");
+    }
+    let mut s = owned_empty.clone();
+    s += "World!";
+    assert_eq!("World!", s);
+    if let Cow::Owned(_) = s {
+        panic!("Adding empty strings to a borrow should note allocate");
+    }
+
+    owned += "World!";
+    borrowed += "World!";
+
+    assert_eq!("Hi, World!", owned);
+    assert_eq!("Hello, World!", borrowed);
+}
diff --git a/src/libcollections/tests/fmt.rs b/src/libcollections/tests/fmt.rs
new file mode 100644 (file)
index 0000000..70e21c6
--- /dev/null
@@ -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, "Hello, world!");
+}
diff --git a/src/libcollections/tests/lib.rs b/src/libcollections/tests/lib.rs
new file mode 100644 (file)
index 0000000..618eb38
--- /dev/null
@@ -0,0 +1,54 @@
+// 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.
+
+#![deny(warnings)]
+
+#![feature(binary_heap_extras)]
+#![feature(binary_heap_peek_mut_pop)]
+#![feature(box_syntax)]
+#![feature(inclusive_range_syntax)]
+#![feature(collection_placement)]
+#![feature(collections)]
+#![feature(const_fn)]
+#![feature(exact_size_is_empty)]
+#![feature(pattern)]
+#![feature(placement_in_syntax)]
+#![feature(rand)]
+#![feature(step_by)]
+#![feature(str_escape)]
+#![feature(test)]
+#![feature(unboxed_closures)]
+#![feature(unicode)]
+#![feature(utf8_error_error_len)]
+
+extern crate collections;
+extern crate test;
+extern crate std_unicode;
+extern crate core;
+
+use std::hash::{Hash, Hasher};
+use std::collections::hash_map::DefaultHasher;
+
+mod binary_heap;
+mod btree;
+mod cow_str;
+mod fmt;
+mod linked_list;
+mod slice;
+mod str;
+mod string;
+mod vec_deque;
+mod vec;
+
+fn hash<T: Hash>(t: &T) -> u64 {
+    let mut s = DefaultHasher::new();
+    t.hash(&mut s);
+    s.finish()
+}
diff --git a/src/libcollections/tests/linked_list.rs b/src/libcollections/tests/linked_list.rs
new file mode 100644 (file)
index 0000000..a59724a
--- /dev/null
@@ -0,0 +1,368 @@
+// 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;
+
+#[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(&x) == ::hash(&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(&x) == ::hash(&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\"]");
+}
+
+#[test]
+fn test_extend_ref() {
+    let mut a = LinkedList::new();
+    a.push_back(1);
+
+    a.extend(&[2, 3, 4]);
+
+    assert_eq!(a.len(), 4);
+    assert_eq!(a, list_from(&[1, 2, 3, 4]));
+
+    let mut b = LinkedList::new();
+    b.push_back(5);
+    b.push_back(6);
+    a.extend(&b);
+
+    assert_eq!(a.len(), 6);
+    assert_eq!(a, list_from(&[1, 2, 3, 4, 5, 6]));
+}
+
+#[test]
+fn test_extend() {
+    let mut a = LinkedList::new();
+    a.push_back(1);
+    a.extend(vec![2, 3, 4]); // uses iterator
+
+    assert_eq!(a.len(), 4);
+    assert!(a.iter().eq(&[1, 2, 3, 4]));
+
+    let b: LinkedList<_> = vec![5, 6, 7].into_iter().collect();
+    a.extend(b); // specializes to `append`
+
+    assert_eq!(a.len(), 7);
+    assert!(a.iter().eq(&[1, 2, 3, 4, 5, 6, 7]));
+}
+
+#[test]
+fn test_contains() {
+    let mut l = LinkedList::new();
+    l.extend(&[2, 3, 4]);
+
+    assert!(l.contains(&3));
+    assert!(!l.contains(&1));
+
+    l.clear();
+
+    assert!(!l.contains(&3));
+}
diff --git a/src/libcollections/tests/slice.rs b/src/libcollections/tests/slice.rs
new file mode 100644 (file)
index 0000000..c3e5304
--- /dev/null
@@ -0,0 +1,1180 @@
+// 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::mem;
+use std::__rand::{Rng, thread_rng};
+use std::rc::Rc;
+
+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[..];
+        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_split_first() {
+    let mut a = vec![11];
+    let b: &[i32] = &[];
+    assert!(b.split_first().is_none());
+    assert_eq!(a.split_first(), Some((&11, b)));
+    a = vec![11, 12];
+    let b: &[i32] = &[12];
+    assert_eq!(a.split_first(), Some((&11, b)));
+}
+
+#[test]
+fn test_split_first_mut() {
+    let mut a = vec![11];
+    let b: &mut [i32] = &mut [];
+    assert!(b.split_first_mut().is_none());
+    assert!(a.split_first_mut() == Some((&mut 11, b)));
+    a = vec![11, 12];
+    let b: &mut [_] = &mut [12];
+    assert!(a.split_first_mut() == Some((&mut 11, b)));
+}
+
+#[test]
+fn test_split_last() {
+    let mut a = vec![11];
+    let b: &[i32] = &[];
+    assert!(b.split_last().is_none());
+    assert_eq!(a.split_last(), Some((&11, b)));
+    a = vec![11, 12];
+    let b: &[_] = &[11];
+    assert_eq!(a.split_last(), Some((&12, b)));
+}
+
+#[test]
+fn test_split_last_mut() {
+    let mut a = vec![11];
+    let b: &mut [i32] = &mut [];
+    assert!(b.split_last_mut().is_none());
+    assert!(a.split_last_mut() == Some((&mut 11, b)));
+
+    a = vec![11, 12];
+    let b: &mut [_] = &mut [11];
+    assert!(a.split_last_mut() == Some((&mut 12, b)));
+}
+
+#[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 0);
+    v.push(box 0);
+    v.push(box 0);
+    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_retain() {
+    let mut v = vec![1, 2, 3, 4, 5];
+    v.retain(is_odd);
+    assert_eq!(v, [1, 3, 5]);
+}
+
+#[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() {
+    let mut rng = thread_rng();
+
+    for len in (2..25).chain(500..510) {
+        for _ in 0..100 {
+            let mut v: Vec<_> = 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]));
+        }
+    }
+
+    // Sort using a completely random comparison function.
+    // This will reorder the elements *somehow*, but won't panic.
+    let mut v = [0; 500];
+    for i in 0..v.len() {
+        v[i] = i as i32;
+    }
+    v.sort_by(|_, _| *rng.choose(&[Less, Equal, Greater]).unwrap());
+    v.sort();
+    for i in 0..v.len() {
+        assert_eq!(v[i], i as i32);
+    }
+
+    // Should not panic.
+    [0i32; 0].sort();
+    [(); 10].sort();
+    [(); 100].sort();
+
+    let mut v = [0xDEADBEEFu64];
+    v.sort();
+    assert!(v == [0xDEADBEEF]);
+}
+
+#[test]
+fn test_sort_stability() {
+    for len in (2..25).chain(500..510) {
+        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.join(&0), [1, 0, 2, 3]);
+    let v: &[&[_]] = &[&[1], &[2], &[3]];
+    assert_eq!(v.join(&0), [1, 0, 2, 0, 3]);
+}
+
+#[test]
+fn test_join() {
+    let v: [Vec<i32>; 0] = [];
+    assert_eq!(v.join(&0), []);
+    assert_eq!([vec![1], vec![2, 3]].join(&0), [1, 0, 2, 3]);
+    assert_eq!([vec![1], vec![2], vec![3]].join(&0), [1, 0, 2, 0, 3]);
+
+    let v: [&[_]; 2] = [&[1], &[2, 3]];
+    assert_eq!(v.join(&0), [1, 0, 2, 3]);
+    let v: [&[_]; 3] = [&[1], &[2], &[3]];
+    assert_eq!(v.join(&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[1..3];
+    assert_eq!(v.len(), 2);
+    assert_eq!(v[0], 2);
+    assert_eq!(v[1], 3);
+}
+
+macro_rules! assert_order {
+    (Greater, $a:expr, $b:expr) => {
+        assert_eq!($a.cmp($b), Greater);
+        assert!($a > $b);
+    };
+    (Less, $a:expr, $b:expr) => {
+        assert_eq!($a.cmp($b), Less);
+        assert!($a < $b);
+    };
+    (Equal, $a:expr, $b:expr) => {
+        assert_eq!($a.cmp($b), Equal);
+        assert_eq!($a, $b);
+    }
+}
+
+#[test]
+fn test_total_ord_u8() {
+    let c = &[1u8, 2, 3];
+    assert_order!(Greater, &[1u8, 2, 3, 4][..], &c[..]);
+    let c = &[1u8, 2, 3, 4];
+    assert_order!(Less, &[1u8, 2, 3][..], &c[..]);
+    let c = &[1u8, 2, 3, 6];
+    assert_order!(Equal, &[1u8, 2, 3, 6][..], &c[..]);
+    let c = &[1u8, 2, 3, 4, 5, 6];
+    assert_order!(Less, &[1u8, 2, 3, 4, 5, 5, 5, 5][..], &c[..]);
+    let c = &[1u8, 2, 3, 4];
+    assert_order!(Greater, &[2u8, 2][..], &c[..]);
+}
+
+
+#[test]
+fn test_total_ord_i32() {
+    let c = &[1, 2, 3];
+    assert_order!(Greater, &[1, 2, 3, 4][..], &c[..]);
+    let c = &[1, 2, 3, 4];
+    assert_order!(Less, &[1, 2, 3][..], &c[..]);
+    let c = &[1, 2, 3, 6];
+    assert_order!(Equal, &[1, 2, 3, 6][..], &c[..]);
+    let c = &[1, 2, 3, 4, 5, 6];
+    assert_order!(Less, &[1, 2, 3, 4, 5, 5, 5, 5][..], &c[..]);
+    let c = &[1, 2, 3, 4];
+    assert_order!(Greater, &[2, 2][..], &c[..]);
+}
+
+#[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_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_as_slice() {
+    let xs = [1, 2, 5, 10, 11];
+    let mut iter = xs.iter();
+    assert_eq!(iter.as_slice(), &[1, 2, 5, 10, 11]);
+    iter.next();
+    assert_eq!(iter.as_slice(), &[2, 5, 10, 11]);
+}
+
+#[test]
+fn test_iter_as_ref() {
+    let xs = [1, 2, 5, 10, 11];
+    let mut iter = xs.iter();
+    assert_eq!(iter.as_ref(), &[1, 2, 5, 10, 11]);
+    iter.next();
+    assert_eq!(iter.as_ref(), &[2, 5, 10, 11]);
+}
+
+#[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_iter_is_empty() {
+    let xs = [1, 2, 5, 10, 11];
+    for i in 0..xs.len() {
+        for j in i..xs.len() {
+            assert_eq!(xs[i..j].iter().is_empty(), xs[i..j].is_empty());
+        }
+    }
+}
+
+#[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(1, |x| *x % 2 == 0).collect::<Vec<_>>(), splits);
+    let splits: &[&[_]] = &[&[1], &[3, 4, 5]];
+    assert_eq!(xs.splitn(2, |x| *x % 2 == 0).collect::<Vec<_>>(), splits);
+    let splits: &[&[_]] = &[&[], &[], &[], &[4, 5]];
+    assert_eq!(xs.splitn(4, |_| true).collect::<Vec<_>>(), splits);
+
+    let xs: &[i32] = &[];
+    let splits: &[&[i32]] = &[&[]];
+    assert_eq!(xs.splitn(2, |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(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&mut [_]] = &[&mut [1], &mut [3, 4, 5]];
+    assert_eq!(xs.splitn_mut(2, |x| *x % 2 == 0).collect::<Vec<_>>(),
+               splits);
+    let splits: &[&mut [_]] = &[&mut [], &mut [], &mut [], &mut [4, 5]];
+    assert_eq!(xs.splitn_mut(4, |_| true).collect::<Vec<_>>(), splits);
+
+    let xs: &mut [i32] = &mut [];
+    let splits: &[&mut [i32]] = &[&mut []];
+    assert_eq!(xs.splitn_mut(2, |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(1, |x| *x % 2 == 0).collect::<Vec<_>>(), splits);
+    let splits: &[&[_]] = &[&[5], &[1, 2, 3]];
+    assert_eq!(xs.rsplitn(2, |x| *x % 2 == 0).collect::<Vec<_>>(), splits);
+    let splits: &[&[_]] = &[&[], &[], &[], &[1, 2]];
+    assert_eq!(xs.rsplitn(4, |_| true).collect::<Vec<_>>(), splits);
+
+    let xs: &[i32] = &[];
+    let splits: &[&[i32]] = &[&[]];
+    assert_eq!(xs.rsplitn(2, |x| *x == 5).collect::<Vec<&[i32]>>(), splits);
+    assert!(xs.rsplitn(0, |x| *x % 2 == 0).next().is_none());
+}
+
+#[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);
+}
+
+#[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);
+}
+
+#[test]
+#[should_panic]
+fn test_chunksator_0() {
+    let v = &[1, 2, 3, 4];
+    let _it = v.chunks(0);
+}
+
+#[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]
+#[should_panic]
+fn test_overflow_does_not_cause_segfault() {
+    let mut v = vec![];
+    v.reserve_exact(!0);
+    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(!0);
+    v.push(Rc::new(2));
+}
+
+#[test]
+fn test_mut_split_at() {
+    let mut values = [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!(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]);
+}
+
+#[test]
+fn test_box_slice_clone() {
+    let data = vec![vec![0, 1], vec![0], vec![1]];
+    let data2 = data.clone().into_boxed_slice().clone().to_vec();
+
+    assert_eq!(data, data2);
+}
+
+#[test]
+#[cfg_attr(target_os = "emscripten", ignore)]
+fn test_box_slice_clone_panics() {
+    use std::sync::Arc;
+    use std::sync::atomic::{AtomicUsize, Ordering};
+    use std::thread::spawn;
+
+    struct Canary {
+        count: Arc<AtomicUsize>,
+        panics: bool,
+    }
+
+    impl Drop for Canary {
+        fn drop(&mut self) {
+            self.count.fetch_add(1, Ordering::SeqCst);
+        }
+    }
+
+    impl Clone for Canary {
+        fn clone(&self) -> Self {
+            if self.panics {
+                panic!()
+            }
+
+            Canary {
+                count: self.count.clone(),
+                panics: self.panics,
+            }
+        }
+    }
+
+    let drop_count = Arc::new(AtomicUsize::new(0));
+    let canary = Canary {
+        count: drop_count.clone(),
+        panics: false,
+    };
+    let panic = Canary {
+        count: drop_count.clone(),
+        panics: true,
+    };
+
+    spawn(move || {
+            // When xs is dropped, +5.
+            let xs = vec![canary.clone(), canary.clone(), canary.clone(), panic, canary]
+                .into_boxed_slice();
+
+            // When panic is cloned, +3.
+            xs.clone();
+        })
+        .join()
+        .unwrap_err();
+
+    // Total = 8
+    assert_eq!(drop_count.load(Ordering::SeqCst), 8);
+}
+
+#[test]
+fn test_copy_from_slice() {
+    let src = [0, 1, 2, 3, 4, 5];
+    let mut dst = [0; 6];
+    dst.copy_from_slice(&src);
+    assert_eq!(src, dst)
+}
+
+#[test]
+#[should_panic(expected = "destination and source slices have different lengths")]
+fn test_copy_from_slice_dst_longer() {
+    let src = [0, 1, 2, 3];
+    let mut dst = [0; 5];
+    dst.copy_from_slice(&src);
+}
+
+#[test]
+#[should_panic(expected = "destination and source slices have different lengths")]
+fn test_copy_from_slice_dst_shorter() {
+    let src = [0, 1, 2, 3];
+    let mut dst = [0; 3];
+    dst.copy_from_slice(&src);
+}
diff --git a/src/libcollections/tests/str.rs b/src/libcollections/tests/str.rs
new file mode 100644 (file)
index 0000000..c9b7104
--- /dev/null
@@ -0,0 +1,1531 @@
+// 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::borrow::Cow;
+use std::cmp::Ordering::{Equal, Greater, Less};
+use std::str::from_utf8;
+
+#[test]
+fn test_le() {
+    assert!("" <= "");
+    assert!("" <= "foo");
+    assert!("foo" <= "foo");
+    assert!("foo" != "bar");
+}
+
+#[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 = "";
+    let s: String = empty.chars().collect();
+    assert_eq!(empty, s);
+    let data = "ประเทศไทย中";
+    let s: String = data.chars().collect();
+    assert_eq!(data, s);
+}
+
+#[test]
+fn test_into_bytes() {
+    let data = String::from("asdf");
+    let buf = data.into_bytes();
+    assert_eq!(buf, b"asdf");
+}
+
+#[test]
+fn test_find_str() {
+    // byte positions
+    assert_eq!("".find(""), Some(0));
+    assert!("banana".find("apple pie").is_none());
+
+    let data = "abcabc";
+    assert_eq!(data[0..6].find("ab"), Some(0));
+    assert_eq!(data[2..6].find("ab"), Some(3 - 2));
+    assert!(data[2..4].find("ab").is_none());
+
+    let string = "ประเทศไทย中华Việt Nam";
+    let mut data = String::from(string);
+    data.push_str(string);
+    assert!(data.find("ไท华").is_none());
+    assert_eq!(data[0..43].find(""), Some(0));
+    assert_eq!(data[6..43].find(""), Some(6 - 6));
+
+    assert_eq!(data[0..43].find("ประ"), Some( 0));
+    assert_eq!(data[0..43].find("ทศไ"), Some(12));
+    assert_eq!(data[0..43].find("ย中"), Some(24));
+    assert_eq!(data[0..43].find("iệt"), Some(34));
+    assert_eq!(data[0..43].find("Nam"), Some(40));
+
+    assert_eq!(data[43..86].find("ประ"), Some(43 - 43));
+    assert_eq!(data[43..86].find("ทศไ"), Some(55 - 43));
+    assert_eq!(data[43..86].find("ย中"), Some(67 - 43));
+    assert_eq!(data[43..86].find("iệt"), Some(77 - 43));
+    assert_eq!(data[43..86].find("Nam"), Some(83 - 43));
+
+    // find every substring -- assert that it finds it, or an earlier occurrence.
+    let string = "Việt Namacbaabcaabaaba";
+    for (i, ci) in string.char_indices() {
+        let ip = i + ci.len_utf8();
+        for j in string[ip..].char_indices()
+                             .map(|(i, _)| i)
+                             .chain(Some(string.len() - ip))
+        {
+            let pat = &string[i..ip + j];
+            assert!(match string.find(pat) {
+                None => false,
+                Some(x) => x <= i,
+            });
+            assert!(match string.rfind(pat) {
+                None => false,
+                Some(x) => x >= i,
+            });
+        }
+    }
+}
+
+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]
+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_join {
+    ($expected: expr, $string: expr, $delim: expr) => {
+        {
+            let s = $string.join($delim);
+            assert_eq!($expected, s);
+        }
+    }
+}
+
+#[test]
+fn test_join_for_different_types() {
+    test_join!("a-b", ["a", "b"], "-");
+    let hyphen = "-".to_string();
+    test_join!("a-b", [s("a"), s("b")], &*hyphen);
+    test_join!("a-b", vec!["a", "b"], &*hyphen);
+    test_join!("a-b", &*vec!["a", "b"], "-");
+    test_join!("a-b", vec![s("a"), s("b")], "-");
+}
+
+#[test]
+fn test_join_for_different_lengths() {
+    let empty: &[&str] = &[];
+    test_join!("", empty, "-");
+    test_join!("a", ["a"], "-");
+    test_join!("a-b", ["a", "b"], "-");
+    test_join!("-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_eq!(half_a_million_letter_a(),
+        unsafe { 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_replacen() {
+    assert_eq!("".replacen('a', "b", 5), "");
+    assert_eq!("acaaa".replacen("a", "b", 3), "bcbba");
+    assert_eq!("aaaa".replacen("a", "b", 0), "aaaa");
+
+    let test = "test";
+    assert_eq!(" test test ".replacen(test, "toast", 3), " toast toast ");
+    assert_eq!(" test test ".replacen(test, "toast", 0), " test test ");
+    assert_eq!(" test test ".replacen(test, "", 5), "   ");
+
+    assert_eq!("qwer123zxc789".replacen(char::is_numeric, "", 3), "qwerzxc789");
+}
+
+#[test]
+fn test_replace() {
+    let a = "a";
+    assert_eq!("".replace(a, "b"), "");
+    assert_eq!("a".replace(a, "b"), "b");
+    assert_eq!("ab".replace(a, "b"), "bb");
+    let test = "test";
+    assert_eq!(" test test ".replace(test, "toast"), " toast toast ");
+    assert_eq!(" test test ".replace(test, ""), "   ");
+}
+
+#[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_replace_pattern() {
+    let data = "abcdαβγδabcdαβγδ";
+    assert_eq!(data.replace("dαβ", "😺😺😺"), "abc😺😺😺γδabc😺😺😺γδ");
+    assert_eq!(data.replace('γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
+    assert_eq!(data.replace(&['a', 'γ'] as &[_], "😺😺😺"), "😺😺😺bcdαβ😺😺😺δ😺😺😺bcdαβ😺😺😺δ");
+    assert_eq!(data.replace(|c| c == 'γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
+}
+
+#[test]
+fn test_slice() {
+    assert_eq!("ab", &"abc"[0..2]);
+    assert_eq!("bc", &"abc"[1..3]);
+    assert_eq!("", &"abc"[1..1]);
+    assert_eq!("\u{65e5}", &"\u{65e5}\u{672c}"[0..3]);
+
+    let data = "ประเทศไทย中华";
+    assert_eq!("ป", &data[0..3]);
+    assert_eq!("ร", &data[3..6]);
+    assert_eq!("", &data[3..3]);
+    assert_eq!("华", &data[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_eq!(half_a_million_letter_x(), &letters[0..3 * 500000]);
+}
+
+#[test]
+fn test_slice_2() {
+    let ss = "中华Việt Nam";
+
+    assert_eq!("华", &ss[3..6]);
+    assert_eq!("Việt Nam", &ss[6..16]);
+
+    assert_eq!("ab", &"abc"[0..2]);
+    assert_eq!("bc", &"abc"[1..3]);
+    assert_eq!("", &"abc"[1..1]);
+
+    assert_eq!("中", &ss[0..3]);
+    assert_eq!("华V", &ss[3..7]);
+    assert_eq!("", &ss[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"[0..2];
+}
+
+
+#[test]
+fn test_is_char_boundary() {
+    let s = "ศไทย中华Việt Nam β-release 🐱123";
+    assert!(s.is_char_boundary(0));
+    assert!(s.is_char_boundary(s.len()));
+    assert!(!s.is_char_boundary(s.len() + 1));
+    for (i, ch) in s.char_indices() {
+        // ensure character locations are boundaries and continuation bytes are not
+        assert!(s.is_char_boundary(i), "{} is a char boundary in {:?}", i, s);
+        for j in 1..ch.len_utf8() {
+            assert!(!s.is_char_boundary(i + j),
+                    "{} should not be a char boundary in {:?}", i + j, s);
+        }
+    }
+}
+const LOREM_PARAGRAPH: &'static str = "\
+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.";
+
+// check the panic includes the prefix of the sliced string
+#[test]
+#[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")]
+fn test_slice_fail_truncated_1() {
+    &LOREM_PARAGRAPH[..1024];
+}
+// check the truncation in the panic message
+#[test]
+#[should_panic(expected="luctus, im`[...]")]
+fn test_slice_fail_truncated_2() {
+    &LOREM_PARAGRAPH[..1024];
+}
+
+#[test]
+#[should_panic(expected="byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5) of")]
+fn test_slice_fail_boundary_1() {
+    &"abcαβγ"[4..];
+}
+
+#[test]
+#[should_panic(expected="byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7) of")]
+fn test_slice_fail_boundary_2() {
+    &"abcαβγ"[2..6];
+}
+
+#[test]
+fn test_slice_from() {
+    assert_eq!(&"abcd"[0..], "abcd");
+    assert_eq!(&"abcd"[2..], "cd");
+    assert_eq!(&"abcd"[4..], "");
+}
+#[test]
+fn test_slice_to() {
+    assert_eq!(&"abcd"[..0], "");
+    assert_eq!(&"abcd"[..2], "ab");
+    assert_eq!(&"abcd"[..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_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 from_utf8_mostly_ascii() {
+    // deny invalid bytes embedded in long stretches of ascii
+    for i in 32..64 {
+        let mut data = [0; 128];
+        data[i] = 0xC0;
+        assert!(from_utf8(&data).is_err());
+        data[i] = 0xC2;
+        assert!(from_utf8(&data).is_err());
+    }
+}
+
+#[test]
+fn from_utf8_error() {
+    macro_rules! test {
+        ($input: expr, $expected_valid_up_to: expr, $expected_error_len: expr) => {
+            let error = from_utf8($input).unwrap_err();
+            assert_eq!(error.valid_up_to(), $expected_valid_up_to);
+            assert_eq!(error.error_len(), $expected_error_len);
+        }
+    }
+    test!(b"A\xC3\xA9 \xFF ", 4, Some(1));
+    test!(b"A\xC3\xA9 \x80 ", 4, Some(1));
+    test!(b"A\xC3\xA9 \xC1 ", 4, Some(1));
+    test!(b"A\xC3\xA9 \xC1", 4, Some(1));
+    test!(b"A\xC3\xA9 \xC2", 4, None);
+    test!(b"A\xC3\xA9 \xC2 ", 4, Some(1));
+    test!(b"A\xC3\xA9 \xC2\xC0", 4, Some(1));
+    test!(b"A\xC3\xA9 \xE0", 4, None);
+    test!(b"A\xC3\xA9 \xE0\x9F", 4, Some(1));
+    test!(b"A\xC3\xA9 \xE0\xA0", 4, None);
+    test!(b"A\xC3\xA9 \xE0\xA0\xC0", 4, Some(2));
+    test!(b"A\xC3\xA9 \xE0\xA0 ", 4, Some(2));
+    test!(b"A\xC3\xA9 \xED\xA0\x80 ", 4, Some(1));
+    test!(b"A\xC3\xA9 \xF1", 4, None);
+    test!(b"A\xC3\xA9 \xF1\x80", 4, None);
+    test!(b"A\xC3\xA9 \xF1\x80\x80", 4, None);
+    test!(b"A\xC3\xA9 \xF1 ", 4, Some(1));
+    test!(b"A\xC3\xA9 \xF1\x80 ", 4, Some(2));
+    test!(b"A\xC3\xA9 \xF1\x80\x80 ", 4, Some(3));
+}
+
+#[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("");
+    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 vec_str_conversions() {
+    let s1: String = String::from("All mimsy were the borogoves");
+
+    let v: Vec<u8> = s1.as_bytes().to_vec();
+    let s2: String = String::from(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];
+        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('b'));
+    assert!("a".contains('a'));
+    assert!(!"abc".contains('d'));
+    assert!(!"".contains('a'));
+}
+
+#[test]
+fn test_split_at() {
+    let s = "ศไทย中华Việt Nam";
+    for (index, _) in s.char_indices() {
+        let (a, b) = s.split_at(index);
+        assert_eq!(&s[..a.len()], a);
+        assert_eq!(&s[a.len()..], b);
+    }
+    let (a, b) = s.split_at(s.len());
+    assert_eq!(a, s);
+    assert_eq!(b, "");
+}
+
+#[test]
+fn test_split_at_mut() {
+    use std::ascii::AsciiExt;
+    let mut s = "Hello World".to_string();
+    {
+        let (a, b) = s.split_at_mut(5);
+        a.make_ascii_uppercase();
+        b.make_ascii_lowercase();
+    }
+    assert_eq!(s, "HELLO world");
+}
+
+#[test]
+#[should_panic]
+fn test_split_at_boundscheck() {
+    let s = "ศไทย中华Việt Nam";
+    s.split_at(1);
+}
+
+#[test]
+fn test_escape_unicode() {
+    assert_eq!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}");
+    assert_eq!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}");
+    assert_eq!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}");
+    assert_eq!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}");
+    assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
+    assert_eq!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}");
+    assert_eq!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}");
+    assert_eq!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}");
+    assert_eq!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}");
+}
+
+#[test]
+fn test_escape_debug() {
+    assert_eq!("abc".escape_debug(), "abc");
+    assert_eq!("a c".escape_debug(), "a c");
+    assert_eq!("éèê".escape_debug(), "éèê");
+    assert_eq!("\r\n\t".escape_debug(), "\\r\\n\\t");
+    assert_eq!("'\"\\".escape_debug(), "\\'\\\"\\\\");
+    assert_eq!("\u{7f}\u{ff}".escape_debug(), "\\u{7f}\u{ff}");
+    assert_eq!("\u{100}\u{ffff}".escape_debug(), "\u{100}\\u{ffff}");
+    assert_eq!("\u{10000}\u{10ffff}".escape_debug(), "\u{10000}\\u{10ffff}");
+    assert_eq!("ab\u{200b}".escape_debug(), "ab\\u{200b}");
+    assert_eq!("\u{10d4ea}\r".escape_debug(), "\\u{10d4ea}\\r");
+}
+
+#[test]
+fn test_escape_default() {
+    assert_eq!("abc".escape_default(), "abc");
+    assert_eq!("a c".escape_default(), "a c");
+    assert_eq!("éèê".escape_default(), "\\u{e9}\\u{e8}\\u{ea}");
+    assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t");
+    assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\");
+    assert_eq!("\u{7f}\u{ff}".escape_default(), "\\u{7f}\\u{ff}");
+    assert_eq!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
+    assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
+    assert_eq!("ab\u{200b}".escape_default(), "ab\\u{200b}");
+    assert_eq!("\u{10d4ea}\r".escape_default(), "\\u{10d4ea}\\r");
+}
+
+#[test]
+fn test_total_ord() {
+    assert_eq!("1234".cmp("123"), Greater);
+    assert_eq!("123".cmp("1234"), Less);
+    assert_eq!("1234".cmp("1234"), Equal);
+    assert_eq!("12345555".cmp("123456"), Less);
+    assert_eq!("22".cmp("1234"), Greater);
+}
+
+#[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());
+    assert_eq!(s.chars().count(), 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 s = c.encode_utf8(&mut bytes);
+        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 s = c.encode_utf8(&mut bytes);
+        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_iterator_last() {
+    let s = "ศไทย中华Việt Nam";
+    let mut it = s.chars();
+    it.next();
+    assert_eq!(it.last(), Some('m'));
+}
+
+#[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_bytesator_nth() {
+    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 b = s.bytes();
+    assert_eq!(b.nth(2).unwrap(), v[2]);
+    assert_eq!(b.nth(10).unwrap(), v[10]);
+    assert_eq!(b.nth(200), None);
+}
+
+#[test]
+fn test_bytesator_count() {
+    let s = "ศไทย中华Việt Nam";
+
+    let b = s.bytes();
+    assert_eq!(b.count(), 28)
+}
+
+#[test]
+fn test_bytesator_last() {
+    let s = "ศไทย中华Việt Nam";
+
+    let b = s.bytes();
+    assert_eq!(b.last().unwrap(), 109)
+}
+
+#[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_char_indices_last() {
+    let s = "ศไทย中华Việt Nam";
+    let mut it = s.char_indices();
+    it.next();
+    assert_eq!(it.last(), Some((27, 'm')));
+}
+
+#[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(4, ' ').collect();
+    assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
+
+    let split: Vec<&str> = data.splitn(4, |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(4, 'ä').collect();
+    assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
+
+    let split: Vec<&str> = data.splitn(4, |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_rsplit() {
+    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+    let split: Vec<&str> = data.rsplit(' ').collect();
+    assert_eq!(split, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
+
+    let split: Vec<&str> = data.rsplit("lämb").collect();
+    assert_eq!(split, ["\n", "\nLittle ", "\nMäry häd ä little "]);
+
+    let split: Vec<&str> = data.rsplit(|c: char| c == 'ä').collect();
+    assert_eq!(split, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
+}
+
+#[test]
+fn test_rsplitn() {
+    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+    let split: Vec<&str> = data.rsplitn(2, ' ').collect();
+    assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
+
+    let split: Vec<&str> = data.rsplitn(2, "lämb").collect();
+    assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]);
+
+    let split: Vec<&str> = data.rsplitn(2, |c: char| c == 'ä').collect();
+    assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
+}
+
+#[test]
+fn test_split_whitespace() {
+    let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
+    let words: Vec<&str> = data.split_whitespace().collect();
+    assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
+}
+
+#[test]
+fn test_lines() {
+    let data = "\nMäry häd ä little lämb\n\r\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 = "\r\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_splitator() {
+    fn t(s: &str, sep: &str, u: &[&str]) {
+        let v: Vec<&str> = s.split(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 + AsRef<str>>() {
+        let s: S = Default::default();
+        assert_eq!(s.as_ref(), "");
+    }
+
+    t::<&str>();
+    t::<String>();
+}
+
+#[test]
+fn test_str_container() {
+    fn sum_len(v: &[&str]) -> usize {
+        v.iter().map(|x| x.len()).sum()
+    }
+
+    let s = "01234";
+    assert_eq!(5, sum_len(&["012", "", "34"]));
+    assert_eq!(5, sum_len(&["01", "2", "34", ""]));
+    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!(from_utf8(xs).is_err());
+}
+
+#[test]
+fn test_pattern_deref_forward() {
+    let data = "aabcdaa";
+    assert!(data.contains("bcd"));
+    assert!(data.contains(&"bcd"));
+    assert!(data.contains(&"bcd".to_string()));
+}
+
+#[test]
+fn test_empty_match_indices() {
+    let data = "aä中!";
+    let vec: Vec<_> = data.match_indices("").collect();
+    assert_eq!(vec, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
+}
+
+#[test]
+fn test_bool_from_str() {
+    assert_eq!("true".parse().ok(), Some(true));
+    assert_eq!("false".parse().ok(), Some(false));
+    assert_eq!("not even a boolean".parse::<bool>().ok(), None);
+}
+
+fn check_contains_all_substrings(s: &str) {
+    assert!(s.contains(""));
+    for i in 0..s.len() {
+        for j in i+1..s.len() + 1 {
+            assert!(s.contains(&s[i..j]));
+        }
+    }
+}
+
+#[test]
+fn strslice_issue_16589() {
+    assert!("bananas".contains("nana"));
+
+    // prior to the fix for #16589, x.contains("abcdabcd") returned false
+    // test all substrings for good measure
+    check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
+}
+
+#[test]
+fn strslice_issue_16878() {
+    assert!(!"1234567ah012345678901ah".contains("hah"));
+    assert!(!"00abc01234567890123456789abc".contains("bcabc"));
+}
+
+
+#[test]
+fn test_strslice_contains() {
+    let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
+    check_contains_all_substrings(x);
+}
+
+#[test]
+fn test_rsplitn_char_iterator() {
+    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+    let mut split: Vec<&str> = data.rsplitn(4, ' ').collect();
+    split.reverse();
+    assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
+
+    let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == ' ').collect();
+    split.reverse();
+    assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
+
+    // Unicode
+    let mut split: Vec<&str> = data.rsplitn(4, 'ä').collect();
+    split.reverse();
+    assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
+
+    let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == 'ä').collect();
+    split.reverse();
+    assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
+}
+
+#[test]
+fn test_split_char_iterator() {
+    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+    let split: Vec<&str> = data.split(' ').collect();
+    assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+
+    let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
+    rsplit.reverse();
+    assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+
+    let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
+    assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+
+    let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
+    rsplit.reverse();
+    assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+
+    // Unicode
+    let split: Vec<&str> = data.split('ä').collect();
+    assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+
+    let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
+    rsplit.reverse();
+    assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+
+    let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
+    assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+
+    let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
+    rsplit.reverse();
+    assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+}
+
+#[test]
+fn test_rev_split_char_iterator_no_trailing() {
+    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+    let mut split: Vec<&str> = data.split('\n').rev().collect();
+    split.reverse();
+    assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
+
+    let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
+    split.reverse();
+    assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
+}
+
+#[test]
+fn test_utf16_code_units() {
+    use std_unicode::str::Utf16Encoder;
+    assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::<Vec<u16>>(),
+               [0xE9, 0xD83D, 0xDCA9])
+}
+
+#[test]
+fn starts_with_in_unicode() {
+    assert!(!"├── Cargo.toml".starts_with("# "));
+}
+
+#[test]
+fn starts_short_long() {
+    assert!(!"".starts_with("##"));
+    assert!(!"##".starts_with("####"));
+    assert!("####".starts_with("##"));
+    assert!(!"##ä".starts_with("####"));
+    assert!("####ä".starts_with("##"));
+    assert!(!"##".starts_with("####ä"));
+    assert!("##ä##".starts_with("##ä"));
+
+    assert!("".starts_with(""));
+    assert!("ä".starts_with(""));
+    assert!("#ä".starts_with(""));
+    assert!("##ä".starts_with(""));
+    assert!("ä###".starts_with(""));
+    assert!("#ä##".starts_with(""));
+    assert!("##ä#".starts_with(""));
+}
+
+#[test]
+fn contains_weird_cases() {
+    assert!("* \t".contains(' '));
+    assert!(!"* \t".contains('?'));
+    assert!(!"* \t".contains('\u{1F4A9}'));
+}
+
+#[test]
+fn trim_ws() {
+    assert_eq!(" \t  a \t  ".trim_left_matches(|c: char| c.is_whitespace()),
+                    "a \t  ");
+    assert_eq!(" \t  a \t  ".trim_right_matches(|c: char| c.is_whitespace()),
+               " \t  a");
+    assert_eq!(" \t  a \t  ".trim_matches(|c: char| c.is_whitespace()),
+                    "a");
+    assert_eq!(" \t   \t  ".trim_left_matches(|c: char| c.is_whitespace()),
+                         "");
+    assert_eq!(" \t   \t  ".trim_right_matches(|c: char| c.is_whitespace()),
+               "");
+    assert_eq!(" \t   \t  ".trim_matches(|c: char| c.is_whitespace()),
+               "");
+}
+
+#[test]
+fn to_lowercase() {
+    assert_eq!("".to_lowercase(), "");
+    assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé ");
+
+    // https://github.com/rust-lang/rust/issues/26035
+    assert_eq!("ΑΣ".to_lowercase(), "ας");
+    assert_eq!("Α'Σ".to_lowercase(), "α'ς");
+    assert_eq!("Α''Σ".to_lowercase(), "α''ς");
+
+    assert_eq!("ΑΣ Α".to_lowercase(), "ας α");
+    assert_eq!("Α'Σ Α".to_lowercase(), "α'ς α");
+    assert_eq!("Α''Σ Α".to_lowercase(), "α''ς α");
+
+    assert_eq!("ΑΣ' Α".to_lowercase(), "ας' α");
+    assert_eq!("ΑΣ'' Α".to_lowercase(), "ας'' α");
+
+    assert_eq!("Α'Σ' Α".to_lowercase(), "α'ς' α");
+    assert_eq!("Α''Σ'' Α".to_lowercase(), "α''ς'' α");
+
+    assert_eq!("Α Σ".to_lowercase(), "α σ");
+    assert_eq!("Α 'Σ".to_lowercase(), "α 'σ");
+    assert_eq!("Α ''Σ".to_lowercase(), "α ''σ");
+
+    assert_eq!("Σ".to_lowercase(), "σ");
+    assert_eq!("'Σ".to_lowercase(), "'σ");
+    assert_eq!("''Σ".to_lowercase(), "''σ");
+
+    assert_eq!("ΑΣΑ".to_lowercase(), "ασα");
+    assert_eq!("ΑΣ'Α".to_lowercase(), "ασ'α");
+    assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α");
+}
+
+#[test]
+fn to_uppercase() {
+    assert_eq!("".to_uppercase(), "");
+    assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
+}
+
+#[test]
+fn test_into_string() {
+    // The only way to acquire a Box<str> in the first place is through a String, so just
+    // test that we can round-trip between Box<str> and String.
+    let string = String::from("Some text goes here");
+    assert_eq!(string.clone().into_boxed_str().into_string(), string);
+}
+
+#[test]
+fn test_box_slice_clone() {
+    let data = String::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
+    let data2 = data.clone().into_boxed_str().clone().into_string();
+
+    assert_eq!(data, data2);
+}
+
+#[test]
+fn test_cow_from() {
+    let borrowed = "borrowed";
+    let owned = String::from("owned");
+    match (Cow::from(owned.clone()), Cow::from(borrowed)) {
+        (Cow::Owned(o), Cow::Borrowed(b)) => assert!(o == owned && b == borrowed),
+        _ => panic!("invalid `Cow::from`"),
+    }
+}
+
+#[test]
+fn test_repeat() {
+    assert_eq!("".repeat(3), "");
+    assert_eq!("abc".repeat(0), "");
+    assert_eq!("α".repeat(3), "ααα");
+}
+
+mod pattern {
+    use std::str::pattern::Pattern;
+    use std::str::pattern::{Searcher, ReverseSearcher};
+    use std::str::pattern::SearchStep::{self, Match, Reject, Done};
+
+    macro_rules! make_test {
+        ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => {
+            #[allow(unused_imports)]
+            mod $name {
+                use std::str::pattern::SearchStep::{Match, Reject};
+                use super::{cmp_search_to_vec};
+                #[test]
+                fn fwd() {
+                    cmp_search_to_vec(false, $p, $h, vec![$($e),*]);
+                }
+                #[test]
+                fn bwd() {
+                    cmp_search_to_vec(true, $p, $h, vec![$($e),*]);
+                }
+            }
+        }
+    }
+
+    fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str,
+                                             right: Vec<SearchStep>)
+    where P::Searcher: ReverseSearcher<'a>
+    {
+        let mut searcher = pat.into_searcher(haystack);
+        let mut v = vec![];
+        loop {
+            match if !rev {searcher.next()} else {searcher.next_back()} {
+                Match(a, b) => v.push(Match(a, b)),
+                Reject(a, b) => v.push(Reject(a, b)),
+                Done => break,
+            }
+        }
+        if rev {
+            v.reverse();
+        }
+
+        let mut first_index = 0;
+        let mut err = None;
+
+        for (i, e) in right.iter().enumerate() {
+            match *e {
+                Match(a, b) | Reject(a, b)
+                if a <= b && a == first_index => {
+                    first_index = b;
+                }
+                _ => {
+                    err = Some(i);
+                    break;
+                }
+            }
+        }
+
+        if let Some(err) = err {
+            panic!("Input skipped range at {}", err);
+        }
+
+        if first_index != haystack.len() {
+            panic!("Did not cover whole input");
+        }
+
+        assert_eq!(v, right);
+    }
+
+    make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [
+        Reject(0, 1),
+        Match (1, 3),
+        Reject(3, 4),
+        Match (4, 6),
+        Reject(6, 7),
+    ]);
+    make_test!(str_searcher_ascii_haystack_seq, "bb", "abbcbbbbd", [
+        Reject(0, 1),
+        Match (1, 3),
+        Reject(3, 4),
+        Match (4, 6),
+        Match (6, 8),
+        Reject(8, 9),
+    ]);
+    make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [
+        Match (0, 0),
+        Reject(0, 1),
+        Match (1, 1),
+        Reject(1, 2),
+        Match (2, 2),
+        Reject(2, 3),
+        Match (3, 3),
+        Reject(3, 4),
+        Match (4, 4),
+        Reject(4, 5),
+        Match (5, 5),
+        Reject(5, 6),
+        Match (6, 6),
+        Reject(6, 7),
+        Match (7, 7),
+    ]);
+    make_test!(str_searcher_mulibyte_haystack, " ", "├──", [
+        Reject(0, 3),
+        Reject(3, 6),
+        Reject(6, 9),
+    ]);
+    make_test!(str_searcher_empty_needle_mulibyte_haystack, "", "├──", [
+        Match (0, 0),
+        Reject(0, 3),
+        Match (3, 3),
+        Reject(3, 6),
+        Match (6, 6),
+        Reject(6, 9),
+        Match (9, 9),
+    ]);
+    make_test!(str_searcher_empty_needle_empty_haystack, "", "", [
+        Match(0, 0),
+    ]);
+    make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", [
+    ]);
+    make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [
+        Reject(0, 1),
+        Match (1, 2),
+        Match (2, 3),
+        Reject(3, 4),
+        Match (4, 5),
+        Match (5, 6),
+        Reject(6, 7),
+    ]);
+    make_test!(char_searcher_mulibyte_haystack, ' ', "├──", [
+        Reject(0, 3),
+        Reject(3, 6),
+        Reject(6, 9),
+    ]);
+    make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [
+        Reject(0, 1),
+        Reject(1, 2),
+        Reject(2, 3),
+    ]);
+
+}
+
+macro_rules! generate_iterator_test {
+    {
+        $name:ident {
+            $(
+                ($($arg:expr),*) -> [$($t:tt)*];
+            )*
+        }
+        with $fwd:expr, $bwd:expr;
+    } => {
+        #[test]
+        fn $name() {
+            $(
+                {
+                    let res = vec![$($t)*];
+
+                    let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
+                    assert_eq!(fwd_vec, res);
+
+                    let mut bwd_vec: Vec<_> = ($bwd)($($arg),*).collect();
+                    bwd_vec.reverse();
+                    assert_eq!(bwd_vec, res);
+                }
+            )*
+        }
+    };
+    {
+        $name:ident {
+            $(
+                ($($arg:expr),*) -> [$($t:tt)*];
+            )*
+        }
+        with $fwd:expr;
+    } => {
+        #[test]
+        fn $name() {
+            $(
+                {
+                    let res = vec![$($t)*];
+
+                    let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
+                    assert_eq!(fwd_vec, res);
+                }
+            )*
+        }
+    }
+}
+
+generate_iterator_test! {
+    double_ended_split {
+        ("foo.bar.baz", '.') -> ["foo", "bar", "baz"];
+        ("foo::bar::baz", "::") -> ["foo", "bar", "baz"];
+    }
+    with str::split, str::rsplit;
+}
+
+generate_iterator_test! {
+    double_ended_split_terminator {
+        ("foo;bar;baz;", ';') -> ["foo", "bar", "baz"];
+    }
+    with str::split_terminator, str::rsplit_terminator;
+}
+
+generate_iterator_test! {
+    double_ended_matches {
+        ("a1b2c3", char::is_numeric) -> ["1", "2", "3"];
+    }
+    with str::matches, str::rmatches;
+}
+
+generate_iterator_test! {
+    double_ended_match_indices {
+        ("a1b2c3", char::is_numeric) -> [(1, "1"), (3, "2"), (5, "3")];
+    }
+    with str::match_indices, str::rmatch_indices;
+}
+
+generate_iterator_test! {
+    not_double_ended_splitn {
+        ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"];
+    }
+    with str::splitn;
+}
+
+generate_iterator_test! {
+    not_double_ended_rsplitn {
+        ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"];
+    }
+    with str::rsplitn;
+}
+
+#[test]
+fn different_str_pattern_forwarding_lifetimes() {
+    use std::str::pattern::Pattern;
+
+    fn foo<'a, P>(p: P) where for<'b> &'b P: Pattern<'a> {
+        for _ in 0..3 {
+            "asdf".find(&p);
+        }
+    }
+
+    foo::<&str>("x");
+}
diff --git a/src/libcollections/tests/string.rs b/src/libcollections/tests/string.rs
new file mode 100644 (file)
index 0000000..2f021b9
--- /dev/null
@@ -0,0 +1,435 @@
+// 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::Cow;
+
+pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
+    fn into_cow(self) -> Cow<'a, B>;
+}
+
+impl<'a> IntoCow<'a, str> for String {
+    fn into_cow(self) -> Cow<'a, str> {
+        Cow::Owned(self)
+    }
+}
+
+impl<'a> IntoCow<'a, str> for &'a str {
+    fn into_cow(self) -> Cow<'a, str> {
+        Cow::Borrowed(self)
+    }
+}
+
+#[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_from_cow_str() {
+    assert_eq!(String::from(Cow::Borrowed("string")), "string");
+    assert_eq!(String::from(Cow::Owned(String::from("string"))), "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("hello"));
+
+    let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
+    assert_eq!(String::from_utf8(xs).unwrap(),
+               String::from("ศไทย中华Việt Nam"));
+
+    let xs = b"hello\xFF".to_vec();
+    let err = String::from_utf8(xs).unwrap_err();
+    assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
+}
+
+#[test]
+fn test_from_utf8_lossy() {
+    let xs = b"hello";
+    let ys: Cow<str> = "hello".into_cow();
+    assert_eq!(String::from_utf8_lossy(xs), ys);
+
+    let xs = "ศไทย中华Việt Nam".as_bytes();
+    let ys: Cow<str> = "ศไทย中华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("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("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("\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("\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("\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("\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("\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("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
+                  vec![0xd800, 0xdf45, 0xd800, 0xdf3f, 0xd800, 0xdf3b, 0xd800, 0xdf46, 0xd800,
+                       0xdf39, 0xd800, 0xdf3b, 0xd800, 0xdf30, 0x000a]),
+
+                 (String::from("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
+                  vec![0xd801, 0xdc12, 0xd801, 0xdc49, 0xd801, 0xdc2e, 0xd801, 0xdc40, 0xd801,
+                       0xdc32, 0xd801, 0xdc4b, 0x0020, 0xd801, 0xdc0f, 0xd801, 0xdc32, 0xd801,
+                       0xdc4d, 0x000a]),
+
+                 (String::from("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\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("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\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("\u{20000}"), vec![0xD840, 0xDC00])];
+
+    for p in &pairs {
+        let (s, u) = (*p).clone();
+        let s_as_utf16 = s.encode_utf16().collect::<Vec<u16>>();
+        let u_as_string = String::from_utf16(&u).unwrap();
+
+        assert!(::std_unicode::char::decode_utf16(u.iter().cloned()).all(|r| r.is_ok()));
+        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.encode_utf16().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("\u{FFFD}"));
+    // lead + lead
+    assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]),
+               String::from("\u{FFFD}\u{FFFD}"));
+
+    // isolated trail
+    assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]),
+               String::from("a\u{FFFD}"));
+
+    // general
+    assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
+               String::from("\u{FFFD}𐒋\u{FFFD}"));
+}
+
+#[test]
+fn test_push_bytes() {
+    let mut s = String::from("ABC");
+    unsafe {
+        let mv = s.as_mut_vec();
+        mv.extend_from_slice(&[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_add_assign() {
+    let mut s = String::new();
+    s += "";
+    assert_eq!(s.as_str(), "");
+    s += "abc";
+    assert_eq!(s.as_str(), "abc");
+    s += "ประเทศไทย中华Việt Nam";
+    assert_eq!(s.as_str(), "abcประเทศไทย中华Việt Nam");
+}
+
+#[test]
+fn test_push() {
+    let mut data = String::from("ประเทศไทย中");
+    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("ประเทศไทย中华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_split_off_empty() {
+    let orig = "Hello, world!";
+    let mut split = String::from(orig);
+    let empty: String = split.split_off(orig.len());
+    assert!(empty.is_empty());
+}
+
+#[test]
+#[should_panic]
+fn test_split_off_past_end() {
+    let orig = "Hello, world!";
+    let mut split = String::from(orig);
+    split.split_off(orig.len() + 1);
+}
+
+#[test]
+#[should_panic]
+fn test_split_off_mid_char() {
+    let mut orig = String::from("山");
+    orig.split_off(1);
+}
+
+#[test]
+fn test_split_off_ascii() {
+    let mut ab = String::from("ABCD");
+    let cd = ab.split_off(2);
+    assert_eq!(ab, "AB");
+    assert_eq!(cd, "CD");
+}
+
+#[test]
+fn test_split_off_unicode() {
+    let mut nihon = String::from("日本語");
+    let go = nihon.split_off("日本".len());
+    assert_eq!(nihon, "日本");
+    assert_eq!(go, "語");
+}
+
+#[test]
+fn test_str_truncate() {
+    let mut s = String::from("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("12345");
+    let p = s.as_ptr();
+    s.truncate(3);
+    s.push_str("6");
+    let p_ = s.as_ptr();
+    assert_eq!(p_, p);
+}
+
+#[test]
+fn test_str_truncate_invalid_len() {
+    let mut s = String::from("12345");
+    s.truncate(6);
+    assert_eq!(s, "12345");
+}
+
+#[test]
+#[should_panic]
+fn test_str_truncate_split_codepoint() {
+    let mut s = String::from("\u{FC}"); // ü
+    s.truncate(1);
+}
+
+#[test]
+fn test_str_clear() {
+    let mut s = String::from("12345");
+    s.clear();
+    assert_eq!(s.len(), 0);
+    assert_eq!(s, "");
+}
+
+#[test]
+fn test_str_add() {
+    let a = String::from("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]);
+    assert_eq!(s, d);
+}
+
+#[test]
+fn test_drain() {
+    let mut s = String::from("αβγ");
+    assert_eq!(s.drain(2..4).collect::<String>(), "β");
+    assert_eq!(s, "αγ");
+
+    let mut t = String::from("abcd");
+    t.drain(..0);
+    assert_eq!(t, "abcd");
+    t.drain(..1);
+    assert_eq!(t, "bcd");
+    t.drain(3..);
+    assert_eq!(t, "bcd");
+    t.drain(..);
+    assert_eq!(t, "");
+}
+
+#[test]
+fn test_extend_ref() {
+    let mut a = "foo".to_string();
+    a.extend(&['b', 'a', 'r']);
+
+    assert_eq!(&a, "foobar");
+}
+
+#[test]
+fn test_into_boxed_str() {
+    let xs = String::from("hello my name is bob");
+    let ys = xs.into_boxed_str();
+    assert_eq!(&*ys, "hello my name is bob");
+}
diff --git a/src/libcollections/tests/vec.rs b/src/libcollections/tests/vec.rs
new file mode 100644 (file)
index 0000000..63df0eb
--- /dev/null
@@ -0,0 +1,698 @@
+// 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::ascii::AsciiExt;
+use std::borrow::Cow;
+use std::mem::size_of;
+use std::panic;
+use std::vec::{Drain, IntoIter};
+
+struct DropCounter<'a> {
+    count: &'a mut u32,
+}
+
+impl<'a> Drop for DropCounter<'a> {
+    fn drop(&mut self) {
+        *self.count += 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);
+
+    v.extend(w.clone()); // specializes to `append`
+    assert!(v.iter().eq(w.iter().chain(w.iter())));
+}
+
+#[test]
+fn test_extend_ref() {
+    let mut v = vec![1, 2];
+    v.extend(&[3, 4, 5]);
+
+    assert_eq!(v.len(), 5);
+    assert_eq!(v, [1, 2, 3, 4, 5]);
+
+    let w = vec![6, 7];
+    v.extend(&w);
+
+    assert_eq!(v.len(), 7);
+    assert_eq!(v, [1, 2, 3, 4, 5, 6, 7]);
+}
+
+#[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 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_by_key() {
+    fn case(a: Vec<i32>, b: Vec<i32>) {
+        let mut v = a;
+        v.dedup_by_key(|i| *i / 10);
+        assert_eq!(v, b);
+    }
+    case(vec![], vec![]);
+    case(vec![10], vec![10]);
+    case(vec![10, 11], vec![10]);
+    case(vec![10, 20, 30], vec![10, 20, 30]);
+    case(vec![10, 11, 20, 30], vec![10, 20, 30]);
+    case(vec![10, 20, 21, 30], vec![10, 20, 30]);
+    case(vec![10, 20, 30, 31], vec![10, 20, 30]);
+    case(vec![10, 11, 20, 21, 22, 30, 31], vec![10, 20, 30]);
+}
+
+#[test]
+fn test_dedup_by() {
+    let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
+    vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+    assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
+}
+
+#[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 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_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[!0..];
+}
+
+#[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[!0..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_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]
+#[should_panic]
+fn test_drain_out_of_bounds() {
+    let mut v = vec![1, 2, 3, 4, 5];
+    v.drain(5..6);
+}
+
+#[test]
+fn test_drain_range() {
+    let mut v = vec![1, 2, 3, 4, 5];
+    for _ in v.drain(4..) {
+    }
+    assert_eq!(v, &[1, 2, 3, 4]);
+
+    let mut v: Vec<_> = (1..6).map(|x| x.to_string()).collect();
+    for _ in v.drain(1..4) {
+    }
+    assert_eq!(v, &[1.to_string(), 5.to_string()]);
+
+    let mut v: Vec<_> = (1..6).map(|x| x.to_string()).collect();
+    for _ in v.drain(1..4).rev() {
+    }
+    assert_eq!(v, &[1.to_string(), 5.to_string()]);
+
+    let mut v: Vec<_> = vec![(); 5];
+    for _ in v.drain(1..4).rev() {
+    }
+    assert_eq!(v, &[(), ()]);
+}
+
+#[test]
+fn test_drain_inclusive_range() {
+    let mut v = vec!['a', 'b', 'c', 'd', 'e'];
+    for _ in v.drain(1...3) {
+    }
+    assert_eq!(v, &['a', 'e']);
+
+    let mut v: Vec<_> = (0...5).map(|x| x.to_string()).collect();
+    for _ in v.drain(1...5) {
+    }
+    assert_eq!(v, &["0".to_string()]);
+
+    let mut v: Vec<String> = (0...5).map(|x| x.to_string()).collect();
+    for _ in v.drain(0...5) {
+    }
+    assert_eq!(v, Vec::<String>::new());
+
+    let mut v: Vec<_> = (0...5).map(|x| x.to_string()).collect();
+    for _ in v.drain(0...3) {
+    }
+    assert_eq!(v, &["4".to_string(), "5".to_string()]);
+
+    let mut v: Vec<_> = (0...1).map(|x| x.to_string()).collect();
+    for _ in v.drain(...0) {
+    }
+    assert_eq!(v, &["1".to_string()]);
+}
+
+#[test]
+fn test_drain_max_vec_size() {
+    let mut v = Vec::<()>::with_capacity(usize::max_value());
+    unsafe { v.set_len(usize::max_value()); }
+    for _ in v.drain(usize::max_value() - 1..) {
+    }
+    assert_eq!(v.len(), usize::max_value() - 1);
+
+    let mut v = Vec::<()>::with_capacity(usize::max_value());
+    unsafe { v.set_len(usize::max_value()); }
+    for _ in v.drain(usize::max_value() - 1...usize::max_value() - 1) {
+    }
+    assert_eq!(v.len(), usize::max_value() - 1);
+}
+
+#[test]
+#[should_panic]
+fn test_drain_inclusive_out_of_bounds() {
+    let mut v = vec![1, 2, 3, 4, 5];
+    v.drain(5...5);
+}
+
+#[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]);
+}
+
+#[test]
+fn test_into_iter_as_slice() {
+    let vec = vec!['a', 'b', 'c'];
+    let mut into_iter = vec.into_iter();
+    assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
+    let _ = into_iter.next().unwrap();
+    assert_eq!(into_iter.as_slice(), &['b', 'c']);
+    let _ = into_iter.next().unwrap();
+    let _ = into_iter.next().unwrap();
+    assert_eq!(into_iter.as_slice(), &[]);
+}
+
+#[test]
+fn test_into_iter_as_mut_slice() {
+    let vec = vec!['a', 'b', 'c'];
+    let mut into_iter = vec.into_iter();
+    assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
+    into_iter.as_mut_slice()[0] = 'x';
+    into_iter.as_mut_slice()[1] = 'y';
+    assert_eq!(into_iter.next().unwrap(), 'x');
+    assert_eq!(into_iter.as_slice(), &['y', 'c']);
+}
+
+#[test]
+fn test_into_iter_debug() {
+    let vec = vec!['a', 'b', 'c'];
+    let into_iter = vec.into_iter();
+    let debug = format!("{:?}", into_iter);
+    assert_eq!(debug, "IntoIter(['a', 'b', 'c'])");
+}
+
+#[test]
+fn test_into_iter_count() {
+    assert_eq!(vec![1, 2, 3].into_iter().count(), 3);
+}
+
+#[test]
+fn test_into_iter_clone() {
+    fn iter_equal<I: Iterator<Item = i32>>(it: I, slice: &[i32]) {
+        let v: Vec<i32> = it.collect();
+        assert_eq!(&v[..], slice);
+    }
+    let mut it = vec![1, 2, 3].into_iter();
+    iter_equal(it.clone(), &[1, 2, 3]);
+    assert_eq!(it.next(), Some(1));
+    let mut it = it.rev();
+    iter_equal(it.clone(), &[3, 2]);
+    assert_eq!(it.next(), Some(3));
+    iter_equal(it.clone(), &[2]);
+    assert_eq!(it.next(), Some(2));
+    iter_equal(it.clone(), &[]);
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_cow_from() {
+    let borrowed: &[_] = &["borrowed", "(slice)"];
+    let owned = vec!["owned", "(vec)"];
+    match (Cow::from(owned.clone()), Cow::from(borrowed)) {
+        (Cow::Owned(o), Cow::Borrowed(b)) => assert!(o == owned && b == borrowed),
+        _ => panic!("invalid `Cow::from`"),
+    }
+}
+
+#[test]
+fn test_from_cow() {
+    let borrowed: &[_] = &["borrowed", "(slice)"];
+    let owned = vec!["owned", "(vec)"];
+    assert_eq!(Vec::from(Cow::Borrowed(borrowed)), vec!["borrowed", "(slice)"]);
+    assert_eq!(Vec::from(Cow::Owned(owned)), vec!["owned", "(vec)"]);
+}
+
+#[allow(dead_code)]
+fn assert_covariance() {
+    fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
+        d
+    }
+    fn into_iter<'new>(i: IntoIter<&'static str>) -> IntoIter<&'new str> {
+        i
+    }
+}
+
+#[test]
+fn test_placement() {
+    let mut vec = vec![1];
+    assert_eq!(vec.place_back() <- 2, &2);
+    assert_eq!(vec.len(), 2);
+    assert_eq!(vec.place_back() <- 3, &3);
+    assert_eq!(vec.len(), 3);
+    assert_eq!(&vec, &[1, 2, 3]);
+}
+
+#[test]
+fn test_placement_panic() {
+    let mut vec = vec![1, 2, 3];
+    fn mkpanic() -> usize { panic!() }
+    let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { vec.place_back() <- mkpanic(); }));
+    assert_eq!(vec.len(), 3);
+}
+
+#[test]
+fn from_into_inner() {
+    let vec = vec![1, 2, 3];
+    let ptr = vec.as_ptr();
+    let vec = vec.into_iter().collect::<Vec<_>>();
+    assert_eq!(vec, [1, 2, 3]);
+    assert_eq!(vec.as_ptr(), ptr);
+
+    let ptr = &vec[1] as *const _;
+    let mut it = vec.into_iter();
+    it.next().unwrap();
+    let vec = it.collect::<Vec<_>>();
+    assert_eq!(vec, [2, 3]);
+    assert!(ptr != vec.as_ptr());
+}
diff --git a/src/libcollections/tests/vec_deque.rs b/src/libcollections/tests/vec_deque.rs
new file mode 100644 (file)
index 0000000..f2935c0
--- /dev/null
@@ -0,0 +1,1024 @@
+// 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::collections::vec_deque::{Drain};
+
+use self::Taggy::*;
+use self::Taggypar::*;
+
+#[test]
+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);
+    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];
+}
+
+#[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().map(|x| *x).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() {
+    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 = (0..).step_by(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_partial_eq_array() {
+    let d = VecDeque::<char>::new();
+    assert!(d == []);
+
+    let mut d = VecDeque::new();
+    d.push_front('a');
+    assert!(d == ['a']);
+
+    let mut d = VecDeque::new();
+    d.push_back('a');
+    assert!(d == ['a']);
+
+    let mut d = VecDeque::new();
+    d.push_back('a');
+    d.push_back('b');
+    assert!(d == ['a', 'b']);
+}
+
+#[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(&x) == ::hash(&y));
+}
+
+#[test]
+fn test_hash_after_rotation() {
+    // test that two deques hash equal even if elements are laid out differently
+    let len = 28;
+    let mut ring: VecDeque<i32> = (0..len as i32).collect();
+    let orig = ring.clone();
+    for _ in 0..ring.capacity() {
+        // shift values 1 step to the right by pop, sub one, push
+        ring.pop_front();
+        for elt in &mut ring {
+            *elt -= 1;
+        }
+        ring.push_back(len - 1);
+        assert_eq!(::hash(&orig), ::hash(&ring));
+        assert_eq!(orig, ring);
+        assert_eq!(ring, orig);
+    }
+}
+
+#[test]
+fn test_eq_after_rotation() {
+    // test that two deques are equal even if elements are laid out differently
+    let len = 28;
+    let mut ring: VecDeque<i32> = (0..len as i32).collect();
+    let mut shifted = ring.clone();
+    for _ in 0..10 {
+        // shift values 1 step to the right by pop, sub one, push
+        ring.pop_front();
+        for elt in &mut ring {
+            *elt -= 1;
+        }
+        ring.push_back(len - 1);
+    }
+
+    // try every shift
+    for _ in 0..shifted.capacity() {
+        shifted.pop_front();
+        for elt in &mut shifted {
+            *elt -= 1;
+        }
+        shifted.push_back(len - 1);
+        assert_eq!(shifted, ring);
+        assert_eq!(ring, shifted);
+    }
+}
+
+#[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<_>>(), []);
+}
+
+#[test]
+fn test_retain() {
+    let mut buf = VecDeque::new();
+    buf.extend(1..5);
+    buf.retain(|&x| x % 2 == 0);
+    let v: Vec<_> = buf.into_iter().collect();
+    assert_eq!(&v[..], &[2, 4]);
+}
+
+#[test]
+fn test_extend_ref() {
+    let mut v = VecDeque::new();
+    v.push_back(1);
+    v.extend(&[2, 3, 4]);
+
+    assert_eq!(v.len(), 4);
+    assert_eq!(v[0], 1);
+    assert_eq!(v[1], 2);
+    assert_eq!(v[2], 3);
+    assert_eq!(v[3], 4);
+
+    let mut w = VecDeque::new();
+    w.push_back(5);
+    w.push_back(6);
+    v.extend(&w);
+
+    assert_eq!(v.len(), 6);
+    assert_eq!(v[0], 1);
+    assert_eq!(v[1], 2);
+    assert_eq!(v[2], 3);
+    assert_eq!(v[3], 4);
+    assert_eq!(v[4], 5);
+    assert_eq!(v[5], 6);
+}
+
+#[test]
+fn test_contains() {
+    let mut v = VecDeque::new();
+    v.extend(&[2, 3, 4]);
+
+    assert!(v.contains(&3));
+    assert!(!v.contains(&1));
+
+    v.clear();
+
+    assert!(!v.contains(&3));
+}
+
+#[allow(dead_code)]
+fn assert_covariance() {
+    fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
+        d
+    }
+}
+
+#[test]
+fn test_is_empty() {
+    let mut v = VecDeque::<i32>::new();
+    assert!(v.is_empty());
+    assert!(v.iter().is_empty());
+    assert!(v.iter_mut().is_empty());
+    v.extend(&[2, 3, 4]);
+    assert!(!v.is_empty());
+    assert!(!v.iter().is_empty());
+    assert!(!v.iter_mut().is_empty());
+    while let Some(_) = v.pop_front() {
+        assert_eq!(v.is_empty(), v.len() == 0);
+        assert_eq!(v.iter().is_empty(), v.iter().len() == 0);
+        assert_eq!(v.iter_mut().is_empty(), v.iter_mut().len() == 0);
+    }
+    assert!(v.is_empty());
+    assert!(v.iter().is_empty());
+    assert!(v.iter_mut().is_empty());
+    assert!(v.into_iter().is_empty());
+}
+
+#[test]
+fn test_placement_in() {
+    let mut buf: VecDeque<isize> = VecDeque::new();
+    buf.place_back() <- 1;
+    buf.place_back() <- 2;
+    assert_eq!(buf, [1,2]);
+
+    buf.place_front() <- 3;
+    buf.place_front() <- 4;
+    assert_eq!(buf, [4,3,1,2]);
+
+    {
+        let ptr_head = buf.place_front() <- 5;
+        assert_eq!(*ptr_head, 5);
+    }
+    {
+        let ptr_tail = buf.place_back() <- 6;
+        assert_eq!(*ptr_tail, 6);
+    }
+    assert_eq!(buf, [5,4,3,1,2,6]);
+}
index 56b60a3e00341b6b4eb6605b65d16d3350e0c2b5..c258ac2bdea9be0a81930b2d5bbb56cd1935c340 100644 (file)
@@ -678,8 +678,9 @@ pub unsafe fn set_len(&mut self, len: usize) {
         self.len = len;
     }
 
-    /// Removes an element from anywhere in the vector and return it, replacing
-    /// it with the last element.
+    /// Removes an element from the vector and returns it.
+    ///
+    /// The removed element is replaced by the last element of the vector.
     ///
     /// This does not preserve ordering, but is O(1).
     ///
@@ -972,6 +973,29 @@ pub fn push(&mut self, value: T) {
         }
     }
 
+    /// Returns a place for insertion at the back of the `Vec`.
+    ///
+    /// Using this method with placement syntax is equivalent to [`push`](#method.push),
+    /// but may be more efficient.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(collection_placement)]
+    /// #![feature(placement_in_syntax)]
+    ///
+    /// let mut vec = vec![1, 2];
+    /// vec.place_back() <- 3;
+    /// vec.place_back() <- 4;
+    /// assert_eq!(&vec, &[1, 2, 3, 4]);
+    /// ```
+    #[unstable(feature = "collection_placement",
+               reason = "placement protocol is subject to change",
+               issue = "30172")]
+    pub fn place_back(&mut self) -> PlaceBack<T> {
+        PlaceBack { vec: self }
+    }
+
     /// Removes the last element from a vector and returns it, or [`None`] if it
     /// is empty.
     ///
@@ -1266,29 +1290,6 @@ fn extend_with_element(&mut self, n: usize, value: T) {
     pub fn extend_from_slice(&mut self, other: &[T]) {
         self.spec_extend(other.iter())
     }
-
-    /// Returns a place for insertion at the back of the `Vec`.
-    ///
-    /// Using this method with placement syntax is equivalent to [`push`](#method.push),
-    /// but may be more efficient.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(collection_placement)]
-    /// #![feature(placement_in_syntax)]
-    ///
-    /// let mut vec = vec![1, 2];
-    /// vec.place_back() <- 3;
-    /// vec.place_back() <- 4;
-    /// assert_eq!(&vec, &[1, 2, 3, 4]);
-    /// ```
-    #[unstable(feature = "collection_placement",
-               reason = "placement protocol is subject to change",
-               issue = "30172")]
-    pub fn place_back(&mut self) -> PlaceBack<T> {
-        PlaceBack { vec: self }
-    }
 }
 
 // Set the length of the vec when the `SetLenOnDrop` value goes out of scope.
@@ -2073,14 +2074,10 @@ fn next(&mut self) -> Option<T> {
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let diff = (self.end as usize) - (self.ptr as usize);
-        let size = mem::size_of::<T>();
-        let exact = diff /
-                    (if size == 0 {
-                         1
-                     } else {
-                         size
-                     });
+        let exact = match self.ptr.offset_to(self.end) {
+            Some(x) => x as usize,
+            None => (self.end as usize).wrapping_sub(self.ptr as usize),
+        };
         (exact, Some(exact))
     }
 
index cb92236ec736cf8928f92da43e8efb5921d7feea..22f2ff1a3461830b13fd9ff25cdb579bd9c1c429 100644 (file)
@@ -635,7 +635,7 @@ pub fn shrink_to_fit(&mut self) {
         }
     }
 
-    /// Shortens a `VecDeque`, dropping excess elements from the back.
+    /// Shortens the `VecDeque`, dropping excess elements from the back.
     ///
     /// If `len` is greater than the `VecDeque`'s current length, this has no
     /// effect.
@@ -941,7 +941,7 @@ pub fn contains(&self, x: &T) -> bool
         a.contains(x) || b.contains(x)
     }
 
-    /// Provides a reference to the front element, or `None` if the sequence is
+    /// Provides a reference to the front element, or `None` if the `VecDeque` is
     /// empty.
     ///
     /// # Examples
@@ -966,7 +966,7 @@ pub fn front(&self) -> Option<&T> {
     }
 
     /// Provides a mutable reference to the front element, or `None` if the
-    /// sequence is empty.
+    /// `VecDeque` is empty.
     ///
     /// # Examples
     ///
@@ -993,7 +993,7 @@ pub fn front_mut(&mut self) -> Option<&mut T> {
         }
     }
 
-    /// Provides a reference to the back element, or `None` if the sequence is
+    /// Provides a reference to the back element, or `None` if the `VecDeque` is
     /// empty.
     ///
     /// # Examples
@@ -1018,7 +1018,7 @@ pub fn back(&self) -> Option<&T> {
     }
 
     /// Provides a mutable reference to the back element, or `None` if the
-    /// sequence is empty.
+    /// `VecDeque` is empty.
     ///
     /// # Examples
     ///
@@ -1046,7 +1046,7 @@ pub fn back_mut(&mut self) -> Option<&mut T> {
         }
     }
 
-    /// Removes the first element and returns it, or `None` if the sequence is
+    /// Removes the first element and returns it, or `None` if the `VecDeque` is
     /// empty.
     ///
     /// # Examples
@@ -1073,7 +1073,7 @@ pub fn pop_front(&mut self) -> Option<T> {
         }
     }
 
-    /// Inserts an element first in the sequence.
+    /// Prepends an element to the `VecDeque`.
     ///
     /// # Examples
     ///
@@ -1096,7 +1096,7 @@ pub fn push_front(&mut self, value: T) {
         }
     }
 
-    /// Appends an element to the back of a buffer
+    /// Appends an element to the back of the `VecDeque`.
     ///
     /// # Examples
     ///
@@ -1117,7 +1117,7 @@ pub fn push_back(&mut self, value: T) {
         unsafe { self.buffer_write(head, value) }
     }
 
-    /// Removes the last element from a buffer and returns it, or `None` if
+    /// Removes the last element from the `VecDeque` and returns it, or `None` if
     /// it is empty.
     ///
     /// # Examples
diff --git a/src/libcollectionstest/binary_heap.rs b/src/libcollectionstest/binary_heap.rs
deleted file mode 100644 (file)
index d284937..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-// 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::panic;
-use std::collections::BinaryHeap;
-use std::collections::binary_heap::{Drain, PeekMut};
-
-#[test]
-fn test_iterator() {
-    let data = vec![5, 9, 3];
-    let iterout = [9, 5, 3];
-    let heap = BinaryHeap::from(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(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(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(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(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(data);
-    while !heap.is_empty() {
-        assert_eq!(heap.peek().unwrap(), sorted.last().unwrap());
-        assert_eq!(heap.pop().unwrap(), sorted.pop().unwrap());
-    }
-}
-
-#[test]
-fn test_peek_mut() {
-    let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
-    let mut heap = BinaryHeap::from(data);
-    assert_eq!(heap.peek(), Some(&10));
-    {
-        let mut top = heap.peek_mut().unwrap();
-        *top -= 2;
-    }
-    assert_eq!(heap.peek(), Some(&9));
-}
-
-#[test]
-fn test_peek_mut_pop() {
-    let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
-    let mut heap = BinaryHeap::from(data);
-    assert_eq!(heap.peek(), Some(&10));
-    {
-        let mut top = heap.peek_mut().unwrap();
-        *top -= 2;
-        assert_eq!(PeekMut::pop(top), 8);
-    }
-    assert_eq!(heap.peek(), Some(&9));
-}
-
-#[test]
-fn test_push() {
-    let mut heap = BinaryHeap::from(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![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]
-#[allow(deprecated)]
-fn test_push_pop() {
-    let mut heap = BinaryHeap::from(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]
-#[allow(deprecated)]
-fn test_replace() {
-    let mut heap = BinaryHeap::from(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(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_peek_mut() {
-    let mut empty = BinaryHeap::<i32>::new();
-    assert!(empty.peek_mut().is_none());
-}
-
-#[test]
-#[allow(deprecated)]
-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());
-}
-
-#[test]
-fn test_extend_ref() {
-    let mut a = BinaryHeap::new();
-    a.push(1);
-    a.push(2);
-
-    a.extend(&[3, 4, 5]);
-
-    assert_eq!(a.len(), 5);
-    assert_eq!(a.into_sorted_vec(), [1, 2, 3, 4, 5]);
-
-    let mut a = BinaryHeap::new();
-    a.push(1);
-    a.push(2);
-    let mut b = BinaryHeap::new();
-    b.push(3);
-    b.push(4);
-    b.push(5);
-
-    a.extend(&b);
-
-    assert_eq!(a.len(), 5);
-    assert_eq!(a.into_sorted_vec(), [1, 2, 3, 4, 5]);
-}
-
-#[test]
-fn test_append() {
-    let mut a = BinaryHeap::from(vec![-10, 1, 2, 3, 3]);
-    let mut b = BinaryHeap::from(vec![-20, 5, 43]);
-
-    a.append(&mut b);
-
-    assert_eq!(a.into_sorted_vec(), [-20, -10, 1, 2, 3, 3, 5, 43]);
-    assert!(b.is_empty());
-}
-
-#[test]
-fn test_append_to_empty() {
-    let mut a = BinaryHeap::new();
-    let mut b = BinaryHeap::from(vec![-20, 5, 43]);
-
-    a.append(&mut b);
-
-    assert_eq!(a.into_sorted_vec(), [-20, 5, 43]);
-    assert!(b.is_empty());
-}
-
-#[test]
-fn test_extend_specialization() {
-    let mut a = BinaryHeap::from(vec![-10, 1, 2, 3, 3]);
-    let b = BinaryHeap::from(vec![-20, 5, 43]);
-
-    a.extend(b);
-
-    assert_eq!(a.into_sorted_vec(), [-20, -10, 1, 2, 3, 3, 5, 43]);
-}
-
-#[test]
-fn test_placement() {
-    let mut a = BinaryHeap::new();
-    &mut a <- 2;
-    &mut a <- 4;
-    &mut a <- 3;
-    assert_eq!(a.peek(), Some(&4));
-    assert_eq!(a.len(), 3);
-    &mut a <- 1;
-    assert_eq!(a.into_sorted_vec(), vec![1, 2, 3, 4]);
-}
-
-#[test]
-fn test_placement_panic() {
-    let mut heap = BinaryHeap::from(vec![1, 2, 3]);
-    fn mkpanic() -> usize { panic!() }
-    let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { &mut heap <- mkpanic(); }));
-    assert_eq!(heap.len(), 3);
-}
-
-#[allow(dead_code)]
-fn assert_covariance() {
-    fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
-        d
-    }
-}
diff --git a/src/libcollectionstest/btree/map.rs b/src/libcollectionstest/btree/map.rs
deleted file mode 100644 (file)
index 2c899d9..0000000
+++ /dev/null
@@ -1,687 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::collections::BTreeMap;
-use std::collections::Bound::{self, Excluded, Included, Unbounded};
-use std::collections::btree_map::Entry::{Occupied, Vacant};
-use std::rc::Rc;
-
-use std::iter::FromIterator;
-use super::DeterministicRng;
-
-#[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_values_mut() {
-    let mut a = BTreeMap::new();
-    a.insert(1, String::from("hello"));
-    a.insert(2, String::from("goodbye"));
-
-    for value in a.values_mut() {
-        value.push_str("!");
-    }
-
-    let values: Vec<String> = a.values().cloned().collect();
-    assert_eq!(values, [String::from("hello!"), String::from("goodbye!")]);
-}
-
-#[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(2..).zip(2..size) {
-        assert_eq!(k, i);
-        assert_eq!(v, i);
-        j += 1;
-    }
-    assert_eq!(j, size - 2);
-}
-
-#[test]
-fn test_range_inclusive() {
-    let size = 500;
-
-    let map: BTreeMap<_, _> = (0...size).map(|i| (i, i)).collect();
-
-    fn check<'a, L, R>(lhs: L, rhs: R)
-        where L: IntoIterator<Item=(&'a i32, &'a i32)>,
-              R: IntoIterator<Item=(&'a i32, &'a i32)>,
-    {
-        let lhs: Vec<_> = lhs.into_iter().collect();
-        let rhs: Vec<_> = rhs.into_iter().collect();
-        assert_eq!(lhs, rhs);
-    }
-
-    check(map.range(size + 1...size + 1), vec![]);
-    check(map.range(size...size), vec![(&size, &size)]);
-    check(map.range(size...size + 1), vec![(&size, &size)]);
-    check(map.range(0...0), vec![(&0, &0)]);
-    check(map.range(0...size - 1), map.range(..size));
-    check(map.range(-1...-1), vec![]);
-    check(map.range(-1...size), map.range(..));
-    check(map.range(...size), map.range(..));
-    check(map.range(...200), map.range(..201));
-    check(map.range(5...8), vec![(&5, &5), (&6, &6), (&7, &7), (&8, &8)]);
-    check(map.range(-1...0), vec![(&0, &0)]);
-    check(map.range(-1...2), vec![(&0, &0), (&1, &1), (&2, &2)]);
-}
-
-#[test]
-fn test_range_inclusive_max_value() {
-    let max = ::std::usize::MAX;
-    let map: BTreeMap<_, _> = vec![(max, 0)].into_iter().collect();
-
-    assert_eq!(map.range(max...max).collect::<Vec<_>>(), &[(&max, &0)]);
-}
-
-#[test]
-fn test_range_equal_empty_cases() {
-    let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
-    assert_eq!(map.range((Included(2), Excluded(2))).next(), None);
-    assert_eq!(map.range((Excluded(2), Included(2))).next(), None);
-}
-
-#[test]
-#[should_panic]
-fn test_range_equal_excluded() {
-    let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
-    map.range((Excluded(2), Excluded(2)));
-}
-
-#[test]
-#[should_panic]
-fn test_range_backwards_1() {
-    let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
-    map.range((Included(3), Included(2)));
-}
-
-#[test]
-#[should_panic]
-fn test_range_backwards_2() {
-    let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
-    map.range((Included(3), Excluded(2)));
-}
-
-#[test]
-#[should_panic]
-fn test_range_backwards_3() {
-    let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
-    map.range((Excluded(3), Included(2)));
-}
-
-#[test]
-#[should_panic]
-fn test_range_backwards_4() {
-    let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect();
-    map.range((Excluded(3), Excluded(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_borrowed_key() {
-    let mut map = BTreeMap::new();
-    map.insert("aardvark".to_string(), 1);
-    map.insert("baboon".to_string(), 2);
-    map.insert("coyote".to_string(), 3);
-    map.insert("dingo".to_string(), 4);
-    // NOTE: would like to use simply "b".."d" here...
-    let mut iter = map.range::<str, _>((Included("b"),Excluded("d")));
-    assert_eq!(iter.next(), Some((&"baboon".to_string(), &2)));
-    assert_eq!(iter.next(), Some((&"coyote".to_string(), &3)));
-    assert_eq!(iter.next(), None);
-}
-
-#[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 = (i..j + 1).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_range_mut() {
-    let size = 200;
-    let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
-
-    for i in 0..size {
-        for j in i..size {
-            let mut kvs = map.range_mut((Included(&i), Included(&j))).map(|(&k, &mut v)| (k, v));
-            let mut pairs = (i..j + 1).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_borrow() {
-    // make sure these compile -- using the Borrow trait
-    {
-        let mut map = BTreeMap::new();
-        map.insert("0".to_string(), 1);
-        assert_eq!(map["0"], 1);
-    }
-
-    {
-        let mut map = BTreeMap::new();
-        map.insert(Box::new(0), 1);
-        assert_eq!(map[&0], 1);
-    }
-
-    {
-        let mut map = BTreeMap::new();
-        map.insert(Box::new([0, 1]) as Box<[i32]>, 1);
-        assert_eq!(map[&[0, 1][..]], 1);
-    }
-
-    {
-        let mut map = BTreeMap::new();
-        map.insert(Rc::new(0), 1);
-        assert_eq!(map[&0], 1);
-    }
-}
-
-#[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);
-}
-
-#[test]
-fn test_extend_ref() {
-    let mut a = BTreeMap::new();
-    a.insert(1, "one");
-    let mut b = BTreeMap::new();
-    b.insert(2, "two");
-    b.insert(3, "three");
-
-    a.extend(&b);
-
-    assert_eq!(a.len(), 3);
-    assert_eq!(a[&1], "one");
-    assert_eq!(a[&2], "two");
-    assert_eq!(a[&3], "three");
-}
-
-#[test]
-fn test_zst() {
-    let mut m = BTreeMap::new();
-    assert_eq!(m.len(), 0);
-
-    assert_eq!(m.insert((), ()), None);
-    assert_eq!(m.len(), 1);
-
-    assert_eq!(m.insert((), ()), Some(()));
-    assert_eq!(m.len(), 1);
-    assert_eq!(m.iter().count(), 1);
-
-    m.clear();
-    assert_eq!(m.len(), 0);
-
-    for _ in 0..100 {
-        m.insert((), ());
-    }
-
-    assert_eq!(m.len(), 1);
-    assert_eq!(m.iter().count(), 1);
-}
-
-// This test's only purpose is to ensure that zero-sized keys with nonsensical orderings
-// do not cause segfaults when used with zero-sized values. All other map behavior is
-// undefined.
-#[test]
-fn test_bad_zst() {
-    use std::cmp::Ordering;
-
-    struct Bad;
-
-    impl PartialEq for Bad {
-        fn eq(&self, _: &Self) -> bool {
-            false
-        }
-    }
-
-    impl Eq for Bad {}
-
-    impl PartialOrd for Bad {
-        fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
-            Some(Ordering::Less)
-        }
-    }
-
-    impl Ord for Bad {
-        fn cmp(&self, _: &Self) -> Ordering {
-            Ordering::Less
-        }
-    }
-
-    let mut m = BTreeMap::new();
-
-    for _ in 0..100 {
-        m.insert(Bad, Bad);
-    }
-}
-
-#[test]
-fn test_clone() {
-    let mut map = BTreeMap::new();
-    let size = 100;
-    assert_eq!(map.len(), 0);
-
-    for i in 0..size {
-        assert_eq!(map.insert(i, 10 * i), None);
-        assert_eq!(map.len(), i + 1);
-        assert_eq!(map, map.clone());
-    }
-
-    for i in 0..size {
-        assert_eq!(map.insert(i, 100 * i), Some(10 * i));
-        assert_eq!(map.len(), size);
-        assert_eq!(map, map.clone());
-    }
-
-    for i in 0..size / 2 {
-        assert_eq!(map.remove(&(i * 2)), Some(i * 200));
-        assert_eq!(map.len(), size - i - 1);
-        assert_eq!(map, map.clone());
-    }
-
-    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);
-        assert_eq!(map, map.clone());
-    }
-}
-
-#[test]
-#[allow(dead_code)]
-fn test_variance() {
-    use std::collections::btree_map::{Iter, IntoIter, Range, Keys, Values};
-
-    fn map_key<'new>(v: BTreeMap<&'static str, ()>) -> BTreeMap<&'new str, ()> {
-        v
-    }
-    fn map_val<'new>(v: BTreeMap<(), &'static str>) -> BTreeMap<(), &'new str> {
-        v
-    }
-    fn iter_key<'a, 'new>(v: Iter<'a, &'static str, ()>) -> Iter<'a, &'new str, ()> {
-        v
-    }
-    fn iter_val<'a, 'new>(v: Iter<'a, (), &'static str>) -> Iter<'a, (), &'new str> {
-        v
-    }
-    fn into_iter_key<'new>(v: IntoIter<&'static str, ()>) -> IntoIter<&'new str, ()> {
-        v
-    }
-    fn into_iter_val<'new>(v: IntoIter<(), &'static str>) -> IntoIter<(), &'new str> {
-        v
-    }
-    fn range_key<'a, 'new>(v: Range<'a, &'static str, ()>) -> Range<'a, &'new str, ()> {
-        v
-    }
-    fn range_val<'a, 'new>(v: Range<'a, (), &'static str>) -> Range<'a, (), &'new str> {
-        v
-    }
-    fn keys<'a, 'new>(v: Keys<'a, &'static str, ()>) -> Keys<'a, &'new str, ()> {
-        v
-    }
-    fn vals<'a, 'new>(v: Values<'a, (), &'static str>) -> Values<'a, (), &'new str> {
-        v
-    }
-}
-
-#[test]
-fn test_occupied_entry_key() {
-    let mut a = BTreeMap::new();
-    let key = "hello there";
-    let value = "value goes here";
-    assert!(a.is_empty());
-    a.insert(key.clone(), value.clone());
-    assert_eq!(a.len(), 1);
-    assert_eq!(a[key], value);
-
-    match a.entry(key.clone()) {
-        Vacant(_) => panic!(),
-        Occupied(e) => assert_eq!(key, *e.key()),
-    }
-    assert_eq!(a.len(), 1);
-    assert_eq!(a[key], value);
-}
-
-#[test]
-fn test_vacant_entry_key() {
-    let mut a = BTreeMap::new();
-    let key = "hello there";
-    let value = "value goes here";
-
-    assert!(a.is_empty());
-    match a.entry(key.clone()) {
-        Occupied(_) => panic!(),
-        Vacant(e) => {
-            assert_eq!(key, *e.key());
-            e.insert(value.clone());
-        }
-    }
-    assert_eq!(a.len(), 1);
-    assert_eq!(a[key], value);
-}
-
-macro_rules! create_append_test {
-    ($name:ident, $len:expr) => {
-        #[test]
-        fn $name() {
-            let mut a = BTreeMap::new();
-            for i in 0..8 {
-                a.insert(i, i);
-            }
-
-            let mut b = BTreeMap::new();
-            for i in 5..$len {
-                b.insert(i, 2*i);
-            }
-
-            a.append(&mut b);
-
-            assert_eq!(a.len(), $len);
-            assert_eq!(b.len(), 0);
-
-            for i in 0..$len {
-                if i < 5 {
-                    assert_eq!(a[&i], i);
-                } else {
-                    assert_eq!(a[&i], 2*i);
-                }
-            }
-
-            assert_eq!(a.remove(&($len-1)), Some(2*($len-1)));
-            assert_eq!(a.insert($len-1, 20), None);
-        }
-    };
-}
-
-// These are mostly for testing the algorithm that "fixes" the right edge after insertion.
-// Single node.
-create_append_test!(test_append_9, 9);
-// Two leafs that don't need fixing.
-create_append_test!(test_append_17, 17);
-// Two leafs where the second one ends up underfull and needs stealing at the end.
-create_append_test!(test_append_14, 14);
-// Two leafs where the second one ends up empty because the insertion finished at the root.
-create_append_test!(test_append_12, 12);
-// Three levels; insertion finished at the root.
-create_append_test!(test_append_144, 144);
-// Three levels; insertion finished at leaf while there is an empty node on the second level.
-create_append_test!(test_append_145, 145);
-// Tests for several randomly chosen sizes.
-create_append_test!(test_append_170, 170);
-create_append_test!(test_append_181, 181);
-create_append_test!(test_append_239, 239);
-create_append_test!(test_append_1700, 1700);
-
-fn rand_data(len: usize) -> Vec<(u32, u32)> {
-    let mut rng = DeterministicRng::new();
-    Vec::from_iter((0..len).map(|_| (rng.next(), rng.next())))
-}
-
-#[test]
-fn test_split_off_empty_right() {
-    let mut data = rand_data(173);
-
-    let mut map = BTreeMap::from_iter(data.clone());
-    let right = map.split_off(&(data.iter().max().unwrap().0 + 1));
-
-    data.sort();
-    assert!(map.into_iter().eq(data));
-    assert!(right.into_iter().eq(None));
-}
-
-#[test]
-fn test_split_off_empty_left() {
-    let mut data = rand_data(314);
-
-    let mut map = BTreeMap::from_iter(data.clone());
-    let right = map.split_off(&data.iter().min().unwrap().0);
-
-    data.sort();
-    assert!(map.into_iter().eq(None));
-    assert!(right.into_iter().eq(data));
-}
-
-#[test]
-fn test_split_off_large_random_sorted() {
-    let mut data = rand_data(1529);
-    // special case with maximum height.
-    data.sort();
-
-    let mut map = BTreeMap::from_iter(data.clone());
-    let key = data[data.len() / 2].0;
-    let right = map.split_off(&key);
-
-    assert!(map.into_iter().eq(data.clone().into_iter().filter(|x| x.0 < key)));
-    assert!(right.into_iter().eq(data.into_iter().filter(|x| x.0 >= key)));
-}
diff --git a/src/libcollectionstest/btree/mod.rs b/src/libcollectionstest/btree/mod.rs
deleted file mode 100644 (file)
index ae8b18d..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-mod map;
-mod set;
-
-/// XorShiftRng
-struct DeterministicRng {
-    x: u32,
-    y: u32,
-    z: u32,
-    w: u32,
-}
-
-impl DeterministicRng {
-    fn new() -> Self {
-        DeterministicRng {
-            x: 0x193a6754,
-            y: 0xa8a7d469,
-            z: 0x97830e05,
-            w: 0x113ba7bb,
-        }
-    }
-
-    fn next(&mut self) -> u32 {
-        let x = self.x;
-        let t = x ^ (x << 11);
-        self.x = self.y;
-        self.y = self.z;
-        self.z = self.w;
-        let w_ = self.w;
-        self.w = w_ ^ (w_ >> 19) ^ (t ^ (t >> 8));
-        self.w
-    }
-}
diff --git a/src/libcollectionstest/btree/set.rs b/src/libcollectionstest/btree/set.rs
deleted file mode 100644 (file)
index 6171b8b..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::collections::BTreeSet;
-
-use std::iter::FromIterator;
-use super::DeterministicRng;
-
-#[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(&x) == ::hash(&y));
-}
-
-fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F)
-    where F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, &mut FnMut(&i32) -> bool) -> 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,
-      &mut |&x| {
-          assert_eq!(x, expected[i]);
-          i += 1;
-          true
-      });
-    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);
-
-    assert_eq!(z.next().unwrap(), (&5, &("bar")));
-    assert_eq!(z.next().unwrap(), (&11, &("foo")));
-    assert!(z.next().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), "{}");
-}
-
-#[test]
-fn test_extend_ref() {
-    let mut a = BTreeSet::new();
-    a.insert(1);
-
-    a.extend(&[2, 3, 4]);
-
-    assert_eq!(a.len(), 4);
-    assert!(a.contains(&1));
-    assert!(a.contains(&2));
-    assert!(a.contains(&3));
-    assert!(a.contains(&4));
-
-    let mut b = BTreeSet::new();
-    b.insert(5);
-    b.insert(6);
-
-    a.extend(&b);
-
-    assert_eq!(a.len(), 6);
-    assert!(a.contains(&1));
-    assert!(a.contains(&2));
-    assert!(a.contains(&3));
-    assert!(a.contains(&4));
-    assert!(a.contains(&5));
-    assert!(a.contains(&6));
-}
-
-#[test]
-fn test_recovery() {
-    use std::cmp::Ordering;
-
-    #[derive(Debug)]
-    struct Foo(&'static str, i32);
-
-    impl PartialEq for Foo {
-        fn eq(&self, other: &Self) -> bool {
-            self.0 == other.0
-        }
-    }
-
-    impl Eq for Foo {}
-
-    impl PartialOrd for Foo {
-        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-            self.0.partial_cmp(&other.0)
-        }
-    }
-
-    impl Ord for Foo {
-        fn cmp(&self, other: &Self) -> Ordering {
-            self.0.cmp(&other.0)
-        }
-    }
-
-    let mut s = BTreeSet::new();
-    assert_eq!(s.replace(Foo("a", 1)), None);
-    assert_eq!(s.len(), 1);
-    assert_eq!(s.replace(Foo("a", 2)), Some(Foo("a", 1)));
-    assert_eq!(s.len(), 1);
-
-    {
-        let mut it = s.iter();
-        assert_eq!(it.next(), Some(&Foo("a", 2)));
-        assert_eq!(it.next(), None);
-    }
-
-    assert_eq!(s.get(&Foo("a", 1)), Some(&Foo("a", 2)));
-    assert_eq!(s.take(&Foo("a", 1)), Some(Foo("a", 2)));
-    assert_eq!(s.len(), 0);
-
-    assert_eq!(s.get(&Foo("a", 1)), None);
-    assert_eq!(s.take(&Foo("a", 1)), None);
-
-    assert_eq!(s.iter().next(), None);
-}
-
-#[test]
-#[allow(dead_code)]
-fn test_variance() {
-    use std::collections::btree_set::{IntoIter, Iter, Range};
-
-    fn set<'new>(v: BTreeSet<&'static str>) -> BTreeSet<&'new str> {
-        v
-    }
-    fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> {
-        v
-    }
-    fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> {
-        v
-    }
-    fn range<'a, 'new>(v: Range<'a, &'static str>) -> Range<'a, &'new str> {
-        v
-    }
-}
-
-#[test]
-fn test_append() {
-    let mut a = BTreeSet::new();
-    a.insert(1);
-    a.insert(2);
-    a.insert(3);
-
-    let mut b = BTreeSet::new();
-    b.insert(3);
-    b.insert(4);
-    b.insert(5);
-
-    a.append(&mut b);
-
-    assert_eq!(a.len(), 5);
-    assert_eq!(b.len(), 0);
-
-    assert_eq!(a.contains(&1), true);
-    assert_eq!(a.contains(&2), true);
-    assert_eq!(a.contains(&3), true);
-    assert_eq!(a.contains(&4), true);
-    assert_eq!(a.contains(&5), true);
-}
-
-fn rand_data(len: usize) -> Vec<u32> {
-    let mut rng = DeterministicRng::new();
-    Vec::from_iter((0..len).map(|_| rng.next()))
-}
-
-#[test]
-fn test_split_off_empty_right() {
-    let mut data = rand_data(173);
-
-    let mut set = BTreeSet::from_iter(data.clone());
-    let right = set.split_off(&(data.iter().max().unwrap() + 1));
-
-    data.sort();
-    assert!(set.into_iter().eq(data));
-    assert!(right.into_iter().eq(None));
-}
-
-#[test]
-fn test_split_off_empty_left() {
-    let mut data = rand_data(314);
-
-    let mut set = BTreeSet::from_iter(data.clone());
-    let right = set.split_off(data.iter().min().unwrap());
-
-    data.sort();
-    assert!(set.into_iter().eq(None));
-    assert!(right.into_iter().eq(data));
-}
-
-#[test]
-fn test_split_off_large_random_sorted() {
-    let mut data = rand_data(1529);
-    // special case with maximum height.
-    data.sort();
-
-    let mut set = BTreeSet::from_iter(data.clone());
-    let key = data[data.len() / 2];
-    let right = set.split_off(&key);
-
-    assert!(set.into_iter().eq(data.clone().into_iter().filter(|x| *x < key)));
-    assert!(right.into_iter().eq(data.into_iter().filter(|x| *x >= key)));
-}
diff --git a/src/libcollectionstest/cow_str.rs b/src/libcollectionstest/cow_str.rs
deleted file mode 100644 (file)
index b292451..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2016 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::Cow;
-
-// check that Cow<'a, str> implements addition
-#[test]
-fn check_cow_add_cow() {
-    let borrowed1 = Cow::Borrowed("Hello, ");
-    let borrowed2 = Cow::Borrowed("World!");
-    let borrow_empty = Cow::Borrowed("");
-
-    let owned1: Cow<str> = Cow::Owned(String::from("Hi, "));
-    let owned2: Cow<str> = Cow::Owned(String::from("Rustaceans!"));
-    let owned_empty: Cow<str> = Cow::Owned(String::new());
-
-    assert_eq!("Hello, World!", borrowed1.clone() + borrowed2.clone());
-    assert_eq!("Hello, Rustaceans!", borrowed1.clone() + owned2.clone());
-
-    assert_eq!("Hi, World!", owned1.clone() + borrowed2.clone());
-    assert_eq!("Hi, Rustaceans!", owned1.clone() + owned2.clone());
-
-    if let Cow::Owned(_) = borrowed1.clone() + borrow_empty.clone() {
-        panic!("Adding empty strings to a borrow should note allocate");
-    }
-    if let Cow::Owned(_) = borrow_empty.clone() + borrowed1.clone() {
-        panic!("Adding empty strings to a borrow should note allocate");
-    }
-    if let Cow::Owned(_) = borrowed1.clone() + owned_empty.clone() {
-        panic!("Adding empty strings to a borrow should note allocate");
-    }
-    if let Cow::Owned(_) = owned_empty.clone() + borrowed1.clone() {
-        panic!("Adding empty strings to a borrow should note allocate");
-    }
-}
-
-#[test]
-fn check_cow_add_str() {
-    let borrowed = Cow::Borrowed("Hello, ");
-    let borrow_empty = Cow::Borrowed("");
-
-    let owned: Cow<str> = Cow::Owned(String::from("Hi, "));
-    let owned_empty: Cow<str> = Cow::Owned(String::new());
-
-    assert_eq!("Hello, World!", borrowed.clone() + "World!");
-
-    assert_eq!("Hi, World!", owned.clone() + "World!");
-
-    if let Cow::Owned(_) = borrowed.clone() + "" {
-        panic!("Adding empty strings to a borrow should note allocate");
-    }
-    if let Cow::Owned(_) = borrow_empty.clone() + "Hello, " {
-        panic!("Adding empty strings to a borrow should note allocate");
-    }
-    if let Cow::Owned(_) = owned_empty.clone() + "Hello, " {
-        panic!("Adding empty strings to a borrow should note allocate");
-    }
-}
-
-#[test]
-fn check_cow_add_assign_cow() {
-    let mut borrowed1 = Cow::Borrowed("Hello, ");
-    let borrowed2 = Cow::Borrowed("World!");
-    let borrow_empty = Cow::Borrowed("");
-
-    let mut owned1: Cow<str> = Cow::Owned(String::from("Hi, "));
-    let owned2: Cow<str> = Cow::Owned(String::from("Rustaceans!"));
-    let owned_empty: Cow<str> = Cow::Owned(String::new());
-
-    let mut s = borrowed1.clone();
-    s += borrow_empty.clone();
-    assert_eq!("Hello, ", s);
-    if let Cow::Owned(_) = s {
-        panic!("Adding empty strings to a borrow should note allocate");
-    }
-    let mut s = borrow_empty.clone();
-    s += borrowed1.clone();
-    assert_eq!("Hello, ", s);
-    if let Cow::Owned(_) = s {
-        panic!("Adding empty strings to a borrow should note allocate");
-    }
-    let mut s = borrowed1.clone();
-    s += owned_empty.clone();
-    assert_eq!("Hello, ", s);
-    if let Cow::Owned(_) = s {
-        panic!("Adding empty strings to a borrow should note allocate");
-    }
-    let mut s = owned_empty.clone();
-    s += borrowed1.clone();
-    assert_eq!("Hello, ", s);
-    if let Cow::Owned(_) = s {
-        panic!("Adding empty strings to a borrow should note allocate");
-    }
-
-    owned1 += borrowed2;
-    borrowed1 += owned2;
-
-    assert_eq!("Hi, World!", owned1);
-    assert_eq!("Hello, Rustaceans!", borrowed1);
-}
-
-#[test]
-fn check_cow_add_assign_str() {
-    let mut borrowed = Cow::Borrowed("Hello, ");
-    let borrow_empty = Cow::Borrowed("");
-
-    let mut owned: Cow<str> = Cow::Owned(String::from("Hi, "));
-    let owned_empty: Cow<str> = Cow::Owned(String::new());
-
-    let mut s = borrowed.clone();
-    s += "";
-    assert_eq!("Hello, ", s);
-    if let Cow::Owned(_) = s {
-        panic!("Adding empty strings to a borrow should note allocate");
-    }
-    let mut s = borrow_empty.clone();
-    s += "World!";
-    assert_eq!("World!", s);
-    if let Cow::Owned(_) = s {
-        panic!("Adding empty strings to a borrow should note allocate");
-    }
-    let mut s = owned_empty.clone();
-    s += "World!";
-    assert_eq!("World!", s);
-    if let Cow::Owned(_) = s {
-        panic!("Adding empty strings to a borrow should note allocate");
-    }
-
-    owned += "World!";
-    borrowed += "World!";
-
-    assert_eq!("Hi, World!", owned);
-    assert_eq!("Hello, World!", borrowed);
-}
diff --git a/src/libcollectionstest/fmt.rs b/src/libcollectionstest/fmt.rs
deleted file mode 100644 (file)
index 70e21c6..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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, "Hello, world!");
-}
diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs
deleted file mode 100644 (file)
index 618eb38..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-// 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.
-
-#![deny(warnings)]
-
-#![feature(binary_heap_extras)]
-#![feature(binary_heap_peek_mut_pop)]
-#![feature(box_syntax)]
-#![feature(inclusive_range_syntax)]
-#![feature(collection_placement)]
-#![feature(collections)]
-#![feature(const_fn)]
-#![feature(exact_size_is_empty)]
-#![feature(pattern)]
-#![feature(placement_in_syntax)]
-#![feature(rand)]
-#![feature(step_by)]
-#![feature(str_escape)]
-#![feature(test)]
-#![feature(unboxed_closures)]
-#![feature(unicode)]
-#![feature(utf8_error_error_len)]
-
-extern crate collections;
-extern crate test;
-extern crate std_unicode;
-extern crate core;
-
-use std::hash::{Hash, Hasher};
-use std::collections::hash_map::DefaultHasher;
-
-mod binary_heap;
-mod btree;
-mod cow_str;
-mod fmt;
-mod linked_list;
-mod slice;
-mod str;
-mod string;
-mod vec_deque;
-mod vec;
-
-fn hash<T: Hash>(t: &T) -> u64 {
-    let mut s = DefaultHasher::new();
-    t.hash(&mut s);
-    s.finish()
-}
diff --git a/src/libcollectionstest/linked_list.rs b/src/libcollectionstest/linked_list.rs
deleted file mode 100644 (file)
index a59724a..0000000
+++ /dev/null
@@ -1,368 +0,0 @@
-// 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;
-
-#[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(&x) == ::hash(&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(&x) == ::hash(&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\"]");
-}
-
-#[test]
-fn test_extend_ref() {
-    let mut a = LinkedList::new();
-    a.push_back(1);
-
-    a.extend(&[2, 3, 4]);
-
-    assert_eq!(a.len(), 4);
-    assert_eq!(a, list_from(&[1, 2, 3, 4]));
-
-    let mut b = LinkedList::new();
-    b.push_back(5);
-    b.push_back(6);
-    a.extend(&b);
-
-    assert_eq!(a.len(), 6);
-    assert_eq!(a, list_from(&[1, 2, 3, 4, 5, 6]));
-}
-
-#[test]
-fn test_extend() {
-    let mut a = LinkedList::new();
-    a.push_back(1);
-    a.extend(vec![2, 3, 4]); // uses iterator
-
-    assert_eq!(a.len(), 4);
-    assert!(a.iter().eq(&[1, 2, 3, 4]));
-
-    let b: LinkedList<_> = vec![5, 6, 7].into_iter().collect();
-    a.extend(b); // specializes to `append`
-
-    assert_eq!(a.len(), 7);
-    assert!(a.iter().eq(&[1, 2, 3, 4, 5, 6, 7]));
-}
-
-#[test]
-fn test_contains() {
-    let mut l = LinkedList::new();
-    l.extend(&[2, 3, 4]);
-
-    assert!(l.contains(&3));
-    assert!(!l.contains(&1));
-
-    l.clear();
-
-    assert!(!l.contains(&3));
-}
diff --git a/src/libcollectionstest/slice.rs b/src/libcollectionstest/slice.rs
deleted file mode 100644 (file)
index c3e5304..0000000
+++ /dev/null
@@ -1,1180 +0,0 @@
-// 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::mem;
-use std::__rand::{Rng, thread_rng};
-use std::rc::Rc;
-
-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[..];
-        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_split_first() {
-    let mut a = vec![11];
-    let b: &[i32] = &[];
-    assert!(b.split_first().is_none());
-    assert_eq!(a.split_first(), Some((&11, b)));
-    a = vec![11, 12];
-    let b: &[i32] = &[12];
-    assert_eq!(a.split_first(), Some((&11, b)));
-}
-
-#[test]
-fn test_split_first_mut() {
-    let mut a = vec![11];
-    let b: &mut [i32] = &mut [];
-    assert!(b.split_first_mut().is_none());
-    assert!(a.split_first_mut() == Some((&mut 11, b)));
-    a = vec![11, 12];
-    let b: &mut [_] = &mut [12];
-    assert!(a.split_first_mut() == Some((&mut 11, b)));
-}
-
-#[test]
-fn test_split_last() {
-    let mut a = vec![11];
-    let b: &[i32] = &[];
-    assert!(b.split_last().is_none());
-    assert_eq!(a.split_last(), Some((&11, b)));
-    a = vec![11, 12];
-    let b: &[_] = &[11];
-    assert_eq!(a.split_last(), Some((&12, b)));
-}
-
-#[test]
-fn test_split_last_mut() {
-    let mut a = vec![11];
-    let b: &mut [i32] = &mut [];
-    assert!(b.split_last_mut().is_none());
-    assert!(a.split_last_mut() == Some((&mut 11, b)));
-
-    a = vec![11, 12];
-    let b: &mut [_] = &mut [11];
-    assert!(a.split_last_mut() == Some((&mut 12, b)));
-}
-
-#[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 0);
-    v.push(box 0);
-    v.push(box 0);
-    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_retain() {
-    let mut v = vec![1, 2, 3, 4, 5];
-    v.retain(is_odd);
-    assert_eq!(v, [1, 3, 5]);
-}
-
-#[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() {
-    let mut rng = thread_rng();
-
-    for len in (2..25).chain(500..510) {
-        for _ in 0..100 {
-            let mut v: Vec<_> = 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]));
-        }
-    }
-
-    // Sort using a completely random comparison function.
-    // This will reorder the elements *somehow*, but won't panic.
-    let mut v = [0; 500];
-    for i in 0..v.len() {
-        v[i] = i as i32;
-    }
-    v.sort_by(|_, _| *rng.choose(&[Less, Equal, Greater]).unwrap());
-    v.sort();
-    for i in 0..v.len() {
-        assert_eq!(v[i], i as i32);
-    }
-
-    // Should not panic.
-    [0i32; 0].sort();
-    [(); 10].sort();
-    [(); 100].sort();
-
-    let mut v = [0xDEADBEEFu64];
-    v.sort();
-    assert!(v == [0xDEADBEEF]);
-}
-
-#[test]
-fn test_sort_stability() {
-    for len in (2..25).chain(500..510) {
-        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.join(&0), [1, 0, 2, 3]);
-    let v: &[&[_]] = &[&[1], &[2], &[3]];
-    assert_eq!(v.join(&0), [1, 0, 2, 0, 3]);
-}
-
-#[test]
-fn test_join() {
-    let v: [Vec<i32>; 0] = [];
-    assert_eq!(v.join(&0), []);
-    assert_eq!([vec![1], vec![2, 3]].join(&0), [1, 0, 2, 3]);
-    assert_eq!([vec![1], vec![2], vec![3]].join(&0), [1, 0, 2, 0, 3]);
-
-    let v: [&[_]; 2] = [&[1], &[2, 3]];
-    assert_eq!(v.join(&0), [1, 0, 2, 3]);
-    let v: [&[_]; 3] = [&[1], &[2], &[3]];
-    assert_eq!(v.join(&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[1..3];
-    assert_eq!(v.len(), 2);
-    assert_eq!(v[0], 2);
-    assert_eq!(v[1], 3);
-}
-
-macro_rules! assert_order {
-    (Greater, $a:expr, $b:expr) => {
-        assert_eq!($a.cmp($b), Greater);
-        assert!($a > $b);
-    };
-    (Less, $a:expr, $b:expr) => {
-        assert_eq!($a.cmp($b), Less);
-        assert!($a < $b);
-    };
-    (Equal, $a:expr, $b:expr) => {
-        assert_eq!($a.cmp($b), Equal);
-        assert_eq!($a, $b);
-    }
-}
-
-#[test]
-fn test_total_ord_u8() {
-    let c = &[1u8, 2, 3];
-    assert_order!(Greater, &[1u8, 2, 3, 4][..], &c[..]);
-    let c = &[1u8, 2, 3, 4];
-    assert_order!(Less, &[1u8, 2, 3][..], &c[..]);
-    let c = &[1u8, 2, 3, 6];
-    assert_order!(Equal, &[1u8, 2, 3, 6][..], &c[..]);
-    let c = &[1u8, 2, 3, 4, 5, 6];
-    assert_order!(Less, &[1u8, 2, 3, 4, 5, 5, 5, 5][..], &c[..]);
-    let c = &[1u8, 2, 3, 4];
-    assert_order!(Greater, &[2u8, 2][..], &c[..]);
-}
-
-
-#[test]
-fn test_total_ord_i32() {
-    let c = &[1, 2, 3];
-    assert_order!(Greater, &[1, 2, 3, 4][..], &c[..]);
-    let c = &[1, 2, 3, 4];
-    assert_order!(Less, &[1, 2, 3][..], &c[..]);
-    let c = &[1, 2, 3, 6];
-    assert_order!(Equal, &[1, 2, 3, 6][..], &c[..]);
-    let c = &[1, 2, 3, 4, 5, 6];
-    assert_order!(Less, &[1, 2, 3, 4, 5, 5, 5, 5][..], &c[..]);
-    let c = &[1, 2, 3, 4];
-    assert_order!(Greater, &[2, 2][..], &c[..]);
-}
-
-#[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_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_as_slice() {
-    let xs = [1, 2, 5, 10, 11];
-    let mut iter = xs.iter();
-    assert_eq!(iter.as_slice(), &[1, 2, 5, 10, 11]);
-    iter.next();
-    assert_eq!(iter.as_slice(), &[2, 5, 10, 11]);
-}
-
-#[test]
-fn test_iter_as_ref() {
-    let xs = [1, 2, 5, 10, 11];
-    let mut iter = xs.iter();
-    assert_eq!(iter.as_ref(), &[1, 2, 5, 10, 11]);
-    iter.next();
-    assert_eq!(iter.as_ref(), &[2, 5, 10, 11]);
-}
-
-#[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_iter_is_empty() {
-    let xs = [1, 2, 5, 10, 11];
-    for i in 0..xs.len() {
-        for j in i..xs.len() {
-            assert_eq!(xs[i..j].iter().is_empty(), xs[i..j].is_empty());
-        }
-    }
-}
-
-#[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(1, |x| *x % 2 == 0).collect::<Vec<_>>(), splits);
-    let splits: &[&[_]] = &[&[1], &[3, 4, 5]];
-    assert_eq!(xs.splitn(2, |x| *x % 2 == 0).collect::<Vec<_>>(), splits);
-    let splits: &[&[_]] = &[&[], &[], &[], &[4, 5]];
-    assert_eq!(xs.splitn(4, |_| true).collect::<Vec<_>>(), splits);
-
-    let xs: &[i32] = &[];
-    let splits: &[&[i32]] = &[&[]];
-    assert_eq!(xs.splitn(2, |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(1, |x| *x % 2 == 0).collect::<Vec<_>>(),
-               splits);
-    let splits: &[&mut [_]] = &[&mut [1], &mut [3, 4, 5]];
-    assert_eq!(xs.splitn_mut(2, |x| *x % 2 == 0).collect::<Vec<_>>(),
-               splits);
-    let splits: &[&mut [_]] = &[&mut [], &mut [], &mut [], &mut [4, 5]];
-    assert_eq!(xs.splitn_mut(4, |_| true).collect::<Vec<_>>(), splits);
-
-    let xs: &mut [i32] = &mut [];
-    let splits: &[&mut [i32]] = &[&mut []];
-    assert_eq!(xs.splitn_mut(2, |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(1, |x| *x % 2 == 0).collect::<Vec<_>>(), splits);
-    let splits: &[&[_]] = &[&[5], &[1, 2, 3]];
-    assert_eq!(xs.rsplitn(2, |x| *x % 2 == 0).collect::<Vec<_>>(), splits);
-    let splits: &[&[_]] = &[&[], &[], &[], &[1, 2]];
-    assert_eq!(xs.rsplitn(4, |_| true).collect::<Vec<_>>(), splits);
-
-    let xs: &[i32] = &[];
-    let splits: &[&[i32]] = &[&[]];
-    assert_eq!(xs.rsplitn(2, |x| *x == 5).collect::<Vec<&[i32]>>(), splits);
-    assert!(xs.rsplitn(0, |x| *x % 2 == 0).next().is_none());
-}
-
-#[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);
-}
-
-#[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);
-}
-
-#[test]
-#[should_panic]
-fn test_chunksator_0() {
-    let v = &[1, 2, 3, 4];
-    let _it = v.chunks(0);
-}
-
-#[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]
-#[should_panic]
-fn test_overflow_does_not_cause_segfault() {
-    let mut v = vec![];
-    v.reserve_exact(!0);
-    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(!0);
-    v.push(Rc::new(2));
-}
-
-#[test]
-fn test_mut_split_at() {
-    let mut values = [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!(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]);
-}
-
-#[test]
-fn test_box_slice_clone() {
-    let data = vec![vec![0, 1], vec![0], vec![1]];
-    let data2 = data.clone().into_boxed_slice().clone().to_vec();
-
-    assert_eq!(data, data2);
-}
-
-#[test]
-#[cfg_attr(target_os = "emscripten", ignore)]
-fn test_box_slice_clone_panics() {
-    use std::sync::Arc;
-    use std::sync::atomic::{AtomicUsize, Ordering};
-    use std::thread::spawn;
-
-    struct Canary {
-        count: Arc<AtomicUsize>,
-        panics: bool,
-    }
-
-    impl Drop for Canary {
-        fn drop(&mut self) {
-            self.count.fetch_add(1, Ordering::SeqCst);
-        }
-    }
-
-    impl Clone for Canary {
-        fn clone(&self) -> Self {
-            if self.panics {
-                panic!()
-            }
-
-            Canary {
-                count: self.count.clone(),
-                panics: self.panics,
-            }
-        }
-    }
-
-    let drop_count = Arc::new(AtomicUsize::new(0));
-    let canary = Canary {
-        count: drop_count.clone(),
-        panics: false,
-    };
-    let panic = Canary {
-        count: drop_count.clone(),
-        panics: true,
-    };
-
-    spawn(move || {
-            // When xs is dropped, +5.
-            let xs = vec![canary.clone(), canary.clone(), canary.clone(), panic, canary]
-                .into_boxed_slice();
-
-            // When panic is cloned, +3.
-            xs.clone();
-        })
-        .join()
-        .unwrap_err();
-
-    // Total = 8
-    assert_eq!(drop_count.load(Ordering::SeqCst), 8);
-}
-
-#[test]
-fn test_copy_from_slice() {
-    let src = [0, 1, 2, 3, 4, 5];
-    let mut dst = [0; 6];
-    dst.copy_from_slice(&src);
-    assert_eq!(src, dst)
-}
-
-#[test]
-#[should_panic(expected = "destination and source slices have different lengths")]
-fn test_copy_from_slice_dst_longer() {
-    let src = [0, 1, 2, 3];
-    let mut dst = [0; 5];
-    dst.copy_from_slice(&src);
-}
-
-#[test]
-#[should_panic(expected = "destination and source slices have different lengths")]
-fn test_copy_from_slice_dst_shorter() {
-    let src = [0, 1, 2, 3];
-    let mut dst = [0; 3];
-    dst.copy_from_slice(&src);
-}
diff --git a/src/libcollectionstest/str.rs b/src/libcollectionstest/str.rs
deleted file mode 100644 (file)
index c9b7104..0000000
+++ /dev/null
@@ -1,1531 +0,0 @@
-// 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::borrow::Cow;
-use std::cmp::Ordering::{Equal, Greater, Less};
-use std::str::from_utf8;
-
-#[test]
-fn test_le() {
-    assert!("" <= "");
-    assert!("" <= "foo");
-    assert!("foo" <= "foo");
-    assert!("foo" != "bar");
-}
-
-#[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 = "";
-    let s: String = empty.chars().collect();
-    assert_eq!(empty, s);
-    let data = "ประเทศไทย中";
-    let s: String = data.chars().collect();
-    assert_eq!(data, s);
-}
-
-#[test]
-fn test_into_bytes() {
-    let data = String::from("asdf");
-    let buf = data.into_bytes();
-    assert_eq!(buf, b"asdf");
-}
-
-#[test]
-fn test_find_str() {
-    // byte positions
-    assert_eq!("".find(""), Some(0));
-    assert!("banana".find("apple pie").is_none());
-
-    let data = "abcabc";
-    assert_eq!(data[0..6].find("ab"), Some(0));
-    assert_eq!(data[2..6].find("ab"), Some(3 - 2));
-    assert!(data[2..4].find("ab").is_none());
-
-    let string = "ประเทศไทย中华Việt Nam";
-    let mut data = String::from(string);
-    data.push_str(string);
-    assert!(data.find("ไท华").is_none());
-    assert_eq!(data[0..43].find(""), Some(0));
-    assert_eq!(data[6..43].find(""), Some(6 - 6));
-
-    assert_eq!(data[0..43].find("ประ"), Some( 0));
-    assert_eq!(data[0..43].find("ทศไ"), Some(12));
-    assert_eq!(data[0..43].find("ย中"), Some(24));
-    assert_eq!(data[0..43].find("iệt"), Some(34));
-    assert_eq!(data[0..43].find("Nam"), Some(40));
-
-    assert_eq!(data[43..86].find("ประ"), Some(43 - 43));
-    assert_eq!(data[43..86].find("ทศไ"), Some(55 - 43));
-    assert_eq!(data[43..86].find("ย中"), Some(67 - 43));
-    assert_eq!(data[43..86].find("iệt"), Some(77 - 43));
-    assert_eq!(data[43..86].find("Nam"), Some(83 - 43));
-
-    // find every substring -- assert that it finds it, or an earlier occurrence.
-    let string = "Việt Namacbaabcaabaaba";
-    for (i, ci) in string.char_indices() {
-        let ip = i + ci.len_utf8();
-        for j in string[ip..].char_indices()
-                             .map(|(i, _)| i)
-                             .chain(Some(string.len() - ip))
-        {
-            let pat = &string[i..ip + j];
-            assert!(match string.find(pat) {
-                None => false,
-                Some(x) => x <= i,
-            });
-            assert!(match string.rfind(pat) {
-                None => false,
-                Some(x) => x >= i,
-            });
-        }
-    }
-}
-
-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]
-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_join {
-    ($expected: expr, $string: expr, $delim: expr) => {
-        {
-            let s = $string.join($delim);
-            assert_eq!($expected, s);
-        }
-    }
-}
-
-#[test]
-fn test_join_for_different_types() {
-    test_join!("a-b", ["a", "b"], "-");
-    let hyphen = "-".to_string();
-    test_join!("a-b", [s("a"), s("b")], &*hyphen);
-    test_join!("a-b", vec!["a", "b"], &*hyphen);
-    test_join!("a-b", &*vec!["a", "b"], "-");
-    test_join!("a-b", vec![s("a"), s("b")], "-");
-}
-
-#[test]
-fn test_join_for_different_lengths() {
-    let empty: &[&str] = &[];
-    test_join!("", empty, "-");
-    test_join!("a", ["a"], "-");
-    test_join!("a-b", ["a", "b"], "-");
-    test_join!("-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_eq!(half_a_million_letter_a(),
-        unsafe { 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_replacen() {
-    assert_eq!("".replacen('a', "b", 5), "");
-    assert_eq!("acaaa".replacen("a", "b", 3), "bcbba");
-    assert_eq!("aaaa".replacen("a", "b", 0), "aaaa");
-
-    let test = "test";
-    assert_eq!(" test test ".replacen(test, "toast", 3), " toast toast ");
-    assert_eq!(" test test ".replacen(test, "toast", 0), " test test ");
-    assert_eq!(" test test ".replacen(test, "", 5), "   ");
-
-    assert_eq!("qwer123zxc789".replacen(char::is_numeric, "", 3), "qwerzxc789");
-}
-
-#[test]
-fn test_replace() {
-    let a = "a";
-    assert_eq!("".replace(a, "b"), "");
-    assert_eq!("a".replace(a, "b"), "b");
-    assert_eq!("ab".replace(a, "b"), "bb");
-    let test = "test";
-    assert_eq!(" test test ".replace(test, "toast"), " toast toast ");
-    assert_eq!(" test test ".replace(test, ""), "   ");
-}
-
-#[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_replace_pattern() {
-    let data = "abcdαβγδabcdαβγδ";
-    assert_eq!(data.replace("dαβ", "😺😺😺"), "abc😺😺😺γδabc😺😺😺γδ");
-    assert_eq!(data.replace('γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
-    assert_eq!(data.replace(&['a', 'γ'] as &[_], "😺😺😺"), "😺😺😺bcdαβ😺😺😺δ😺😺😺bcdαβ😺😺😺δ");
-    assert_eq!(data.replace(|c| c == 'γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
-}
-
-#[test]
-fn test_slice() {
-    assert_eq!("ab", &"abc"[0..2]);
-    assert_eq!("bc", &"abc"[1..3]);
-    assert_eq!("", &"abc"[1..1]);
-    assert_eq!("\u{65e5}", &"\u{65e5}\u{672c}"[0..3]);
-
-    let data = "ประเทศไทย中华";
-    assert_eq!("ป", &data[0..3]);
-    assert_eq!("ร", &data[3..6]);
-    assert_eq!("", &data[3..3]);
-    assert_eq!("华", &data[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_eq!(half_a_million_letter_x(), &letters[0..3 * 500000]);
-}
-
-#[test]
-fn test_slice_2() {
-    let ss = "中华Việt Nam";
-
-    assert_eq!("华", &ss[3..6]);
-    assert_eq!("Việt Nam", &ss[6..16]);
-
-    assert_eq!("ab", &"abc"[0..2]);
-    assert_eq!("bc", &"abc"[1..3]);
-    assert_eq!("", &"abc"[1..1]);
-
-    assert_eq!("中", &ss[0..3]);
-    assert_eq!("华V", &ss[3..7]);
-    assert_eq!("", &ss[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"[0..2];
-}
-
-
-#[test]
-fn test_is_char_boundary() {
-    let s = "ศไทย中华Việt Nam β-release 🐱123";
-    assert!(s.is_char_boundary(0));
-    assert!(s.is_char_boundary(s.len()));
-    assert!(!s.is_char_boundary(s.len() + 1));
-    for (i, ch) in s.char_indices() {
-        // ensure character locations are boundaries and continuation bytes are not
-        assert!(s.is_char_boundary(i), "{} is a char boundary in {:?}", i, s);
-        for j in 1..ch.len_utf8() {
-            assert!(!s.is_char_boundary(i + j),
-                    "{} should not be a char boundary in {:?}", i + j, s);
-        }
-    }
-}
-const LOREM_PARAGRAPH: &'static str = "\
-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.";
-
-// check the panic includes the prefix of the sliced string
-#[test]
-#[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")]
-fn test_slice_fail_truncated_1() {
-    &LOREM_PARAGRAPH[..1024];
-}
-// check the truncation in the panic message
-#[test]
-#[should_panic(expected="luctus, im`[...]")]
-fn test_slice_fail_truncated_2() {
-    &LOREM_PARAGRAPH[..1024];
-}
-
-#[test]
-#[should_panic(expected="byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5) of")]
-fn test_slice_fail_boundary_1() {
-    &"abcαβγ"[4..];
-}
-
-#[test]
-#[should_panic(expected="byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7) of")]
-fn test_slice_fail_boundary_2() {
-    &"abcαβγ"[2..6];
-}
-
-#[test]
-fn test_slice_from() {
-    assert_eq!(&"abcd"[0..], "abcd");
-    assert_eq!(&"abcd"[2..], "cd");
-    assert_eq!(&"abcd"[4..], "");
-}
-#[test]
-fn test_slice_to() {
-    assert_eq!(&"abcd"[..0], "");
-    assert_eq!(&"abcd"[..2], "ab");
-    assert_eq!(&"abcd"[..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_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 from_utf8_mostly_ascii() {
-    // deny invalid bytes embedded in long stretches of ascii
-    for i in 32..64 {
-        let mut data = [0; 128];
-        data[i] = 0xC0;
-        assert!(from_utf8(&data).is_err());
-        data[i] = 0xC2;
-        assert!(from_utf8(&data).is_err());
-    }
-}
-
-#[test]
-fn from_utf8_error() {
-    macro_rules! test {
-        ($input: expr, $expected_valid_up_to: expr, $expected_error_len: expr) => {
-            let error = from_utf8($input).unwrap_err();
-            assert_eq!(error.valid_up_to(), $expected_valid_up_to);
-            assert_eq!(error.error_len(), $expected_error_len);
-        }
-    }
-    test!(b"A\xC3\xA9 \xFF ", 4, Some(1));
-    test!(b"A\xC3\xA9 \x80 ", 4, Some(1));
-    test!(b"A\xC3\xA9 \xC1 ", 4, Some(1));
-    test!(b"A\xC3\xA9 \xC1", 4, Some(1));
-    test!(b"A\xC3\xA9 \xC2", 4, None);
-    test!(b"A\xC3\xA9 \xC2 ", 4, Some(1));
-    test!(b"A\xC3\xA9 \xC2\xC0", 4, Some(1));
-    test!(b"A\xC3\xA9 \xE0", 4, None);
-    test!(b"A\xC3\xA9 \xE0\x9F", 4, Some(1));
-    test!(b"A\xC3\xA9 \xE0\xA0", 4, None);
-    test!(b"A\xC3\xA9 \xE0\xA0\xC0", 4, Some(2));
-    test!(b"A\xC3\xA9 \xE0\xA0 ", 4, Some(2));
-    test!(b"A\xC3\xA9 \xED\xA0\x80 ", 4, Some(1));
-    test!(b"A\xC3\xA9 \xF1", 4, None);
-    test!(b"A\xC3\xA9 \xF1\x80", 4, None);
-    test!(b"A\xC3\xA9 \xF1\x80\x80", 4, None);
-    test!(b"A\xC3\xA9 \xF1 ", 4, Some(1));
-    test!(b"A\xC3\xA9 \xF1\x80 ", 4, Some(2));
-    test!(b"A\xC3\xA9 \xF1\x80\x80 ", 4, Some(3));
-}
-
-#[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("");
-    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 vec_str_conversions() {
-    let s1: String = String::from("All mimsy were the borogoves");
-
-    let v: Vec<u8> = s1.as_bytes().to_vec();
-    let s2: String = String::from(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];
-        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('b'));
-    assert!("a".contains('a'));
-    assert!(!"abc".contains('d'));
-    assert!(!"".contains('a'));
-}
-
-#[test]
-fn test_split_at() {
-    let s = "ศไทย中华Việt Nam";
-    for (index, _) in s.char_indices() {
-        let (a, b) = s.split_at(index);
-        assert_eq!(&s[..a.len()], a);
-        assert_eq!(&s[a.len()..], b);
-    }
-    let (a, b) = s.split_at(s.len());
-    assert_eq!(a, s);
-    assert_eq!(b, "");
-}
-
-#[test]
-fn test_split_at_mut() {
-    use std::ascii::AsciiExt;
-    let mut s = "Hello World".to_string();
-    {
-        let (a, b) = s.split_at_mut(5);
-        a.make_ascii_uppercase();
-        b.make_ascii_lowercase();
-    }
-    assert_eq!(s, "HELLO world");
-}
-
-#[test]
-#[should_panic]
-fn test_split_at_boundscheck() {
-    let s = "ศไทย中华Việt Nam";
-    s.split_at(1);
-}
-
-#[test]
-fn test_escape_unicode() {
-    assert_eq!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}");
-    assert_eq!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}");
-    assert_eq!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}");
-    assert_eq!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}");
-    assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
-    assert_eq!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}");
-    assert_eq!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}");
-    assert_eq!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}");
-    assert_eq!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}");
-}
-
-#[test]
-fn test_escape_debug() {
-    assert_eq!("abc".escape_debug(), "abc");
-    assert_eq!("a c".escape_debug(), "a c");
-    assert_eq!("éèê".escape_debug(), "éèê");
-    assert_eq!("\r\n\t".escape_debug(), "\\r\\n\\t");
-    assert_eq!("'\"\\".escape_debug(), "\\'\\\"\\\\");
-    assert_eq!("\u{7f}\u{ff}".escape_debug(), "\\u{7f}\u{ff}");
-    assert_eq!("\u{100}\u{ffff}".escape_debug(), "\u{100}\\u{ffff}");
-    assert_eq!("\u{10000}\u{10ffff}".escape_debug(), "\u{10000}\\u{10ffff}");
-    assert_eq!("ab\u{200b}".escape_debug(), "ab\\u{200b}");
-    assert_eq!("\u{10d4ea}\r".escape_debug(), "\\u{10d4ea}\\r");
-}
-
-#[test]
-fn test_escape_default() {
-    assert_eq!("abc".escape_default(), "abc");
-    assert_eq!("a c".escape_default(), "a c");
-    assert_eq!("éèê".escape_default(), "\\u{e9}\\u{e8}\\u{ea}");
-    assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t");
-    assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\");
-    assert_eq!("\u{7f}\u{ff}".escape_default(), "\\u{7f}\\u{ff}");
-    assert_eq!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
-    assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
-    assert_eq!("ab\u{200b}".escape_default(), "ab\\u{200b}");
-    assert_eq!("\u{10d4ea}\r".escape_default(), "\\u{10d4ea}\\r");
-}
-
-#[test]
-fn test_total_ord() {
-    assert_eq!("1234".cmp("123"), Greater);
-    assert_eq!("123".cmp("1234"), Less);
-    assert_eq!("1234".cmp("1234"), Equal);
-    assert_eq!("12345555".cmp("123456"), Less);
-    assert_eq!("22".cmp("1234"), Greater);
-}
-
-#[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());
-    assert_eq!(s.chars().count(), 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 s = c.encode_utf8(&mut bytes);
-        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 s = c.encode_utf8(&mut bytes);
-        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_iterator_last() {
-    let s = "ศไทย中华Việt Nam";
-    let mut it = s.chars();
-    it.next();
-    assert_eq!(it.last(), Some('m'));
-}
-
-#[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_bytesator_nth() {
-    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 b = s.bytes();
-    assert_eq!(b.nth(2).unwrap(), v[2]);
-    assert_eq!(b.nth(10).unwrap(), v[10]);
-    assert_eq!(b.nth(200), None);
-}
-
-#[test]
-fn test_bytesator_count() {
-    let s = "ศไทย中华Việt Nam";
-
-    let b = s.bytes();
-    assert_eq!(b.count(), 28)
-}
-
-#[test]
-fn test_bytesator_last() {
-    let s = "ศไทย中华Việt Nam";
-
-    let b = s.bytes();
-    assert_eq!(b.last().unwrap(), 109)
-}
-
-#[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_char_indices_last() {
-    let s = "ศไทย中华Việt Nam";
-    let mut it = s.char_indices();
-    it.next();
-    assert_eq!(it.last(), Some((27, 'm')));
-}
-
-#[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(4, ' ').collect();
-    assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
-
-    let split: Vec<&str> = data.splitn(4, |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(4, 'ä').collect();
-    assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
-
-    let split: Vec<&str> = data.splitn(4, |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_rsplit() {
-    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
-    let split: Vec<&str> = data.rsplit(' ').collect();
-    assert_eq!(split, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
-
-    let split: Vec<&str> = data.rsplit("lämb").collect();
-    assert_eq!(split, ["\n", "\nLittle ", "\nMäry häd ä little "]);
-
-    let split: Vec<&str> = data.rsplit(|c: char| c == 'ä').collect();
-    assert_eq!(split, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
-}
-
-#[test]
-fn test_rsplitn() {
-    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
-    let split: Vec<&str> = data.rsplitn(2, ' ').collect();
-    assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
-
-    let split: Vec<&str> = data.rsplitn(2, "lämb").collect();
-    assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]);
-
-    let split: Vec<&str> = data.rsplitn(2, |c: char| c == 'ä').collect();
-    assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
-}
-
-#[test]
-fn test_split_whitespace() {
-    let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
-    let words: Vec<&str> = data.split_whitespace().collect();
-    assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
-}
-
-#[test]
-fn test_lines() {
-    let data = "\nMäry häd ä little lämb\n\r\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 = "\r\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_splitator() {
-    fn t(s: &str, sep: &str, u: &[&str]) {
-        let v: Vec<&str> = s.split(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 + AsRef<str>>() {
-        let s: S = Default::default();
-        assert_eq!(s.as_ref(), "");
-    }
-
-    t::<&str>();
-    t::<String>();
-}
-
-#[test]
-fn test_str_container() {
-    fn sum_len(v: &[&str]) -> usize {
-        v.iter().map(|x| x.len()).sum()
-    }
-
-    let s = "01234";
-    assert_eq!(5, sum_len(&["012", "", "34"]));
-    assert_eq!(5, sum_len(&["01", "2", "34", ""]));
-    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!(from_utf8(xs).is_err());
-}
-
-#[test]
-fn test_pattern_deref_forward() {
-    let data = "aabcdaa";
-    assert!(data.contains("bcd"));
-    assert!(data.contains(&"bcd"));
-    assert!(data.contains(&"bcd".to_string()));
-}
-
-#[test]
-fn test_empty_match_indices() {
-    let data = "aä中!";
-    let vec: Vec<_> = data.match_indices("").collect();
-    assert_eq!(vec, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
-}
-
-#[test]
-fn test_bool_from_str() {
-    assert_eq!("true".parse().ok(), Some(true));
-    assert_eq!("false".parse().ok(), Some(false));
-    assert_eq!("not even a boolean".parse::<bool>().ok(), None);
-}
-
-fn check_contains_all_substrings(s: &str) {
-    assert!(s.contains(""));
-    for i in 0..s.len() {
-        for j in i+1..s.len() + 1 {
-            assert!(s.contains(&s[i..j]));
-        }
-    }
-}
-
-#[test]
-fn strslice_issue_16589() {
-    assert!("bananas".contains("nana"));
-
-    // prior to the fix for #16589, x.contains("abcdabcd") returned false
-    // test all substrings for good measure
-    check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
-}
-
-#[test]
-fn strslice_issue_16878() {
-    assert!(!"1234567ah012345678901ah".contains("hah"));
-    assert!(!"00abc01234567890123456789abc".contains("bcabc"));
-}
-
-
-#[test]
-fn test_strslice_contains() {
-    let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
-    check_contains_all_substrings(x);
-}
-
-#[test]
-fn test_rsplitn_char_iterator() {
-    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
-    let mut split: Vec<&str> = data.rsplitn(4, ' ').collect();
-    split.reverse();
-    assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
-
-    let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == ' ').collect();
-    split.reverse();
-    assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
-
-    // Unicode
-    let mut split: Vec<&str> = data.rsplitn(4, 'ä').collect();
-    split.reverse();
-    assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
-
-    let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == 'ä').collect();
-    split.reverse();
-    assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
-}
-
-#[test]
-fn test_split_char_iterator() {
-    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
-    let split: Vec<&str> = data.split(' ').collect();
-    assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
-
-    let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
-    rsplit.reverse();
-    assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
-
-    let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
-    assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
-
-    let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
-    rsplit.reverse();
-    assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
-
-    // Unicode
-    let split: Vec<&str> = data.split('ä').collect();
-    assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
-
-    let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
-    rsplit.reverse();
-    assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
-
-    let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
-    assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
-
-    let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
-    rsplit.reverse();
-    assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
-}
-
-#[test]
-fn test_rev_split_char_iterator_no_trailing() {
-    let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
-    let mut split: Vec<&str> = data.split('\n').rev().collect();
-    split.reverse();
-    assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
-
-    let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
-    split.reverse();
-    assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
-}
-
-#[test]
-fn test_utf16_code_units() {
-    use std_unicode::str::Utf16Encoder;
-    assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::<Vec<u16>>(),
-               [0xE9, 0xD83D, 0xDCA9])
-}
-
-#[test]
-fn starts_with_in_unicode() {
-    assert!(!"├── Cargo.toml".starts_with("# "));
-}
-
-#[test]
-fn starts_short_long() {
-    assert!(!"".starts_with("##"));
-    assert!(!"##".starts_with("####"));
-    assert!("####".starts_with("##"));
-    assert!(!"##ä".starts_with("####"));
-    assert!("####ä".starts_with("##"));
-    assert!(!"##".starts_with("####ä"));
-    assert!("##ä##".starts_with("##ä"));
-
-    assert!("".starts_with(""));
-    assert!("ä".starts_with(""));
-    assert!("#ä".starts_with(""));
-    assert!("##ä".starts_with(""));
-    assert!("ä###".starts_with(""));
-    assert!("#ä##".starts_with(""));
-    assert!("##ä#".starts_with(""));
-}
-
-#[test]
-fn contains_weird_cases() {
-    assert!("* \t".contains(' '));
-    assert!(!"* \t".contains('?'));
-    assert!(!"* \t".contains('\u{1F4A9}'));
-}
-
-#[test]
-fn trim_ws() {
-    assert_eq!(" \t  a \t  ".trim_left_matches(|c: char| c.is_whitespace()),
-                    "a \t  ");
-    assert_eq!(" \t  a \t  ".trim_right_matches(|c: char| c.is_whitespace()),
-               " \t  a");
-    assert_eq!(" \t  a \t  ".trim_matches(|c: char| c.is_whitespace()),
-                    "a");
-    assert_eq!(" \t   \t  ".trim_left_matches(|c: char| c.is_whitespace()),
-                         "");
-    assert_eq!(" \t   \t  ".trim_right_matches(|c: char| c.is_whitespace()),
-               "");
-    assert_eq!(" \t   \t  ".trim_matches(|c: char| c.is_whitespace()),
-               "");
-}
-
-#[test]
-fn to_lowercase() {
-    assert_eq!("".to_lowercase(), "");
-    assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé ");
-
-    // https://github.com/rust-lang/rust/issues/26035
-    assert_eq!("ΑΣ".to_lowercase(), "ας");
-    assert_eq!("Α'Σ".to_lowercase(), "α'ς");
-    assert_eq!("Α''Σ".to_lowercase(), "α''ς");
-
-    assert_eq!("ΑΣ Α".to_lowercase(), "ας α");
-    assert_eq!("Α'Σ Α".to_lowercase(), "α'ς α");
-    assert_eq!("Α''Σ Α".to_lowercase(), "α''ς α");
-
-    assert_eq!("ΑΣ' Α".to_lowercase(), "ας' α");
-    assert_eq!("ΑΣ'' Α".to_lowercase(), "ας'' α");
-
-    assert_eq!("Α'Σ' Α".to_lowercase(), "α'ς' α");
-    assert_eq!("Α''Σ'' Α".to_lowercase(), "α''ς'' α");
-
-    assert_eq!("Α Σ".to_lowercase(), "α σ");
-    assert_eq!("Α 'Σ".to_lowercase(), "α 'σ");
-    assert_eq!("Α ''Σ".to_lowercase(), "α ''σ");
-
-    assert_eq!("Σ".to_lowercase(), "σ");
-    assert_eq!("'Σ".to_lowercase(), "'σ");
-    assert_eq!("''Σ".to_lowercase(), "''σ");
-
-    assert_eq!("ΑΣΑ".to_lowercase(), "ασα");
-    assert_eq!("ΑΣ'Α".to_lowercase(), "ασ'α");
-    assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α");
-}
-
-#[test]
-fn to_uppercase() {
-    assert_eq!("".to_uppercase(), "");
-    assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
-}
-
-#[test]
-fn test_into_string() {
-    // The only way to acquire a Box<str> in the first place is through a String, so just
-    // test that we can round-trip between Box<str> and String.
-    let string = String::from("Some text goes here");
-    assert_eq!(string.clone().into_boxed_str().into_string(), string);
-}
-
-#[test]
-fn test_box_slice_clone() {
-    let data = String::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
-    let data2 = data.clone().into_boxed_str().clone().into_string();
-
-    assert_eq!(data, data2);
-}
-
-#[test]
-fn test_cow_from() {
-    let borrowed = "borrowed";
-    let owned = String::from("owned");
-    match (Cow::from(owned.clone()), Cow::from(borrowed)) {
-        (Cow::Owned(o), Cow::Borrowed(b)) => assert!(o == owned && b == borrowed),
-        _ => panic!("invalid `Cow::from`"),
-    }
-}
-
-#[test]
-fn test_repeat() {
-    assert_eq!("".repeat(3), "");
-    assert_eq!("abc".repeat(0), "");
-    assert_eq!("α".repeat(3), "ααα");
-}
-
-mod pattern {
-    use std::str::pattern::Pattern;
-    use std::str::pattern::{Searcher, ReverseSearcher};
-    use std::str::pattern::SearchStep::{self, Match, Reject, Done};
-
-    macro_rules! make_test {
-        ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => {
-            #[allow(unused_imports)]
-            mod $name {
-                use std::str::pattern::SearchStep::{Match, Reject};
-                use super::{cmp_search_to_vec};
-                #[test]
-                fn fwd() {
-                    cmp_search_to_vec(false, $p, $h, vec![$($e),*]);
-                }
-                #[test]
-                fn bwd() {
-                    cmp_search_to_vec(true, $p, $h, vec![$($e),*]);
-                }
-            }
-        }
-    }
-
-    fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str,
-                                             right: Vec<SearchStep>)
-    where P::Searcher: ReverseSearcher<'a>
-    {
-        let mut searcher = pat.into_searcher(haystack);
-        let mut v = vec![];
-        loop {
-            match if !rev {searcher.next()} else {searcher.next_back()} {
-                Match(a, b) => v.push(Match(a, b)),
-                Reject(a, b) => v.push(Reject(a, b)),
-                Done => break,
-            }
-        }
-        if rev {
-            v.reverse();
-        }
-
-        let mut first_index = 0;
-        let mut err = None;
-
-        for (i, e) in right.iter().enumerate() {
-            match *e {
-                Match(a, b) | Reject(a, b)
-                if a <= b && a == first_index => {
-                    first_index = b;
-                }
-                _ => {
-                    err = Some(i);
-                    break;
-                }
-            }
-        }
-
-        if let Some(err) = err {
-            panic!("Input skipped range at {}", err);
-        }
-
-        if first_index != haystack.len() {
-            panic!("Did not cover whole input");
-        }
-
-        assert_eq!(v, right);
-    }
-
-    make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [
-        Reject(0, 1),
-        Match (1, 3),
-        Reject(3, 4),
-        Match (4, 6),
-        Reject(6, 7),
-    ]);
-    make_test!(str_searcher_ascii_haystack_seq, "bb", "abbcbbbbd", [
-        Reject(0, 1),
-        Match (1, 3),
-        Reject(3, 4),
-        Match (4, 6),
-        Match (6, 8),
-        Reject(8, 9),
-    ]);
-    make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [
-        Match (0, 0),
-        Reject(0, 1),
-        Match (1, 1),
-        Reject(1, 2),
-        Match (2, 2),
-        Reject(2, 3),
-        Match (3, 3),
-        Reject(3, 4),
-        Match (4, 4),
-        Reject(4, 5),
-        Match (5, 5),
-        Reject(5, 6),
-        Match (6, 6),
-        Reject(6, 7),
-        Match (7, 7),
-    ]);
-    make_test!(str_searcher_mulibyte_haystack, " ", "├──", [
-        Reject(0, 3),
-        Reject(3, 6),
-        Reject(6, 9),
-    ]);
-    make_test!(str_searcher_empty_needle_mulibyte_haystack, "", "├──", [
-        Match (0, 0),
-        Reject(0, 3),
-        Match (3, 3),
-        Reject(3, 6),
-        Match (6, 6),
-        Reject(6, 9),
-        Match (9, 9),
-    ]);
-    make_test!(str_searcher_empty_needle_empty_haystack, "", "", [
-        Match(0, 0),
-    ]);
-    make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", [
-    ]);
-    make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [
-        Reject(0, 1),
-        Match (1, 2),
-        Match (2, 3),
-        Reject(3, 4),
-        Match (4, 5),
-        Match (5, 6),
-        Reject(6, 7),
-    ]);
-    make_test!(char_searcher_mulibyte_haystack, ' ', "├──", [
-        Reject(0, 3),
-        Reject(3, 6),
-        Reject(6, 9),
-    ]);
-    make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [
-        Reject(0, 1),
-        Reject(1, 2),
-        Reject(2, 3),
-    ]);
-
-}
-
-macro_rules! generate_iterator_test {
-    {
-        $name:ident {
-            $(
-                ($($arg:expr),*) -> [$($t:tt)*];
-            )*
-        }
-        with $fwd:expr, $bwd:expr;
-    } => {
-        #[test]
-        fn $name() {
-            $(
-                {
-                    let res = vec![$($t)*];
-
-                    let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
-                    assert_eq!(fwd_vec, res);
-
-                    let mut bwd_vec: Vec<_> = ($bwd)($($arg),*).collect();
-                    bwd_vec.reverse();
-                    assert_eq!(bwd_vec, res);
-                }
-            )*
-        }
-    };
-    {
-        $name:ident {
-            $(
-                ($($arg:expr),*) -> [$($t:tt)*];
-            )*
-        }
-        with $fwd:expr;
-    } => {
-        #[test]
-        fn $name() {
-            $(
-                {
-                    let res = vec![$($t)*];
-
-                    let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
-                    assert_eq!(fwd_vec, res);
-                }
-            )*
-        }
-    }
-}
-
-generate_iterator_test! {
-    double_ended_split {
-        ("foo.bar.baz", '.') -> ["foo", "bar", "baz"];
-        ("foo::bar::baz", "::") -> ["foo", "bar", "baz"];
-    }
-    with str::split, str::rsplit;
-}
-
-generate_iterator_test! {
-    double_ended_split_terminator {
-        ("foo;bar;baz;", ';') -> ["foo", "bar", "baz"];
-    }
-    with str::split_terminator, str::rsplit_terminator;
-}
-
-generate_iterator_test! {
-    double_ended_matches {
-        ("a1b2c3", char::is_numeric) -> ["1", "2", "3"];
-    }
-    with str::matches, str::rmatches;
-}
-
-generate_iterator_test! {
-    double_ended_match_indices {
-        ("a1b2c3", char::is_numeric) -> [(1, "1"), (3, "2"), (5, "3")];
-    }
-    with str::match_indices, str::rmatch_indices;
-}
-
-generate_iterator_test! {
-    not_double_ended_splitn {
-        ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"];
-    }
-    with str::splitn;
-}
-
-generate_iterator_test! {
-    not_double_ended_rsplitn {
-        ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"];
-    }
-    with str::rsplitn;
-}
-
-#[test]
-fn different_str_pattern_forwarding_lifetimes() {
-    use std::str::pattern::Pattern;
-
-    fn foo<'a, P>(p: P) where for<'b> &'b P: Pattern<'a> {
-        for _ in 0..3 {
-            "asdf".find(&p);
-        }
-    }
-
-    foo::<&str>("x");
-}
diff --git a/src/libcollectionstest/string.rs b/src/libcollectionstest/string.rs
deleted file mode 100644 (file)
index 2f021b9..0000000
+++ /dev/null
@@ -1,435 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::borrow::Cow;
-
-pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
-    fn into_cow(self) -> Cow<'a, B>;
-}
-
-impl<'a> IntoCow<'a, str> for String {
-    fn into_cow(self) -> Cow<'a, str> {
-        Cow::Owned(self)
-    }
-}
-
-impl<'a> IntoCow<'a, str> for &'a str {
-    fn into_cow(self) -> Cow<'a, str> {
-        Cow::Borrowed(self)
-    }
-}
-
-#[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_from_cow_str() {
-    assert_eq!(String::from(Cow::Borrowed("string")), "string");
-    assert_eq!(String::from(Cow::Owned(String::from("string"))), "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("hello"));
-
-    let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
-    assert_eq!(String::from_utf8(xs).unwrap(),
-               String::from("ศไทย中华Việt Nam"));
-
-    let xs = b"hello\xFF".to_vec();
-    let err = String::from_utf8(xs).unwrap_err();
-    assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
-}
-
-#[test]
-fn test_from_utf8_lossy() {
-    let xs = b"hello";
-    let ys: Cow<str> = "hello".into_cow();
-    assert_eq!(String::from_utf8_lossy(xs), ys);
-
-    let xs = "ศไทย中华Việt Nam".as_bytes();
-    let ys: Cow<str> = "ศไทย中华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("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("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("\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("\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("\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("\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("\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("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
-                  vec![0xd800, 0xdf45, 0xd800, 0xdf3f, 0xd800, 0xdf3b, 0xd800, 0xdf46, 0xd800,
-                       0xdf39, 0xd800, 0xdf3b, 0xd800, 0xdf30, 0x000a]),
-
-                 (String::from("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
-                  vec![0xd801, 0xdc12, 0xd801, 0xdc49, 0xd801, 0xdc2e, 0xd801, 0xdc40, 0xd801,
-                       0xdc32, 0xd801, 0xdc4b, 0x0020, 0xd801, 0xdc0f, 0xd801, 0xdc32, 0xd801,
-                       0xdc4d, 0x000a]),
-
-                 (String::from("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\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("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\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("\u{20000}"), vec![0xD840, 0xDC00])];
-
-    for p in &pairs {
-        let (s, u) = (*p).clone();
-        let s_as_utf16 = s.encode_utf16().collect::<Vec<u16>>();
-        let u_as_string = String::from_utf16(&u).unwrap();
-
-        assert!(::std_unicode::char::decode_utf16(u.iter().cloned()).all(|r| r.is_ok()));
-        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.encode_utf16().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("\u{FFFD}"));
-    // lead + lead
-    assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]),
-               String::from("\u{FFFD}\u{FFFD}"));
-
-    // isolated trail
-    assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]),
-               String::from("a\u{FFFD}"));
-
-    // general
-    assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
-               String::from("\u{FFFD}𐒋\u{FFFD}"));
-}
-
-#[test]
-fn test_push_bytes() {
-    let mut s = String::from("ABC");
-    unsafe {
-        let mv = s.as_mut_vec();
-        mv.extend_from_slice(&[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_add_assign() {
-    let mut s = String::new();
-    s += "";
-    assert_eq!(s.as_str(), "");
-    s += "abc";
-    assert_eq!(s.as_str(), "abc");
-    s += "ประเทศไทย中华Việt Nam";
-    assert_eq!(s.as_str(), "abcประเทศไทย中华Việt Nam");
-}
-
-#[test]
-fn test_push() {
-    let mut data = String::from("ประเทศไทย中");
-    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("ประเทศไทย中华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_split_off_empty() {
-    let orig = "Hello, world!";
-    let mut split = String::from(orig);
-    let empty: String = split.split_off(orig.len());
-    assert!(empty.is_empty());
-}
-
-#[test]
-#[should_panic]
-fn test_split_off_past_end() {
-    let orig = "Hello, world!";
-    let mut split = String::from(orig);
-    split.split_off(orig.len() + 1);
-}
-
-#[test]
-#[should_panic]
-fn test_split_off_mid_char() {
-    let mut orig = String::from("山");
-    orig.split_off(1);
-}
-
-#[test]
-fn test_split_off_ascii() {
-    let mut ab = String::from("ABCD");
-    let cd = ab.split_off(2);
-    assert_eq!(ab, "AB");
-    assert_eq!(cd, "CD");
-}
-
-#[test]
-fn test_split_off_unicode() {
-    let mut nihon = String::from("日本語");
-    let go = nihon.split_off("日本".len());
-    assert_eq!(nihon, "日本");
-    assert_eq!(go, "語");
-}
-
-#[test]
-fn test_str_truncate() {
-    let mut s = String::from("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("12345");
-    let p = s.as_ptr();
-    s.truncate(3);
-    s.push_str("6");
-    let p_ = s.as_ptr();
-    assert_eq!(p_, p);
-}
-
-#[test]
-fn test_str_truncate_invalid_len() {
-    let mut s = String::from("12345");
-    s.truncate(6);
-    assert_eq!(s, "12345");
-}
-
-#[test]
-#[should_panic]
-fn test_str_truncate_split_codepoint() {
-    let mut s = String::from("\u{FC}"); // ü
-    s.truncate(1);
-}
-
-#[test]
-fn test_str_clear() {
-    let mut s = String::from("12345");
-    s.clear();
-    assert_eq!(s.len(), 0);
-    assert_eq!(s, "");
-}
-
-#[test]
-fn test_str_add() {
-    let a = String::from("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]);
-    assert_eq!(s, d);
-}
-
-#[test]
-fn test_drain() {
-    let mut s = String::from("αβγ");
-    assert_eq!(s.drain(2..4).collect::<String>(), "β");
-    assert_eq!(s, "αγ");
-
-    let mut t = String::from("abcd");
-    t.drain(..0);
-    assert_eq!(t, "abcd");
-    t.drain(..1);
-    assert_eq!(t, "bcd");
-    t.drain(3..);
-    assert_eq!(t, "bcd");
-    t.drain(..);
-    assert_eq!(t, "");
-}
-
-#[test]
-fn test_extend_ref() {
-    let mut a = "foo".to_string();
-    a.extend(&['b', 'a', 'r']);
-
-    assert_eq!(&a, "foobar");
-}
-
-#[test]
-fn test_into_boxed_str() {
-    let xs = String::from("hello my name is bob");
-    let ys = xs.into_boxed_str();
-    assert_eq!(&*ys, "hello my name is bob");
-}
diff --git a/src/libcollectionstest/vec.rs b/src/libcollectionstest/vec.rs
deleted file mode 100644 (file)
index 63df0eb..0000000
+++ /dev/null
@@ -1,698 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::ascii::AsciiExt;
-use std::borrow::Cow;
-use std::mem::size_of;
-use std::panic;
-use std::vec::{Drain, IntoIter};
-
-struct DropCounter<'a> {
-    count: &'a mut u32,
-}
-
-impl<'a> Drop for DropCounter<'a> {
-    fn drop(&mut self) {
-        *self.count += 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);
-
-    v.extend(w.clone()); // specializes to `append`
-    assert!(v.iter().eq(w.iter().chain(w.iter())));
-}
-
-#[test]
-fn test_extend_ref() {
-    let mut v = vec![1, 2];
-    v.extend(&[3, 4, 5]);
-
-    assert_eq!(v.len(), 5);
-    assert_eq!(v, [1, 2, 3, 4, 5]);
-
-    let w = vec![6, 7];
-    v.extend(&w);
-
-    assert_eq!(v.len(), 7);
-    assert_eq!(v, [1, 2, 3, 4, 5, 6, 7]);
-}
-
-#[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 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_by_key() {
-    fn case(a: Vec<i32>, b: Vec<i32>) {
-        let mut v = a;
-        v.dedup_by_key(|i| *i / 10);
-        assert_eq!(v, b);
-    }
-    case(vec![], vec![]);
-    case(vec![10], vec![10]);
-    case(vec![10, 11], vec![10]);
-    case(vec![10, 20, 30], vec![10, 20, 30]);
-    case(vec![10, 11, 20, 30], vec![10, 20, 30]);
-    case(vec![10, 20, 21, 30], vec![10, 20, 30]);
-    case(vec![10, 20, 30, 31], vec![10, 20, 30]);
-    case(vec![10, 11, 20, 21, 22, 30, 31], vec![10, 20, 30]);
-}
-
-#[test]
-fn test_dedup_by() {
-    let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
-    vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
-
-    assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
-}
-
-#[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 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_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[!0..];
-}
-
-#[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[!0..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_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]
-#[should_panic]
-fn test_drain_out_of_bounds() {
-    let mut v = vec![1, 2, 3, 4, 5];
-    v.drain(5..6);
-}
-
-#[test]
-fn test_drain_range() {
-    let mut v = vec![1, 2, 3, 4, 5];
-    for _ in v.drain(4..) {
-    }
-    assert_eq!(v, &[1, 2, 3, 4]);
-
-    let mut v: Vec<_> = (1..6).map(|x| x.to_string()).collect();
-    for _ in v.drain(1..4) {
-    }
-    assert_eq!(v, &[1.to_string(), 5.to_string()]);
-
-    let mut v: Vec<_> = (1..6).map(|x| x.to_string()).collect();
-    for _ in v.drain(1..4).rev() {
-    }
-    assert_eq!(v, &[1.to_string(), 5.to_string()]);
-
-    let mut v: Vec<_> = vec![(); 5];
-    for _ in v.drain(1..4).rev() {
-    }
-    assert_eq!(v, &[(), ()]);
-}
-
-#[test]
-fn test_drain_inclusive_range() {
-    let mut v = vec!['a', 'b', 'c', 'd', 'e'];
-    for _ in v.drain(1...3) {
-    }
-    assert_eq!(v, &['a', 'e']);
-
-    let mut v: Vec<_> = (0...5).map(|x| x.to_string()).collect();
-    for _ in v.drain(1...5) {
-    }
-    assert_eq!(v, &["0".to_string()]);
-
-    let mut v: Vec<String> = (0...5).map(|x| x.to_string()).collect();
-    for _ in v.drain(0...5) {
-    }
-    assert_eq!(v, Vec::<String>::new());
-
-    let mut v: Vec<_> = (0...5).map(|x| x.to_string()).collect();
-    for _ in v.drain(0...3) {
-    }
-    assert_eq!(v, &["4".to_string(), "5".to_string()]);
-
-    let mut v: Vec<_> = (0...1).map(|x| x.to_string()).collect();
-    for _ in v.drain(...0) {
-    }
-    assert_eq!(v, &["1".to_string()]);
-}
-
-#[test]
-fn test_drain_max_vec_size() {
-    let mut v = Vec::<()>::with_capacity(usize::max_value());
-    unsafe { v.set_len(usize::max_value()); }
-    for _ in v.drain(usize::max_value() - 1..) {
-    }
-    assert_eq!(v.len(), usize::max_value() - 1);
-
-    let mut v = Vec::<()>::with_capacity(usize::max_value());
-    unsafe { v.set_len(usize::max_value()); }
-    for _ in v.drain(usize::max_value() - 1...usize::max_value() - 1) {
-    }
-    assert_eq!(v.len(), usize::max_value() - 1);
-}
-
-#[test]
-#[should_panic]
-fn test_drain_inclusive_out_of_bounds() {
-    let mut v = vec![1, 2, 3, 4, 5];
-    v.drain(5...5);
-}
-
-#[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]);
-}
-
-#[test]
-fn test_into_iter_as_slice() {
-    let vec = vec!['a', 'b', 'c'];
-    let mut into_iter = vec.into_iter();
-    assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
-    let _ = into_iter.next().unwrap();
-    assert_eq!(into_iter.as_slice(), &['b', 'c']);
-    let _ = into_iter.next().unwrap();
-    let _ = into_iter.next().unwrap();
-    assert_eq!(into_iter.as_slice(), &[]);
-}
-
-#[test]
-fn test_into_iter_as_mut_slice() {
-    let vec = vec!['a', 'b', 'c'];
-    let mut into_iter = vec.into_iter();
-    assert_eq!(into_iter.as_slice(), &['a', 'b', 'c']);
-    into_iter.as_mut_slice()[0] = 'x';
-    into_iter.as_mut_slice()[1] = 'y';
-    assert_eq!(into_iter.next().unwrap(), 'x');
-    assert_eq!(into_iter.as_slice(), &['y', 'c']);
-}
-
-#[test]
-fn test_into_iter_debug() {
-    let vec = vec!['a', 'b', 'c'];
-    let into_iter = vec.into_iter();
-    let debug = format!("{:?}", into_iter);
-    assert_eq!(debug, "IntoIter(['a', 'b', 'c'])");
-}
-
-#[test]
-fn test_into_iter_count() {
-    assert_eq!(vec![1, 2, 3].into_iter().count(), 3);
-}
-
-#[test]
-fn test_into_iter_clone() {
-    fn iter_equal<I: Iterator<Item = i32>>(it: I, slice: &[i32]) {
-        let v: Vec<i32> = it.collect();
-        assert_eq!(&v[..], slice);
-    }
-    let mut it = vec![1, 2, 3].into_iter();
-    iter_equal(it.clone(), &[1, 2, 3]);
-    assert_eq!(it.next(), Some(1));
-    let mut it = it.rev();
-    iter_equal(it.clone(), &[3, 2]);
-    assert_eq!(it.next(), Some(3));
-    iter_equal(it.clone(), &[2]);
-    assert_eq!(it.next(), Some(2));
-    iter_equal(it.clone(), &[]);
-    assert_eq!(it.next(), None);
-}
-
-#[test]
-fn test_cow_from() {
-    let borrowed: &[_] = &["borrowed", "(slice)"];
-    let owned = vec!["owned", "(vec)"];
-    match (Cow::from(owned.clone()), Cow::from(borrowed)) {
-        (Cow::Owned(o), Cow::Borrowed(b)) => assert!(o == owned && b == borrowed),
-        _ => panic!("invalid `Cow::from`"),
-    }
-}
-
-#[test]
-fn test_from_cow() {
-    let borrowed: &[_] = &["borrowed", "(slice)"];
-    let owned = vec!["owned", "(vec)"];
-    assert_eq!(Vec::from(Cow::Borrowed(borrowed)), vec!["borrowed", "(slice)"]);
-    assert_eq!(Vec::from(Cow::Owned(owned)), vec!["owned", "(vec)"]);
-}
-
-#[allow(dead_code)]
-fn assert_covariance() {
-    fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
-        d
-    }
-    fn into_iter<'new>(i: IntoIter<&'static str>) -> IntoIter<&'new str> {
-        i
-    }
-}
-
-#[test]
-fn test_placement() {
-    let mut vec = vec![1];
-    assert_eq!(vec.place_back() <- 2, &2);
-    assert_eq!(vec.len(), 2);
-    assert_eq!(vec.place_back() <- 3, &3);
-    assert_eq!(vec.len(), 3);
-    assert_eq!(&vec, &[1, 2, 3]);
-}
-
-#[test]
-fn test_placement_panic() {
-    let mut vec = vec![1, 2, 3];
-    fn mkpanic() -> usize { panic!() }
-    let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { vec.place_back() <- mkpanic(); }));
-    assert_eq!(vec.len(), 3);
-}
-
-#[test]
-fn from_into_inner() {
-    let vec = vec![1, 2, 3];
-    let ptr = vec.as_ptr();
-    let vec = vec.into_iter().collect::<Vec<_>>();
-    assert_eq!(vec, [1, 2, 3]);
-    assert_eq!(vec.as_ptr(), ptr);
-
-    let ptr = &vec[1] as *const _;
-    let mut it = vec.into_iter();
-    it.next().unwrap();
-    let vec = it.collect::<Vec<_>>();
-    assert_eq!(vec, [2, 3]);
-    assert!(ptr != vec.as_ptr());
-}
diff --git a/src/libcollectionstest/vec_deque.rs b/src/libcollectionstest/vec_deque.rs
deleted file mode 100644 (file)
index f2935c0..0000000
+++ /dev/null
@@ -1,1024 +0,0 @@
-// 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::collections::vec_deque::{Drain};
-
-use self::Taggy::*;
-use self::Taggypar::*;
-
-#[test]
-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);
-    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];
-}
-
-#[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().map(|x| *x).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() {
-    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 = (0..).step_by(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_partial_eq_array() {
-    let d = VecDeque::<char>::new();
-    assert!(d == []);
-
-    let mut d = VecDeque::new();
-    d.push_front('a');
-    assert!(d == ['a']);
-
-    let mut d = VecDeque::new();
-    d.push_back('a');
-    assert!(d == ['a']);
-
-    let mut d = VecDeque::new();
-    d.push_back('a');
-    d.push_back('b');
-    assert!(d == ['a', 'b']);
-}
-
-#[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(&x) == ::hash(&y));
-}
-
-#[test]
-fn test_hash_after_rotation() {
-    // test that two deques hash equal even if elements are laid out differently
-    let len = 28;
-    let mut ring: VecDeque<i32> = (0..len as i32).collect();
-    let orig = ring.clone();
-    for _ in 0..ring.capacity() {
-        // shift values 1 step to the right by pop, sub one, push
-        ring.pop_front();
-        for elt in &mut ring {
-            *elt -= 1;
-        }
-        ring.push_back(len - 1);
-        assert_eq!(::hash(&orig), ::hash(&ring));
-        assert_eq!(orig, ring);
-        assert_eq!(ring, orig);
-    }
-}
-
-#[test]
-fn test_eq_after_rotation() {
-    // test that two deques are equal even if elements are laid out differently
-    let len = 28;
-    let mut ring: VecDeque<i32> = (0..len as i32).collect();
-    let mut shifted = ring.clone();
-    for _ in 0..10 {
-        // shift values 1 step to the right by pop, sub one, push
-        ring.pop_front();
-        for elt in &mut ring {
-            *elt -= 1;
-        }
-        ring.push_back(len - 1);
-    }
-
-    // try every shift
-    for _ in 0..shifted.capacity() {
-        shifted.pop_front();
-        for elt in &mut shifted {
-            *elt -= 1;
-        }
-        shifted.push_back(len - 1);
-        assert_eq!(shifted, ring);
-        assert_eq!(ring, shifted);
-    }
-}
-
-#[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<_>>(), []);
-}
-
-#[test]
-fn test_retain() {
-    let mut buf = VecDeque::new();
-    buf.extend(1..5);
-    buf.retain(|&x| x % 2 == 0);
-    let v: Vec<_> = buf.into_iter().collect();
-    assert_eq!(&v[..], &[2, 4]);
-}
-
-#[test]
-fn test_extend_ref() {
-    let mut v = VecDeque::new();
-    v.push_back(1);
-    v.extend(&[2, 3, 4]);
-
-    assert_eq!(v.len(), 4);
-    assert_eq!(v[0], 1);
-    assert_eq!(v[1], 2);
-    assert_eq!(v[2], 3);
-    assert_eq!(v[3], 4);
-
-    let mut w = VecDeque::new();
-    w.push_back(5);
-    w.push_back(6);
-    v.extend(&w);
-
-    assert_eq!(v.len(), 6);
-    assert_eq!(v[0], 1);
-    assert_eq!(v[1], 2);
-    assert_eq!(v[2], 3);
-    assert_eq!(v[3], 4);
-    assert_eq!(v[4], 5);
-    assert_eq!(v[5], 6);
-}
-
-#[test]
-fn test_contains() {
-    let mut v = VecDeque::new();
-    v.extend(&[2, 3, 4]);
-
-    assert!(v.contains(&3));
-    assert!(!v.contains(&1));
-
-    v.clear();
-
-    assert!(!v.contains(&3));
-}
-
-#[allow(dead_code)]
-fn assert_covariance() {
-    fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
-        d
-    }
-}
-
-#[test]
-fn test_is_empty() {
-    let mut v = VecDeque::<i32>::new();
-    assert!(v.is_empty());
-    assert!(v.iter().is_empty());
-    assert!(v.iter_mut().is_empty());
-    v.extend(&[2, 3, 4]);
-    assert!(!v.is_empty());
-    assert!(!v.iter().is_empty());
-    assert!(!v.iter_mut().is_empty());
-    while let Some(_) = v.pop_front() {
-        assert_eq!(v.is_empty(), v.len() == 0);
-        assert_eq!(v.iter().is_empty(), v.iter().len() == 0);
-        assert_eq!(v.iter_mut().is_empty(), v.iter_mut().len() == 0);
-    }
-    assert!(v.is_empty());
-    assert!(v.iter().is_empty());
-    assert!(v.iter_mut().is_empty());
-    assert!(v.into_iter().is_empty());
-}
-
-#[test]
-fn test_placement_in() {
-    let mut buf: VecDeque<isize> = VecDeque::new();
-    buf.place_back() <- 1;
-    buf.place_back() <- 2;
-    assert_eq!(buf, [1,2]);
-
-    buf.place_front() <- 3;
-    buf.place_front() <- 4;
-    assert_eq!(buf, [4,3,1,2]);
-
-    {
-        let ptr_head = buf.place_front() <- 5;
-        assert_eq!(*ptr_head, 5);
-    }
-    {
-        let ptr_tail = buf.place_back() <- 6;
-        assert_eq!(*ptr_tail, 6);
-    }
-    assert_eq!(buf, [5,4,3,1,2,6]);
-}
index e847c7fa3a0ec9580c82431ebe0d86bd8a88e9c2..5af63aa970f2c7cb50a720298b73dbc875e5b4c9 100644 (file)
@@ -10,8 +10,8 @@ test = false
 bench = false
 
 [[test]]
-name = "coretest"
-path = "../libcoretest/lib.rs"
+name = "coretests"
+path = "../libcore/tests/lib.rs"
 
 [[bench]]
 name = "corebenches"
index ddc473592a26026035edd0c0f15705e30f0a3dd0..2c0f449b27601405bdcb1014552944c36b2461e7 100644 (file)
 // NOTE: The following code was generated by "src/etc/char_private.py",
 //       do not edit directly!
 
-use slice::SliceExt;
-
-fn check(x: u16, singletons: &[u16], normal: &[u16]) -> bool {
-    for &s in singletons {
-        if x == s {
-            return false;
-        } else if x < s {
+fn check(x: u16, singletonuppers: &[(u8, u8)], singletonlowers: &[u8],
+         normal: &[u8]) -> bool {
+    let xupper = (x >> 8) as u8;
+    let mut lowerstart = 0;
+    for &(upper, lowercount) in singletonuppers {
+        let lowerend = lowerstart + lowercount as usize;
+        if xupper == upper {
+            for &lower in &singletonlowers[lowerstart..lowerend] {
+                if lower == x as u8 {
+                    return false;
+                }
+            }
+        } else if xupper < upper {
             break;
         }
+        lowerstart = lowerend;
     }
-    for w in normal.chunks(2) {
-        let start = w[0];
-        let len = w[1];
-        let difference = (x as i32) - (start as i32);
-        if 0 <= difference {
-            if difference < len as i32 {
-                return false;
-            }
+
+    let mut x = x as i32;
+    let mut normal = normal.iter().cloned();
+    let mut current = true;
+    while let Some(v) = normal.next() {
+        let len = if v & 0x80 != 0 {
+            ((v & 0x7f) as i32) << 8 | normal.next().unwrap() as i32
         } else {
+            v as i32
+        };
+        x -= len;
+        if x < 0 {
             break;
         }
+        current = !current;
     }
-    true
+    current
 }
 
 pub fn is_printable(x: char) -> bool {
     let x = x as u32;
     let lower = x as u16;
     if x < 0x10000 {
-        check(lower, SINGLETONS0, NORMAL0)
+        check(lower, SINGLETONS0U, SINGLETONS0L, NORMAL0)
     } else if x < 0x20000 {
-        check(lower, SINGLETONS1, NORMAL1)
+        check(lower, SINGLETONS1U, SINGLETONS1L, NORMAL1)
     } else {
         if 0x2a6d7 <= x && x < 0x2a700 {
             return false;
@@ -66,761 +77,446 @@ pub fn is_printable(x: char) -> bool {
     }
 }
 
-const SINGLETONS0: &'static [u16] = &[
-    0xad,
-    0x378,
-    0x379,
-    0x38b,
-    0x38d,
-    0x3a2,
-    0x530,
-    0x557,
-    0x558,
-    0x560,
-    0x588,
-    0x58b,
-    0x58c,
-    0x590,
-    0x61c,
-    0x61d,
-    0x6dd,
-    0x70e,
-    0x70f,
-    0x74b,
-    0x74c,
-    0x82e,
-    0x82f,
-    0x83f,
-    0x85c,
-    0x85d,
-    0x8b5,
-    0x8e2,
-    0x984,
-    0x98d,
-    0x98e,
-    0x991,
-    0x992,
-    0x9a9,
-    0x9b1,
-    0x9ba,
-    0x9bb,
-    0x9c5,
-    0x9c6,
-    0x9c9,
-    0x9ca,
-    0x9de,
-    0x9e4,
-    0x9e5,
-    0xa04,
-    0xa11,
-    0xa12,
-    0xa29,
-    0xa31,
-    0xa34,
-    0xa37,
-    0xa3a,
-    0xa3b,
-    0xa3d,
-    0xa49,
-    0xa4a,
-    0xa5d,
-    0xa84,
-    0xa8e,
-    0xa92,
-    0xaa9,
-    0xab1,
-    0xab4,
-    0xaba,
-    0xabb,
-    0xac6,
-    0xaca,
-    0xace,
-    0xacf,
-    0xae4,
-    0xae5,
-    0xb04,
-    0xb0d,
-    0xb0e,
-    0xb11,
-    0xb12,
-    0xb29,
-    0xb31,
-    0xb34,
-    0xb3a,
-    0xb3b,
-    0xb45,
-    0xb46,
-    0xb49,
-    0xb4a,
-    0xb5e,
-    0xb64,
-    0xb65,
-    0xb84,
-    0xb91,
-    0xb9b,
-    0xb9d,
-    0xbc9,
-    0xbce,
-    0xbcf,
-    0xc04,
-    0xc0d,
-    0xc11,
-    0xc29,
-    0xc45,
-    0xc49,
-    0xc57,
-    0xc64,
-    0xc65,
-    0xc84,
-    0xc8d,
-    0xc91,
-    0xca9,
-    0xcb4,
-    0xcba,
-    0xcbb,
-    0xcc5,
-    0xcc9,
-    0xcdf,
-    0xce4,
-    0xce5,
-    0xcf0,
-    0xd04,
-    0xd0d,
-    0xd11,
-    0xd3b,
-    0xd3c,
-    0xd45,
-    0xd49,
-    0xd64,
-    0xd65,
-    0xd80,
-    0xd81,
-    0xd84,
-    0xdb2,
-    0xdbc,
-    0xdbe,
-    0xdbf,
-    0xdd5,
-    0xdd7,
-    0xdf0,
-    0xdf1,
-    0xe83,
-    0xe85,
-    0xe86,
-    0xe89,
-    0xe8b,
-    0xe8c,
-    0xe98,
-    0xea0,
-    0xea4,
-    0xea6,
-    0xea8,
-    0xea9,
-    0xeac,
-    0xeba,
-    0xebe,
-    0xebf,
-    0xec5,
-    0xec7,
-    0xece,
-    0xecf,
-    0xeda,
-    0xedb,
-    0xf48,
-    0xf98,
-    0xfbd,
-    0xfcd,
-    0x10c6,
-    0x10ce,
-    0x10cf,
-    0x1249,
-    0x124e,
-    0x124f,
-    0x1257,
-    0x1259,
-    0x125e,
-    0x125f,
-    0x1289,
-    0x128e,
-    0x128f,
-    0x12b1,
-    0x12b6,
-    0x12b7,
-    0x12bf,
-    0x12c1,
-    0x12c6,
-    0x12c7,
-    0x12d7,
-    0x1311,
-    0x1316,
-    0x1317,
-    0x135b,
-    0x135c,
-    0x13f6,
-    0x13f7,
-    0x13fe,
-    0x13ff,
-    0x1680,
-    0x170d,
-    0x176d,
-    0x1771,
-    0x17de,
-    0x17df,
-    0x180e,
-    0x180f,
-    0x191f,
-    0x196e,
-    0x196f,
-    0x1a1c,
-    0x1a1d,
-    0x1a5f,
-    0x1a7d,
-    0x1a7e,
-    0x1aae,
-    0x1aaf,
-    0x1cf7,
-    0x1f16,
-    0x1f17,
-    0x1f1e,
-    0x1f1f,
-    0x1f46,
-    0x1f47,
-    0x1f4e,
-    0x1f4f,
-    0x1f58,
-    0x1f5a,
-    0x1f5c,
-    0x1f5e,
-    0x1f7e,
-    0x1f7f,
-    0x1fb5,
-    0x1fc5,
-    0x1fd4,
-    0x1fd5,
-    0x1fdc,
-    0x1ff0,
-    0x1ff1,
-    0x1ff5,
-    0x2072,
-    0x2073,
-    0x208f,
-    0x23ff,
-    0x2b74,
-    0x2b75,
-    0x2b96,
-    0x2b97,
-    0x2bc9,
-    0x2c2f,
-    0x2c5f,
-    0x2d26,
-    0x2d2e,
-    0x2d2f,
-    0x2da7,
-    0x2daf,
-    0x2db7,
-    0x2dbf,
-    0x2dc7,
-    0x2dcf,
-    0x2dd7,
-    0x2ddf,
-    0x2e9a,
-    0x3040,
-    0x3097,
-    0x3098,
-    0x318f,
-    0x321f,
-    0x32ff,
-    0xa7af,
-    0xa8fe,
-    0xa8ff,
-    0xa9ce,
-    0xa9ff,
-    0xaa4e,
-    0xaa4f,
-    0xaa5a,
-    0xaa5b,
-    0xab07,
-    0xab08,
-    0xab0f,
-    0xab10,
-    0xab27,
-    0xab2f,
-    0xabee,
-    0xabef,
-    0xfa6e,
-    0xfa6f,
-    0xfb37,
-    0xfb3d,
-    0xfb3f,
-    0xfb42,
-    0xfb45,
-    0xfd90,
-    0xfd91,
-    0xfdfe,
-    0xfdff,
-    0xfe53,
-    0xfe67,
-    0xfe75,
-    0xffc8,
-    0xffc9,
-    0xffd0,
-    0xffd1,
-    0xffd8,
-    0xffd9,
-    0xffe7,
-    0xfffe,
-    0xffff,
+const SINGLETONS0U: &'static [(u8, u8)] = &[
+    (0x00, 1),
+    (0x03, 5),
+    (0x05, 8),
+    (0x06, 3),
+    (0x07, 4),
+    (0x08, 7),
+    (0x09, 16),
+    (0x0a, 27),
+    (0x0b, 24),
+    (0x0c, 22),
+    (0x0d, 20),
+    (0x0e, 22),
+    (0x0f, 4),
+    (0x10, 3),
+    (0x12, 18),
+    (0x13, 9),
+    (0x16, 1),
+    (0x17, 5),
+    (0x18, 2),
+    (0x19, 3),
+    (0x1a, 7),
+    (0x1c, 1),
+    (0x1f, 22),
+    (0x20, 3),
+    (0x23, 1),
+    (0x2b, 5),
+    (0x2c, 2),
+    (0x2d, 11),
+    (0x2e, 1),
+    (0x30, 3),
+    (0x31, 1),
+    (0x32, 2),
+    (0xa7, 1),
+    (0xa8, 2),
+    (0xa9, 2),
+    (0xaa, 4),
+    (0xab, 8),
+    (0xfa, 2),
+    (0xfb, 5),
+    (0xfd, 4),
+    (0xfe, 3),
+    (0xff, 9),
 ];
-const SINGLETONS1: &'static [u16] = &[
-    0xc,
-    0x27,
-    0x3b,
-    0x3e,
-    0x4e,
-    0x4f,
-    0x18f,
-    0x39e,
-    0x49e,
-    0x49f,
-    0x806,
-    0x807,
-    0x809,
-    0x836,
-    0x83d,
-    0x83e,
-    0x856,
-    0x8f3,
-    0x9d0,
-    0x9d1,
-    0xa04,
-    0xa14,
-    0xa18,
-    0xb56,
-    0xb57,
-    0x10bd,
-    0x1135,
-    0x11ce,
-    0x11cf,
-    0x11e0,
-    0x1212,
-    0x1287,
-    0x1289,
-    0x128e,
-    0x129e,
-    0x1304,
-    0x130d,
-    0x130e,
-    0x1311,
-    0x1312,
-    0x1329,
-    0x1331,
-    0x1334,
-    0x133a,
-    0x133b,
-    0x1345,
-    0x1346,
-    0x1349,
-    0x134a,
-    0x134e,
-    0x134f,
-    0x1364,
-    0x1365,
-    0x145a,
-    0x145c,
-    0x15b6,
-    0x15b7,
-    0x1c09,
-    0x1c37,
-    0x1c90,
-    0x1c91,
-    0x1ca8,
-    0x246f,
-    0x6a5f,
-    0x6aee,
-    0x6aef,
-    0x6b5a,
-    0x6b62,
-    0xbc9a,
-    0xbc9b,
-    0xd127,
-    0xd128,
-    0xd455,
-    0xd49d,
-    0xd4a0,
-    0xd4a1,
-    0xd4a3,
-    0xd4a4,
-    0xd4a7,
-    0xd4a8,
-    0xd4ad,
-    0xd4ba,
-    0xd4bc,
-    0xd4c4,
-    0xd506,
-    0xd50b,
-    0xd50c,
-    0xd515,
-    0xd51d,
-    0xd53a,
-    0xd53f,
-    0xd545,
-    0xd551,
-    0xd6a6,
-    0xd6a7,
-    0xd7cc,
-    0xd7cd,
-    0xdaa0,
-    0xe007,
-    0xe019,
-    0xe01a,
-    0xe022,
-    0xe025,
-    0xe8c5,
-    0xe8c6,
-    0xee04,
-    0xee20,
-    0xee23,
-    0xee25,
-    0xee26,
-    0xee28,
-    0xee33,
-    0xee38,
-    0xee3a,
-    0xee48,
-    0xee4a,
-    0xee4c,
-    0xee50,
-    0xee53,
-    0xee55,
-    0xee56,
-    0xee58,
-    0xee5a,
-    0xee5c,
-    0xee5e,
-    0xee60,
-    0xee63,
-    0xee65,
-    0xee66,
-    0xee6b,
-    0xee73,
-    0xee78,
-    0xee7d,
-    0xee7f,
-    0xee8a,
-    0xeea4,
-    0xeeaa,
-    0xf0af,
-    0xf0b0,
-    0xf0c0,
-    0xf0d0,
-    0xf12f,
-    0xf91f,
-    0xf931,
-    0xf932,
-    0xf93f,
+const SINGLETONS0L: &'static [u8] = &[
+    0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57,
+    0x58, 0x60, 0x88, 0x8b, 0x8c, 0x90, 0x1c, 0x1d,
+    0xdd, 0x0e, 0x0f, 0x4b, 0x4c, 0x2e, 0x2f, 0x3f,
+    0x5c, 0x5d, 0xb5, 0xe2, 0x84, 0x8d, 0x8e, 0x91,
+    0x92, 0xa9, 0xb1, 0xba, 0xbb, 0xc5, 0xc6, 0xc9,
+    0xca, 0xde, 0xe4, 0xe5, 0x04, 0x11, 0x12, 0x29,
+    0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49, 0x4a,
+    0x5d, 0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4, 0xba,
+    0xbb, 0xc6, 0xca, 0xce, 0xcf, 0xe4, 0xe5, 0x04,
+    0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a,
+    0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e, 0x64, 0x65,
+    0x84, 0x91, 0x9b, 0x9d, 0xc9, 0xce, 0xcf, 0x04,
+    0x0d, 0x11, 0x29, 0x45, 0x49, 0x57, 0x64, 0x65,
+    0x84, 0x8d, 0x91, 0xa9, 0xb4, 0xba, 0xbb, 0xc5,
+    0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x04, 0x0d, 0x11,
+    0x3b, 0x3c, 0x45, 0x49, 0x64, 0x65, 0x80, 0x81,
+    0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5, 0xd7, 0xf0,
+    0xf1, 0x83, 0x85, 0x86, 0x89, 0x8b, 0x8c, 0x98,
+    0xa0, 0xa4, 0xa6, 0xa8, 0xa9, 0xac, 0xba, 0xbe,
+    0xbf, 0xc5, 0xc7, 0xce, 0xcf, 0xda, 0xdb, 0x48,
+    0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49, 0x4e,
+    0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f,
+    0xb1, 0xb6, 0xb7, 0xbf, 0xc1, 0xc6, 0xc7, 0xd7,
+    0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, 0xfe,
+    0xff, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e,
+    0x0f, 0x1f, 0x6e, 0x6f, 0x1c, 0x1d, 0x5f, 0x7d,
+    0x7e, 0xae, 0xaf, 0xf7, 0x16, 0x17, 0x1e, 0x1f,
+    0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e,
+    0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0,
+    0xf1, 0xf5, 0x72, 0x73, 0x8f, 0xff, 0x74, 0x75,
+    0x96, 0x97, 0xc9, 0x2f, 0x5f, 0x26, 0x2e, 0x2f,
+    0xa7, 0xaf, 0xb7, 0xbf, 0xc7, 0xcf, 0xd7, 0xdf,
+    0x9a, 0x40, 0x97, 0x98, 0x8f, 0x1f, 0xff, 0xaf,
+    0xfe, 0xff, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b,
+    0x07, 0x08, 0x0f, 0x10, 0x27, 0x2f, 0xee, 0xef,
+    0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90,
+    0x91, 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9,
+    0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff,
 ];
-const NORMAL0: &'static [u16] = &[
-    0x0, 0x20,
-    0x7f, 0x22,
-    0x380, 0x4,
-    0x5c8, 0x8,
-    0x5eb, 0x5,
-    0x5f5, 0x11,
-    0x7b2, 0xe,
-    0x7fb, 0x5,
-    0x85f, 0x41,
-    0x8be, 0x16,
-    0x9b3, 0x3,
-    0x9cf, 0x8,
-    0x9d8, 0x4,
-    0x9fc, 0x5,
-    0xa0b, 0x4,
-    0xa43, 0x4,
-    0xa4e, 0x3,
-    0xa52, 0x7,
-    0xa5f, 0x7,
-    0xa76, 0xb,
-    0xad1, 0xf,
-    0xaf2, 0x7,
-    0xafa, 0x7,
-    0xb4e, 0x8,
-    0xb58, 0x4,
-    0xb78, 0xa,
-    0xb8b, 0x3,
-    0xb96, 0x3,
-    0xba0, 0x3,
-    0xba5, 0x3,
-    0xbab, 0x3,
-    0xbba, 0x4,
-    0xbc3, 0x3,
-    0xbd1, 0x6,
-    0xbd8, 0xe,
-    0xbfb, 0x5,
-    0xc3a, 0x3,
-    0xc4e, 0x7,
-    0xc5b, 0x5,
-    0xc70, 0x8,
-    0xcce, 0x7,
-    0xcd7, 0x7,
-    0xcf3, 0xe,
-    0xd50, 0x4,
-    0xd97, 0x3,
-    0xdc7, 0x3,
-    0xdcb, 0x4,
-    0xde0, 0x6,
-    0xdf5, 0xc,
-    0xe3b, 0x4,
-    0xe5c, 0x25,
-    0xe8e, 0x6,
-    0xee0, 0x20,
-    0xf6d, 0x4,
-    0xfdb, 0x25,
-    0x10c8, 0x5,
-    0x137d, 0x3,
-    0x139a, 0x6,
-    0x169d, 0x3,
-    0x16f9, 0x7,
-    0x1715, 0xb,
-    0x1737, 0x9,
-    0x1754, 0xc,
-    0x1774, 0xc,
-    0x17ea, 0x6,
-    0x17fa, 0x6,
-    0x181a, 0x6,
-    0x1878, 0x8,
-    0x18ab, 0x5,
-    0x18f6, 0xa,
-    0x192c, 0x4,
-    0x193c, 0x4,
-    0x1941, 0x3,
-    0x1975, 0xb,
-    0x19ac, 0x4,
-    0x19ca, 0x6,
-    0x19db, 0x3,
-    0x1a8a, 0x6,
-    0x1a9a, 0x6,
-    0x1abf, 0x41,
-    0x1b4c, 0x4,
-    0x1b7d, 0x3,
-    0x1bf4, 0x8,
-    0x1c38, 0x3,
-    0x1c4a, 0x3,
-    0x1c89, 0x37,
-    0x1cc8, 0x8,
-    0x1cfa, 0x6,
-    0x1df6, 0x5,
-    0x1fff, 0x11,
-    0x2028, 0x8,
-    0x205f, 0x11,
-    0x209d, 0x3,
-    0x20bf, 0x11,
-    0x20f1, 0xf,
-    0x218c, 0x4,
-    0x2427, 0x19,
-    0x244b, 0x15,
-    0x2bba, 0x3,
-    0x2bd2, 0x1a,
-    0x2bf0, 0x10,
-    0x2cf4, 0x5,
-    0x2d28, 0x5,
-    0x2d68, 0x7,
-    0x2d71, 0xe,
-    0x2d97, 0x9,
-    0x2e45, 0x3b,
-    0x2ef4, 0xc,
-    0x2fd6, 0x1a,
-    0x2ffc, 0x5,
-    0x3100, 0x5,
-    0x312e, 0x3,
-    0x31bb, 0x5,
-    0x31e4, 0xc,
-    0x4db6, 0xa,
-    0x9fd6, 0x2a,
-    0xa48d, 0x3,
-    0xa4c7, 0x9,
-    0xa62c, 0x14,
-    0xa6f8, 0x8,
-    0xa7b8, 0x3f,
-    0xa82c, 0x4,
-    0xa83a, 0x6,
-    0xa878, 0x8,
-    0xa8c6, 0x8,
-    0xa8da, 0x6,
-    0xa954, 0xb,
-    0xa97d, 0x3,
-    0xa9da, 0x4,
-    0xaa37, 0x9,
-    0xaac3, 0x18,
-    0xaaf7, 0xa,
-    0xab17, 0x9,
-    0xab66, 0xa,
-    0xabfa, 0x6,
-    0xd7a4, 0xc,
-    0xd7c7, 0x4,
-    0xd7fc, 0x2104,
-    0xfada, 0x26,
-    0xfb07, 0xc,
-    0xfb18, 0x5,
-    0xfbc2, 0x11,
-    0xfd40, 0x10,
-    0xfdc8, 0x28,
-    0xfe1a, 0x6,
-    0xfe6c, 0x4,
-    0xfefd, 0x4,
-    0xffbf, 0x3,
-    0xffdd, 0x3,
-    0xffef, 0xd,
+const SINGLETONS1U: &'static [(u8, u8)] = &[
+    (0x00, 6),
+    (0x01, 1),
+    (0x03, 1),
+    (0x04, 2),
+    (0x08, 8),
+    (0x09, 2),
+    (0x0a, 3),
+    (0x0b, 2),
+    (0x10, 1),
+    (0x11, 4),
+    (0x12, 5),
+    (0x13, 18),
+    (0x14, 2),
+    (0x15, 2),
+    (0x1c, 5),
+    (0x24, 1),
+    (0x6a, 3),
+    (0x6b, 2),
+    (0xbc, 2),
+    (0xd1, 2),
+    (0xd4, 12),
+    (0xd5, 9),
+    (0xd6, 2),
+    (0xd7, 2),
+    (0xda, 1),
+    (0xe0, 5),
+    (0xe8, 2),
+    (0xee, 32),
+    (0xf0, 4),
+    (0xf1, 1),
+    (0xf9, 4),
 ];
-const NORMAL1: &'static [u16] = &[
+const SINGLETONS1L: &'static [u8] = &[
+    0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e,
+    0x9e, 0x9f, 0x06, 0x07, 0x09, 0x36, 0x3d, 0x3e,
+    0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x56,
+    0x57, 0xbd, 0x35, 0xce, 0xcf, 0xe0, 0x12, 0x87,
+    0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e, 0x11, 0x12,
+    0x29, 0x31, 0x34, 0x3a, 0x3b, 0x45, 0x46, 0x49,
+    0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5a, 0x5c, 0xb6,
+    0xb7, 0x09, 0x37, 0x90, 0x91, 0xa8, 0x6f, 0x5f,
+    0xee, 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27, 0x28,
+    0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8,
+    0xad, 0xba, 0xbc, 0xc4, 0x06, 0x0b, 0x0c, 0x15,
+    0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, 0xcc,
+    0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0xc5,
+    0xc6, 0x04, 0x20, 0x23, 0x25, 0x26, 0x28, 0x33,
+    0x38, 0x3a, 0x48, 0x4a, 0x4c, 0x50, 0x53, 0x55,
+    0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65,
+    0x66, 0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4,
+    0xaa, 0xaf, 0xb0, 0xc0, 0xd0, 0x2f, 0x1f, 0x31,
+    0x32, 0x3f,
+];
+const NORMAL0: &'static [u8] = &[
+    0x00, 0x20,
+    0x5f, 0x22,
+    0x82, 0xdf, 0x04,
+    0x82, 0x44, 0x08,
+    0x1b, 0x05,
+    0x05, 0x11,
+    0x81, 0xac, 0x0e,
+    0x3b, 0x05,
+    0x5f, 0x41,
+    0x1e, 0x16,
+    0x80, 0xdf, 0x03,
+    0x19, 0x08,
+    0x01, 0x04,
+    0x20, 0x05,
+    0x0a, 0x04,
+    0x34, 0x04,
+    0x07, 0x03,
+    0x01, 0x07,
+    0x06, 0x07,
+    0x10, 0x0b,
+    0x50, 0x0f,
+    0x12, 0x07,
+    0x01, 0x07,
+    0x4d, 0x08,
+    0x02, 0x04,
+    0x1c, 0x0a,
+    0x09, 0x03,
+    0x08, 0x03,
+    0x07, 0x03,
+    0x02, 0x03,
+    0x03, 0x03,
+    0x0c, 0x04,
+    0x05, 0x03,
+    0x0b, 0x06,
+    0x01, 0x0e,
+    0x15, 0x05,
+    0x3a, 0x03,
+    0x11, 0x07,
+    0x06, 0x05,
+    0x10, 0x08,
+    0x56, 0x07,
+    0x02, 0x07,
+    0x15, 0x0e,
+    0x4f, 0x04,
+    0x43, 0x03,
+    0x2d, 0x03,
+    0x01, 0x04,
+    0x11, 0x06,
+    0x0f, 0x0c,
+    0x3a, 0x04,
+    0x1d, 0x25,
+    0x0d, 0x06,
+    0x4c, 0x20,
+    0x6d, 0x04,
+    0x6a, 0x25,
+    0x80, 0xc8, 0x05,
+    0x82, 0xb0, 0x03,
+    0x1a, 0x06,
+    0x82, 0xfd, 0x03,
+    0x59, 0x07,
+    0x15, 0x0b,
+    0x17, 0x09,
+    0x14, 0x0c,
+    0x14, 0x0c,
+    0x6a, 0x06,
+    0x0a, 0x06,
+    0x1a, 0x06,
+    0x58, 0x08,
+    0x2b, 0x05,
+    0x46, 0x0a,
+    0x2c, 0x04,
+    0x0c, 0x04,
+    0x01, 0x03,
+    0x31, 0x0b,
+    0x2c, 0x04,
+    0x1a, 0x06,
+    0x0b, 0x03,
+    0x80, 0xac, 0x06,
+    0x0a, 0x06,
+    0x1f, 0x41,
+    0x4c, 0x04,
+    0x2d, 0x03,
+    0x74, 0x08,
+    0x3c, 0x03,
+    0x0f, 0x03,
+    0x3c, 0x37,
+    0x08, 0x08,
+    0x2a, 0x06,
+    0x80, 0xf6, 0x05,
+    0x82, 0x04, 0x11,
+    0x18, 0x08,
+    0x2f, 0x11,
+    0x2d, 0x03,
+    0x1f, 0x11,
+    0x21, 0x0f,
+    0x80, 0x8c, 0x04,
+    0x82, 0x97, 0x19,
+    0x0b, 0x15,
+    0x87, 0x5a, 0x03,
+    0x15, 0x1a,
+    0x04, 0x10,
+    0x80, 0xf4, 0x05,
+    0x2f, 0x05,
+    0x3b, 0x07,
+    0x02, 0x0e,
+    0x18, 0x09,
+    0x80, 0xa5, 0x3b,
+    0x74, 0x0c,
+    0x80, 0xd6, 0x1a,
+    0x0c, 0x05,
+    0x80, 0xff, 0x05,
+    0x29, 0x03,
+    0x80, 0x8a, 0x05,
+    0x24, 0x0c,
+    0x9b, 0xc6, 0x0a,
+    0xd2, 0x16, 0x2a,
+    0x84, 0x8d, 0x03,
+    0x37, 0x09,
+    0x81, 0x5c, 0x14,
+    0x80, 0xb8, 0x08,
+    0x80, 0xb8, 0x3f,
+    0x35, 0x04,
+    0x0a, 0x06,
+    0x38, 0x08,
+    0x46, 0x08,
+    0x0c, 0x06,
+    0x74, 0x0b,
+    0x1e, 0x03,
+    0x5a, 0x04,
+    0x59, 0x09,
+    0x80, 0x83, 0x18,
+    0x1c, 0x0a,
+    0x16, 0x09,
+    0x46, 0x0a,
+    0x80, 0x8a, 0x06,
+    0xab, 0xa4, 0x0c,
+    0x17, 0x04,
+    0x31, 0xa1, 0x04,
+    0x81, 0xda, 0x26,
+    0x07, 0x0c,
+    0x05, 0x05,
+    0x80, 0xa5, 0x11,
+    0x81, 0x6d, 0x10,
+    0x78, 0x28,
+    0x2a, 0x06,
+    0x4c, 0x04,
+    0x80, 0x8d, 0x04,
+    0x80, 0xbe, 0x03,
+    0x1b, 0x03,
+    0x0f, 0x0d,
+];
+const NORMAL1: &'static [u8] = &[
+    0x5e, 0x22,
+    0x7b, 0x05,
+    0x03, 0x04,
+    0x2d, 0x03,
+    0x65, 0x04,
+    0x01, 0x2f,
+    0x2e, 0x80, 0x82,
+    0x1d, 0x03,
+    0x31, 0x0f,
+    0x1c, 0x04,
+    0x24, 0x0c,
+    0x1b, 0x05,
+    0x2b, 0x05,
+    0x44, 0x04,
+    0x0e, 0x2a,
+    0x80, 0xaa, 0x06,
+    0x24, 0x04,
+    0x24, 0x04,
+    0x28, 0x08,
+    0x34, 0x0b,
+    0x01, 0x80, 0x90,
+    0x81, 0x37, 0x09,
+    0x16, 0x0a,
+    0x08, 0x80, 0x98,
+    0x39, 0x03,
+    0x63, 0x08,
+    0x09, 0x30,
+    0x16, 0x05,
+    0x21, 0x03,
+    0x1b, 0x05,
+    0x01, 0x40,
+    0x38, 0x04,
+    0x4b, 0x05,
+    0x28, 0x04,
+    0x03, 0x04,
+    0x09, 0x08,
+    0x09, 0x07,
+    0x40, 0x20,
+    0x27, 0x04,
+    0x0c, 0x09,
+    0x36, 0x03,
+    0x3a, 0x05,
+    0x1a, 0x07,
+    0x04, 0x0c,
+    0x07, 0x50,
+    0x49, 0x37,
+    0x33, 0x0d,
+    0x33, 0x07,
+    0x06, 0x81, 0x60,
+    0x1f, 0x81, 0x81,
+    0x4e, 0x04,
+    0x1e, 0x0f,
+    0x43, 0x0e,
+    0x19, 0x07,
+    0x0a, 0x06,
+    0x44, 0x0c,
+    0x27, 0x09,
+    0x75, 0x0b,
+    0x3f, 0x41,
+    0x2a, 0x06,
+    0x3b, 0x05,
+    0x0a, 0x06,
+    0x51, 0x06,
+    0x01, 0x05,
+    0x10, 0x03,
+    0x05, 0x80, 0x8b,
+    0x5e, 0x22,
+    0x48, 0x08,
+    0x0a, 0x80, 0xa6,
     0x5e, 0x22,
-    0xfb, 0x5,
-    0x103, 0x4,
-    0x134, 0x3,
-    0x19c, 0x4,
-    0x1a1, 0x2f,
-    0x1fe, 0x82,
-    0x29d, 0x3,
-    0x2d1, 0xf,
-    0x2fc, 0x4,
-    0x324, 0xc,
-    0x34b, 0x5,
-    0x37b, 0x5,
-    0x3c4, 0x4,
-    0x3d6, 0x2a,
-    0x4aa, 0x6,
-    0x4d4, 0x4,
-    0x4fc, 0x4,
-    0x528, 0x8,
-    0x564, 0xb,
-    0x570, 0x90,
-    0x737, 0x9,
-    0x756, 0xa,
-    0x768, 0x98,
-    0x839, 0x3,
-    0x89f, 0x8,
-    0x8b0, 0x30,
-    0x8f6, 0x5,
-    0x91c, 0x3,
-    0x93a, 0x5,
-    0x940, 0x40,
-    0x9b8, 0x4,
-    0xa07, 0x5,
-    0xa34, 0x4,
-    0xa3b, 0x4,
-    0xa48, 0x8,
-    0xa59, 0x7,
-    0xaa0, 0x20,
-    0xae7, 0x4,
-    0xaf7, 0x9,
-    0xb36, 0x3,
-    0xb73, 0x5,
-    0xb92, 0x7,
-    0xb9d, 0xc,
-    0xbb0, 0x50,
-    0xc49, 0x37,
-    0xcb3, 0xd,
-    0xcf3, 0x7,
-    0xd00, 0x160,
-    0xe7f, 0x181,
-    0x104e, 0x4,
-    0x1070, 0xf,
-    0x10c2, 0xe,
-    0x10e9, 0x7,
-    0x10fa, 0x6,
-    0x1144, 0xc,
-    0x1177, 0x9,
-    0x11f5, 0xb,
-    0x123f, 0x41,
-    0x12aa, 0x6,
-    0x12eb, 0x5,
-    0x12fa, 0x6,
-    0x1351, 0x6,
-    0x1358, 0x5,
-    0x136d, 0x3,
-    0x1375, 0x8b,
-    0x145e, 0x22,
-    0x14c8, 0x8,
-    0x14da, 0xa6,
-    0x15de, 0x22,
-    0x1645, 0xb,
-    0x165a, 0x6,
-    0x166d, 0x13,
-    0x16b8, 0x8,
-    0x16ca, 0x36,
-    0x171a, 0x3,
-    0x172c, 0x4,
-    0x1740, 0x160,
-    0x18f3, 0xc,
-    0x1900, 0x1c0,
-    0x1af9, 0x107,
-    0x1c46, 0xa,
-    0x1c6d, 0x3,
-    0x1cb7, 0x349,
-    0x239a, 0x66,
-    0x2475, 0xb,
-    0x2544, 0xabc,
-    0x342f, 0xfd1,
-    0x4647, 0x21b9,
-    0x6a39, 0x7,
-    0x6a6a, 0x4,
-    0x6a70, 0x60,
-    0x6af6, 0xa,
-    0x6b46, 0xa,
-    0x6b78, 0x5,
-    0x6b90, 0x370,
-    0x6f45, 0xb,
-    0x6f7f, 0x10,
-    0x6fa0, 0x40,
-    0x6fe1, 0x1f,
-    0x87ed, 0x13,
-    0x8af3, 0x250d,
-    0xb002, 0xbfe,
-    0xbc6b, 0x5,
-    0xbc7d, 0x3,
-    0xbc89, 0x7,
-    0xbca0, 0x1360,
-    0xd0f6, 0xa,
-    0xd173, 0x8,
-    0xd1e9, 0x17,
-    0xd246, 0xba,
-    0xd357, 0x9,
-    0xd372, 0x8e,
-    0xd547, 0x3,
-    0xda8c, 0xf,
-    0xdab0, 0x550,
-    0xe02b, 0x7d5,
-    0xe8d7, 0x29,
-    0xe94b, 0x5,
-    0xe95a, 0x4,
-    0xe960, 0x4a0,
-    0xee3c, 0x6,
-    0xee43, 0x4,
-    0xee9c, 0x5,
-    0xeebc, 0x34,
-    0xeef2, 0x10e,
-    0xf02c, 0x4,
-    0xf094, 0xc,
-    0xf0f6, 0xa,
-    0xf10d, 0x3,
-    0xf16c, 0x4,
-    0xf1ad, 0x39,
-    0xf203, 0xd,
-    0xf23c, 0x4,
-    0xf249, 0x7,
-    0xf252, 0xae,
-    0xf6d3, 0xd,
-    0xf6ed, 0x3,
-    0xf6f7, 0x9,
-    0xf774, 0xc,
-    0xf7d5, 0x2b,
-    0xf80c, 0x4,
-    0xf848, 0x8,
-    0xf85a, 0x6,
-    0xf888, 0x8,
-    0xf8ae, 0x62,
-    0xf928, 0x8,
-    0xf94c, 0x4,
-    0xf95f, 0x21,
-    0xf992, 0x2e,
-    0xf9c1, 0x63f,
+    0x45, 0x0b,
+    0x0a, 0x06,
+    0x0d, 0x13,
+    0x38, 0x08,
+    0x0a, 0x36,
+    0x1a, 0x03,
+    0x0f, 0x04,
+    0x10, 0x81, 0x60,
+    0x53, 0x0c,
+    0x01, 0x81, 0xc0,
+    0x39, 0x81, 0x07,
+    0x46, 0x0a,
+    0x1d, 0x03,
+    0x47, 0x83, 0x49,
+    0x83, 0x9a, 0x66,
+    0x75, 0x0b,
+    0x80, 0xc4, 0x8a, 0xbc,
+    0x84, 0x2f, 0x8f, 0xd1,
+    0x82, 0x47, 0xa1, 0xb9,
+    0x82, 0x39, 0x07,
+    0x2a, 0x04,
+    0x02, 0x60,
+    0x26, 0x0a,
+    0x46, 0x0a,
+    0x28, 0x05,
+    0x13, 0x83, 0x70,
+    0x45, 0x0b,
+    0x2f, 0x10,
+    0x11, 0x40,
+    0x01, 0x1f,
+    0x97, 0xed, 0x13,
+    0x82, 0xf3, 0xa5, 0x0d,
+    0x02, 0x8b, 0xfe,
+    0x6b, 0x05,
+    0x0d, 0x03,
+    0x09, 0x07,
+    0x10, 0x93, 0x60,
+    0x80, 0xf6, 0x0a,
+    0x73, 0x08,
+    0x6e, 0x17,
+    0x46, 0x80, 0xba,
+    0x57, 0x09,
+    0x12, 0x80, 0x8e,
+    0x81, 0x47, 0x03,
+    0x85, 0x42, 0x0f,
+    0x15, 0x85, 0x50,
+    0x2b, 0x87, 0xd5,
+    0x80, 0xd7, 0x29,
+    0x4b, 0x05,
+    0x0a, 0x04,
+    0x02, 0x84, 0xa0,
+    0x3c, 0x06,
+    0x01, 0x04,
+    0x55, 0x05,
+    0x1b, 0x34,
+    0x02, 0x81, 0x0e,
+    0x2c, 0x04,
+    0x64, 0x0c,
+    0x56, 0x0a,
+    0x0d, 0x03,
+    0x5c, 0x04,
+    0x3d, 0x39,
+    0x1d, 0x0d,
+    0x2c, 0x04,
+    0x09, 0x07,
+    0x02, 0x80, 0xae,
+    0x83, 0xd3, 0x0d,
+    0x0d, 0x03,
+    0x07, 0x09,
+    0x74, 0x0c,
+    0x55, 0x2b,
+    0x0c, 0x04,
+    0x38, 0x08,
+    0x0a, 0x06,
+    0x28, 0x08,
+    0x1e, 0x62,
+    0x18, 0x08,
+    0x1c, 0x04,
+    0x0f, 0x21,
+    0x12, 0x2e,
+    0x01, 0x86, 0x3f,
 ];
index 1ae8b6bb45113b45a491d5868a059de76d799691..e0a4707ff665f58c0bdedbb8fed6f6e29bc897be 100644 (file)
     /// `std::sync::atomic` types via the `compare_exchange` method by passing
     /// [`Ordering::SeqCst`](../../std/sync/atomic/enum.Ordering.html)
     /// as both the `success` and `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange).
+    /// [`AtomicBool::compare_exchange`][compare_exchange].
+    ///
+    /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
     pub fn atomic_cxchg<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
     /// `std::sync::atomic` types via the `compare_exchange` method by passing
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html)
     /// as both the `success` and `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange).
+    /// [`AtomicBool::compare_exchange`][compare_exchange].
+    ///
+    /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
     pub fn atomic_cxchg_acq<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
@@ -79,8 +81,9 @@
     /// as the `success` and
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange).
+    /// [`AtomicBool::compare_exchange`][compare_exchange].
+    ///
+    /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
     pub fn atomic_cxchg_rel<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
     /// as the `success` and
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange).
+    /// [`AtomicBool::compare_exchange`][compare_exchange].
+    ///
+    /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
     pub fn atomic_cxchg_acqrel<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
     /// `std::sync::atomic` types via the `compare_exchange` method by passing
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as both the `success` and `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange).
+    /// [`AtomicBool::compare_exchange`][compare_exchange].
+    ///
+    /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
     pub fn atomic_cxchg_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
     /// as the `success` and
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange).
+    /// [`AtomicBool::compare_exchange`][compare_exchange].
+    ///
+    /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
     pub fn atomic_cxchg_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
     /// as the `success` and
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange).
+    /// [`AtomicBool::compare_exchange`][compare_exchange].
+    ///
+    /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
     pub fn atomic_cxchg_failacq<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
     /// as the `success` and
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange).
+    /// [`AtomicBool::compare_exchange`][compare_exchange].
+    ///
+    /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
     pub fn atomic_cxchg_acq_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
     /// as the `success` and
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange).
+    /// [`AtomicBool::compare_exchange`][compare_exchange].
+    ///
+    /// [compare_exchange]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange
     pub fn atomic_cxchg_acqrel_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
 
     /// Stores a value if the current value is the same as the `old` value.
     /// `std::sync::atomic` types via the `compare_exchange_weak` method by passing
     /// [`Ordering::SeqCst`](../../std/sync/atomic/enum.Ordering.html)
     /// as both the `success` and `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange_weak`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak).
+    /// [`AtomicBool::compare_exchange_weak`][cew].
+    ///
+    /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
     pub fn atomic_cxchgweak<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
     /// `std::sync::atomic` types via the `compare_exchange_weak` method by passing
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html)
     /// as both the `success` and `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange_weak`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak).
+    /// [`AtomicBool::compare_exchange_weak`][cew].
+    ///
+    /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
     pub fn atomic_cxchgweak_acq<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
     /// as the `success` and
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange_weak`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak).
+    /// [`AtomicBool::compare_exchange_weak`][cew].
+    ///
+    /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
     pub fn atomic_cxchgweak_rel<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
     /// as the `success` and
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange_weak`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak).
+    /// [`AtomicBool::compare_exchange_weak`][cew].
+    ///
+    /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
     pub fn atomic_cxchgweak_acqrel<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
     /// `std::sync::atomic` types via the `compare_exchange_weak` method by passing
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as both the `success` and `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange_weak`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak).
+    /// [`AtomicBool::compare_exchange_weak`][cew].
+    ///
+    /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
     pub fn atomic_cxchgweak_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
     /// as the `success` and
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange_weak`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak).
+    /// [`AtomicBool::compare_exchange_weak`][cew].
+    ///
+    /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
     pub fn atomic_cxchgweak_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
     /// as the `success` and
     /// [`Ordering::Acquire`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange_weak`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak).
+    /// [`AtomicBool::compare_exchange_weak`][cew].
+    ///
+    /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
     pub fn atomic_cxchgweak_failacq<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
     /// as the `success` and
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange_weak`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak).
+    /// [`AtomicBool::compare_exchange_weak`][cew].
+    ///
+    /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
     pub fn atomic_cxchgweak_acq_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
     /// Stores a value if the current value is the same as the `old` value.
     /// The stabilized version of this intrinsic is available on the
     /// as the `success` and
     /// [`Ordering::Relaxed`](../../std/sync/atomic/enum.Ordering.html)
     /// as the `failure` parameters. For example,
-    /// [`AtomicBool::compare_exchange_weak`]
-    /// (../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak).
+    /// [`AtomicBool::compare_exchange_weak`][cew].
+    ///
+    /// [cew]: ../../std/sync/atomic/struct.AtomicBool.html#method.compare_exchange_weak
     pub fn atomic_cxchgweak_acqrel_failrelaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
 
     /// Loads the current value of the pointer.
@@ -1253,17 +1271,17 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
     #[cfg(not(stage0))]
     pub fn unchecked_shr<T>(x: T, y: T) -> T;
 
-    /// Returns (a + b) mod 2^N, where N is the width of T in bits.
+    /// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `wrapping_add` method. For example,
     /// [`std::u32::wrapping_add`](../../std/primitive.u32.html#method.wrapping_add)
     pub fn overflowing_add<T>(a: T, b: T) -> T;
-    /// Returns (a - b) mod 2^N, where N is the width of T in bits.
+    /// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `wrapping_sub` method. For example,
     /// [`std::u32::wrapping_sub`](../../std/primitive.u32.html#method.wrapping_sub)
     pub fn overflowing_sub<T>(a: T, b: T) -> T;
-    /// Returns (a * b) mod 2^N, where N is the width of T in bits.
+    /// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `wrapping_mul` method. For example,
     /// [`std::u32::wrapping_mul`](../../std/primitive.u32.html#method.wrapping_mul)
index 04394e0a3a876c811ab3ce7d3af3543b2713b3af..273f9d0e6f6d31cf9581cbafb0fde73d7f569f96 100644 (file)
@@ -358,12 +358,24 @@ impl<I> Iterator for Rev<I> where I: DoubleEndedIterator {
     fn next(&mut self) -> Option<<I as Iterator>::Item> { self.iter.next_back() }
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
+
+    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
+        where P: FnMut(&Self::Item) -> bool
+    {
+        self.iter.rfind(predicate)
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<I> DoubleEndedIterator for Rev<I> where I: DoubleEndedIterator {
     #[inline]
     fn next_back(&mut self) -> Option<<I as Iterator>::Item> { self.iter.next() }
+
+    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
+        where P: FnMut(&Self::Item) -> bool
+    {
+        self.iter.find(predicate)
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
index 34f14ef53f8935e890f6459472aa02c971cbf677..798dda199281310a58c3740c084803a41fa37a5e 100644 (file)
@@ -467,7 +467,7 @@ fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
         Self: Sized,
         P: FnMut(&Self::Item) -> bool
     {
-        for x in self.by_ref().rev() {
+        while let Some(x) = self.next_back() {
             if predicate(&x) { return Some(x) }
         }
         None
index 8904322ca48f77b01db9b8a9bbbafe19c02438f7..b5553fb29475b9481251e62d0d9eea761f9599b3 100644 (file)
@@ -19,7 +19,7 @@
 //! inputs, but we don't do so to avoid the code bloat. Each bignum is still
 //! tracked for the actual usages, so it normally doesn't matter.
 
-// This module is only for dec2flt and flt2dec, and only public because of libcoretest.
+// This module is only for dec2flt and flt2dec, and only public because of coretests.
 // It is not intended to ever be stabilized.
 #![doc(hidden)]
 #![unstable(feature = "core_private_bignum",
index e3b58b6cc7ce94407980d2c351e71b2a982f2565..45fa721a5a33e0b71c8504e3e0b5ef9a1ab6487c 100644 (file)
 
 //! Bit fiddling on positive IEEE 754 floats. Negative numbers aren't and needn't be handled.
 //! Normal floating point numbers have a canonical representation as (frac, exp) such that the
-//! value is 2^exp * (1 + sum(frac[N-i] / 2^i)) where N is the number of bits. Subnormals are
-//! slightly different and weird, but the same principle applies.
+//! value is 2<sup>exp</sup> * (1 + sum(frac[N-i] / 2<sup>i</sup>)) where N is the number of bits.
+//! Subnormals are slightly different and weird, but the same principle applies.
 //!
-//! Here, however, we represent them as (sig, k) with f positive, such that the value is f * 2^e.
-//! Besides making the "hidden bit" explicit, this changes the exponent by the so-called
-//! mantissa shift.
+//! Here, however, we represent them as (sig, k) with f positive, such that the value is f *
+//! 2<sup>e</sup>. Besides making the "hidden bit" explicit, this changes the exponent by the
+//! so-called mantissa shift.
 //!
 //! Put another way, normally floats are written as (1) but here they are written as (2):
 //!
@@ -94,7 +94,8 @@ fn integer_decode2(self) -> (u64, i16, i8) {
     /// represented, the other code in this module makes sure to never let that happen.
     fn from_int(x: u64) -> Self;
 
-    /// Get the value 10^e from a pre-computed table. Panics for e >= ceil_log5_of_max_sig().
+    /// Get the value 10<sup>e</sup> from a pre-computed table. Panics for e >=
+    /// ceil_log5_of_max_sig().
     fn short_fast_pow10(e: usize) -> Self;
 
     // FIXME Everything that follows should be associated constants, but taking the value of an
index 11eea753f93f912a579dd607cddae2e39f61eb24..6635d95155f4baa4537a0cce133ff8f10bb806a6 100644 (file)
@@ -10,7 +10,7 @@
 
 //! Extended precision "soft float", for internal use only.
 
-// This module is only for dec2flt and flt2dec, and only public because of libcoretest.
+// This module is only for dec2flt and flt2dec, and only public because of coretests.
 // It is not intended to ever be stabilized.
 #![doc(hidden)]
 #![unstable(feature = "core_private_diy_float",
index f6c03a59f81e4ed7750a3cda89fc5841e64a3505..5123e42df61ca8e013943c5d2be7f1f561d57299 100644 (file)
 string from resulting `Part`s itself.
 
 All algorithms and formatting functions are accompanied by extensive tests
-in `coretest::num::flt2dec` module. It also shows how to use individual
+in `coretests::num::flt2dec` module. It also shows how to use individual
 functions.
 
 */
index df343c9d45f20ffa64a47ecb01f6c4af0d6071f3..f665cfdee77aeaaaadc9513dda03b45fac286578 100644 (file)
@@ -90,7 +90,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 mod wrapping;
 
-// All these modules are technically private and only exposed for libcoretest:
+// All these modules are technically private and only exposed for coretests:
 pub mod flt2dec;
 pub mod dec2flt;
 pub mod bignum;
index d997f3592fd76d45842af82c89dede308fa08d68..1a48f27762580e38047b87ad5468adb21b58114f 100644 (file)
@@ -894,9 +894,15 @@ impl<A> ExactSizeIterator for Item<A> {}
 impl<A> FusedIterator for Item<A> {}
 unsafe impl<A> TrustedLen for Item<A> {}
 
-/// An iterator over a reference of the contained item in an [`Option`].
+/// An iterator over a reference to the [`Some`] variant of an [`Option`].
+///
+/// The iterator yields one value if the [`Option`] is a [`Some`], otherwise none.
+///
+/// This `struct` is created by the [`Option::iter`] function.
 ///
 /// [`Option`]: enum.Option.html
+/// [`Some`]: enum.Option.html#variant.Some
+/// [`Option::iter`]: enum.Option.html#method.iter
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 pub struct Iter<'a, A: 'a> { inner: Item<&'a A> }
@@ -933,9 +939,15 @@ fn clone(&self) -> Iter<'a, A> {
     }
 }
 
-/// An iterator over a mutable reference of the contained item in an [`Option`].
+/// An iterator over a mutable reference to the [`Some`] variant of an [`Option`].
+///
+/// The iterator yields one value if the [`Option`] is a [`Some`], otherwise none.
+///
+/// This `struct` is created by the [`Option::iter_mut`] function.
 ///
 /// [`Option`]: enum.Option.html
+/// [`Some`]: enum.Option.html#variant.Some
+/// [`Option::iter_mut`]: enum.Option.html#method.iter_mut
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 pub struct IterMut<'a, A: 'a> { inner: Item<&'a mut A> }
@@ -964,9 +976,15 @@ impl<'a, A> FusedIterator for IterMut<'a, A> {}
 #[unstable(feature = "trusted_len", issue = "37572")]
 unsafe impl<'a, A> TrustedLen for IterMut<'a, A> {}
 
-/// An iterator over the item contained inside an [`Option`].
+/// An iterator over the value in [`Some`] variant of an [`Option`].
+///
+/// The iterator yields one value if the [`Option`] is a [`Some`], otherwise none.
+///
+/// This `struct` is created by the [`Option::into_iter`] function.
 ///
 /// [`Option`]: enum.Option.html
+/// [`Some`]: enum.Option.html#variant.Some
+/// [`Option::into_iter`]: enum.Option.html#method.into_iter
 #[derive(Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoIter<A> { inner: Item<A> }
index d2830a6d00cec149ba22e64c98db7de2ce23d63c..04480fc5d31da2e53d5479850fbf0ce9a560fcdb 100644 (file)
@@ -500,6 +500,44 @@ pub fn wrapping_offset(self, count: isize) -> *const T where T: Sized {
             intrinsics::arith_offset(self, count)
         }
     }
+
+    /// Calculates the distance between two pointers. The returned value is in
+    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+    ///
+    /// If the address different between the two pointers ia not a multiple of
+    /// `mem::size_of::<T>()` then the result of the division is rounded towards
+    /// zero.
+    ///
+    /// This function returns `None` if `T` is a zero-sized typed.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(offset_to)]
+    ///
+    /// fn main() {
+    ///     let a = [0; 5];
+    ///     let ptr1: *const i32 = &a[1];
+    ///     let ptr2: *const i32 = &a[3];
+    ///     assert_eq!(ptr1.offset_to(ptr2), Some(2));
+    ///     assert_eq!(ptr2.offset_to(ptr1), Some(-2));
+    ///     assert_eq!(unsafe { ptr1.offset(2) }, ptr2);
+    ///     assert_eq!(unsafe { ptr2.offset(-2) }, ptr1);
+    /// }
+    /// ```
+    #[unstable(feature = "offset_to", issue = "41079")]
+    #[inline]
+    pub fn offset_to(self, other: *const T) -> Option<isize> where T: Sized {
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            None
+        } else {
+            let diff = (other as isize).wrapping_sub(self as isize);
+            Some(diff / size as isize)
+        }
+    }
 }
 
 #[lang = "mut_ptr"]
@@ -653,6 +691,44 @@ pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> where T: Sized {
             Some(&mut *self)
         }
     }
+
+    /// Calculates the distance between two pointers. The returned value is in
+    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+    ///
+    /// If the address different between the two pointers ia not a multiple of
+    /// `mem::size_of::<T>()` then the result of the division is rounded towards
+    /// zero.
+    ///
+    /// This function returns `None` if `T` is a zero-sized typed.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(offset_to)]
+    ///
+    /// fn main() {
+    ///     let mut a = [0; 5];
+    ///     let ptr1: *mut i32 = &mut a[1];
+    ///     let ptr2: *mut i32 = &mut a[3];
+    ///     assert_eq!(ptr1.offset_to(ptr2), Some(2));
+    ///     assert_eq!(ptr2.offset_to(ptr1), Some(-2));
+    ///     assert_eq!(unsafe { ptr1.offset(2) }, ptr2);
+    ///     assert_eq!(unsafe { ptr2.offset(-2) }, ptr1);
+    /// }
+    /// ```
+    #[unstable(feature = "offset_to", issue = "41079")]
+    #[inline]
+    pub fn offset_to(self, other: *const T) -> Option<isize> where T: Sized {
+        let size = mem::size_of::<T>();
+        if size == 0 {
+            None
+        } else {
+            let diff = (other as isize).wrapping_sub(self as isize);
+            Some(diff / size as isize)
+        }
+    }
 }
 
 // Equality for pointers
index 45667bb42993da8568246b7409321be821f8e464..6d598677c9ba4f0cad90dc5bf1458d1d94433f58 100644 (file)
@@ -81,6 +81,10 @@ pub trait SliceExt {
     fn split<P>(&self, pred: P) -> Split<Self::Item, P>
         where P: FnMut(&Self::Item) -> bool;
 
+    #[unstable(feature = "slice_rsplit", issue = "41020")]
+    fn rsplit<P>(&self, pred: P) -> RSplit<Self::Item, P>
+        where P: FnMut(&Self::Item) -> bool;
+
     #[stable(feature = "core", since = "1.6.0")]
     fn splitn<P>(&self, n: usize, pred: P) -> SplitN<Self::Item, P>
         where P: FnMut(&Self::Item) -> bool;
@@ -159,6 +163,10 @@ fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
     fn split_mut<P>(&mut self, pred: P) -> SplitMut<Self::Item, P>
         where P: FnMut(&Self::Item) -> bool;
 
+    #[unstable(feature = "slice_rsplit", issue = "41020")]
+    fn rsplit_mut<P>(&mut self, pred: P) -> RSplitMut<Self::Item, P>
+        where P: FnMut(&Self::Item) -> bool;
+
     #[stable(feature = "core", since = "1.6.0")]
     fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<Self::Item, P>
         where P: FnMut(&Self::Item) -> bool;
@@ -293,6 +301,13 @@ fn split<P>(&self, pred: P) -> Split<T, P>
         }
     }
 
+    #[inline]
+    fn rsplit<P>(&self, pred: P) -> RSplit<T, P>
+        where P: FnMut(&T) -> bool
+    {
+        RSplit { inner: self.split(pred) }
+    }
+
     #[inline]
     fn splitn<P>(&self, n: usize, pred: P) -> SplitN<T, P>
         where P: FnMut(&T) -> bool
@@ -300,8 +315,7 @@ fn splitn<P>(&self, n: usize, pred: P) -> SplitN<T, P>
         SplitN {
             inner: GenericSplitN {
                 iter: self.split(pred),
-                count: n,
-                invert: false
+                count: n
             }
         }
     }
@@ -312,9 +326,8 @@ fn rsplitn<P>(&self, n: usize, pred: P) -> RSplitN<T, P>
     {
         RSplitN {
             inner: GenericSplitN {
-                iter: self.split(pred),
-                count: n,
-                invert: true
+                iter: self.rsplit(pred),
+                count: n
             }
         }
     }
@@ -475,6 +488,13 @@ fn split_mut<P>(&mut self, pred: P) -> SplitMut<T, P>
         SplitMut { v: self, pred: pred, finished: false }
     }
 
+    #[inline]
+    fn rsplit_mut<P>(&mut self, pred: P) -> RSplitMut<T, P>
+        where P: FnMut(&T) -> bool
+    {
+        RSplitMut { inner: self.split_mut(pred) }
+    }
+
     #[inline]
     fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<T, P>
         where P: FnMut(&T) -> bool
@@ -482,8 +502,7 @@ fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<T, P>
         SplitNMut {
             inner: GenericSplitN {
                 iter: self.split_mut(pred),
-                count: n,
-                invert: false
+                count: n
             }
         }
     }
@@ -494,9 +513,8 @@ fn rsplitn_mut<P>(&mut self, n: usize, pred: P) -> RSplitNMut<T, P> where
     {
         RSplitNMut {
             inner: GenericSplitN {
-                iter: self.split_mut(pred),
-                count: n,
-                invert: true
+                iter: self.rsplit_mut(pred),
+                count: n
             }
         }
     }
@@ -1498,9 +1516,10 @@ unsafe impl<'a, T> TrustedLen for IterMut<'a, T> {}
 // Return the arithmetic difference if `T` is zero size.
 #[inline(always)]
 fn ptrdistance<T>(start: *const T, end: *const T) -> usize {
-    let diff = (end as usize).wrapping_sub(start as usize);
-    let size = mem::size_of::<T>();
-    diff / (if size == 0 { 1 } else { size })
+    match start.offset_to(end) {
+        Some(x) => x as usize,
+        None => (end as usize).wrapping_sub(start as usize),
+    }
 }
 
 // Extension methods for raw pointers, used by the iterators
@@ -1735,6 +1754,123 @@ fn next_back(&mut self) -> Option<&'a mut [T]> {
 #[unstable(feature = "fused", issue = "35602")]
 impl<'a, T, P> FusedIterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool {}
 
+/// An iterator over subslices separated by elements that match a predicate
+/// function, starting from the end of the slice.
+///
+/// This struct is created by the [`rsplit`] method on [slices].
+///
+/// [`rsplit`]: ../../std/primitive.slice.html#method.rsplit
+/// [slices]: ../../std/primitive.slice.html
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+#[derive(Clone)] // Is this correct, or does it incorrectly require `T: Clone`?
+pub struct RSplit<'a, T:'a, P> where P: FnMut(&T) -> bool {
+    inner: Split<'a, T, P>
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for RSplit<'a, T, P> where P: FnMut(&T) -> bool {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("RSplit")
+            .field("v", &self.inner.v)
+            .field("finished", &self.inner.finished)
+            .finish()
+    }
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> Iterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool {
+    type Item = &'a [T];
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a [T]> {
+        self.inner.next_back()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.inner.size_hint()
+    }
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> DoubleEndedIterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool {
+    #[inline]
+    fn next_back(&mut self) -> Option<&'a [T]> {
+        self.inner.next()
+    }
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> SplitIter for RSplit<'a, T, P> where P: FnMut(&T) -> bool {
+    #[inline]
+    fn finish(&mut self) -> Option<&'a [T]> {
+        self.inner.finish()
+    }
+}
+
+//#[unstable(feature = "fused", issue = "35602")]
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> FusedIterator for RSplit<'a, T, P> where P: FnMut(&T) -> bool {}
+
+/// An iterator over the subslices of the vector which are separated
+/// by elements that match `pred`, starting from the end of the slice.
+///
+/// This struct is created by the [`rsplit_mut`] method on [slices].
+///
+/// [`rsplit_mut`]: ../../std/primitive.slice.html#method.rsplit_mut
+/// [slices]: ../../std/primitive.slice.html
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+pub struct RSplitMut<'a, T:'a, P> where P: FnMut(&T) -> bool {
+    inner: SplitMut<'a, T, P>
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("RSplitMut")
+            .field("v", &self.inner.v)
+            .field("finished", &self.inner.finished)
+            .finish()
+    }
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> SplitIter for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool {
+    #[inline]
+    fn finish(&mut self) -> Option<&'a mut [T]> {
+        self.inner.finish()
+    }
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> Iterator for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool {
+    type Item = &'a mut [T];
+
+    #[inline]
+    fn next(&mut self) -> Option<&'a mut [T]> {
+        self.inner.next_back()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.inner.size_hint()
+    }
+}
+
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> DoubleEndedIterator for RSplitMut<'a, T, P> where
+    P: FnMut(&T) -> bool,
+{
+    #[inline]
+    fn next_back(&mut self) -> Option<&'a mut [T]> {
+        self.inner.next()
+    }
+}
+
+//#[unstable(feature = "fused", issue = "35602")]
+#[unstable(feature = "slice_rsplit", issue = "41020")]
+impl<'a, T, P> FusedIterator for RSplitMut<'a, T, P> where P: FnMut(&T) -> bool {}
+
 /// An private iterator over subslices separated by elements that
 /// match a predicate function, splitting at most a fixed number of
 /// times.
@@ -1742,7 +1878,6 @@ impl<'a, T, P> FusedIterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool {
 struct GenericSplitN<I> {
     iter: I,
     count: usize,
-    invert: bool
 }
 
 impl<T, I: SplitIter<Item=T>> Iterator for GenericSplitN<I> {
@@ -1753,10 +1888,7 @@ fn next(&mut self) -> Option<T> {
         match self.count {
             0 => None,
             1 => { self.count -= 1; self.iter.finish() }
-            _ => {
-                self.count -= 1;
-                if self.invert {self.iter.next_back()} else {self.iter.next()}
-            }
+            _ => { self.count -= 1; self.iter.next() }
         }
     }
 
@@ -1798,7 +1930,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// [slices]: ../../std/primitive.slice.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RSplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool {
-    inner: GenericSplitN<Split<'a, T, P>>
+    inner: GenericSplitN<RSplit<'a, T, P>>
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
@@ -1841,7 +1973,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 /// [slices]: ../../std/primitive.slice.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RSplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool {
-    inner: GenericSplitN<SplitMut<'a, T, P>>
+    inner: GenericSplitN<RSplitMut<'a, T, P>>
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
index f75a1f7ab6e0f07fa720b8abf8a81f8bfb0f9515..352cc926994e3685ae5ca5554eba5f9fbfd3e3c6 100644 (file)
@@ -152,11 +152,16 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 Section: Creating a string
 */
 
-/// Errors which can occur when attempting to interpret a sequence of `u8`
+/// Errors which can occur when attempting to interpret a sequence of [`u8`]
 /// as a string.
 ///
-/// As such, the `from_utf8` family of functions and methods for both `String`s
-/// and `&str`s make use of this error, for example.
+/// [`u8`]: ../../std/primitive.u8.html
+///
+/// As such, the `from_utf8` family of functions and methods for both [`String`]s
+/// and [`&str`]s make use of this error, for example.
+///
+/// [`String`]: ../../std/string/struct.String.html#method.from_utf8
+/// [`&str`]: ../../std/str/fn.from_utf8.html
 #[derive(Copy, Eq, PartialEq, Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Utf8Error {
@@ -210,11 +215,15 @@ pub fn error_len(&self) -> Option<usize> {
 
 /// Converts a slice of bytes to a string slice.
 ///
-/// A string slice (`&str`) is made of bytes (`u8`), and a byte slice (`&[u8]`)
-/// is made of bytes, so this function converts between the two. Not all byte
-/// slices are valid string slices, however: `&str` requires that it is valid
-/// UTF-8. `from_utf8()` checks to ensure that the bytes are valid UTF-8, and
-/// then does the conversion.
+/// A string slice ([`&str`]) is made of bytes ([`u8`]), and a byte slice
+/// ([`&[u8]`][byteslice]) is made of bytes, so this function converts between
+/// the two. Not all byte slices are valid string slices, however: [`&str`] requires
+/// that it is valid UTF-8. `from_utf8()` checks to ensure that the bytes are valid
+/// UTF-8, and then does the conversion.
+///
+/// [`&str`]: ../../std/primitive.str.html
+/// [`u8`]: ../../std/primitive.u8.html
+/// [byteslice]: ../../std/primitive.slice.html
 ///
 /// If you are sure that the byte slice is valid UTF-8, and you don't want to
 /// incur the overhead of the validity check, there is an unsafe version of
@@ -228,9 +237,12 @@ pub fn error_len(&self) -> Option<usize> {
 ///
 /// [string]: ../../std/string/struct.String.html#method.from_utf8
 ///
-/// Because you can stack-allocate a `[u8; N]`, and you can take a `&[u8]` of
-/// it, this function is one way to have a stack-allocated string. There is
-/// an example of this in the examples section below.
+/// Because you can stack-allocate a `[u8; N]`, and you can take a
+/// [`&[u8]`][byteslice] of it, this function is one way to have a
+/// stack-allocated string. There is an example of this in the
+/// examples section below.
+///
+/// [byteslice]: ../../std/primitive.slice.html
 ///
 /// # Errors
 ///
index ae47e6fdfa928ee6b037d9d7e1c1e80cd74bfdfc..4e5ddfb541e8913aafa28a928b7a43f91be7fa25 100644 (file)
@@ -321,7 +321,7 @@ pub fn store(&self, val: bool, order: Ordering) {
         }
     }
 
-    /// Stores a value into the bool, returning the old value.
+    /// Stores a value into the bool, returning the previous value.
     ///
     /// `swap` takes an [`Ordering`] argument which describes the memory ordering
     /// of this operation.
@@ -732,7 +732,7 @@ pub fn store(&self, ptr: *mut T, order: Ordering) {
         }
     }
 
-    /// Stores a value into the pointer, returning the old value.
+    /// Stores a value into the pointer, returning the previous value.
     ///
     /// `swap` takes an [`Ordering`] argument which describes the memory ordering
     /// of this operation.
@@ -1047,7 +1047,7 @@ pub fn store(&self, val: $int_type, order: Ordering) {
                 unsafe { atomic_store(self.v.get(), val, order); }
             }
 
-            /// Stores a value into the atomic integer, returning the old value.
+            /// Stores a value into the atomic integer, returning the previous value.
             ///
             /// `swap` takes an [`Ordering`] argument which describes the memory ordering of this
             /// operation.
@@ -1201,7 +1201,9 @@ pub fn compare_exchange_weak(&self,
                 }
             }
 
-            /// Add to the current value, returning the previous value.
+            /// Adds to the current value, returning the previous value.
+            ///
+            /// This operation wraps around on overflow.
             ///
             /// # Examples
             ///
@@ -1218,7 +1220,9 @@ pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
                 unsafe { atomic_add(self.v.get(), val, order) }
             }
 
-            /// Subtract from the current value, returning the previous value.
+            /// Subtracts from the current value, returning the previous value.
+            ///
+            /// This operation wraps around on overflow.
             ///
             /// # Examples
             ///
@@ -1235,7 +1239,12 @@ pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
                 unsafe { atomic_sub(self.v.get(), val, order) }
             }
 
-            /// Bitwise and with the current value, returning the previous value.
+            /// Bitwise "and" with the current value.
+            ///
+            /// Performs a bitwise "and" operation on the current value and the argument `val`, and
+            /// sets the new value to the result.
+            ///
+            /// Returns the previous value.
             ///
             /// # Examples
             ///
@@ -1251,7 +1260,12 @@ pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
                 unsafe { atomic_and(self.v.get(), val, order) }
             }
 
-            /// Bitwise or with the current value, returning the previous value.
+            /// Bitwise "or" with the current value.
+            ///
+            /// Performs a bitwise "or" operation on the current value and the argument `val`, and
+            /// sets the new value to the result.
+            ///
+            /// Returns the previous value.
             ///
             /// # Examples
             ///
@@ -1267,7 +1281,12 @@ pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
                 unsafe { atomic_or(self.v.get(), val, order) }
             }
 
-            /// Bitwise xor with the current value, returning the previous value.
+            /// Bitwise "xor" with the current value.
+            ///
+            /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
+            /// sets the new value to the result.
+            ///
+            /// Returns the previous value.
             ///
             /// # Examples
             ///
@@ -1415,7 +1434,7 @@ unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
     }
 }
 
-/// Returns the old value (like __sync_fetch_and_add).
+/// Returns the previous value (like __sync_fetch_and_add).
 #[inline]
 unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
     match order {
@@ -1428,7 +1447,7 @@ unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
     }
 }
 
-/// Returns the old value (like __sync_fetch_and_sub).
+/// Returns the previous value (like __sync_fetch_and_sub).
 #[inline]
 unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
     match order {
diff --git a/src/libcore/tests/any.rs b/src/libcore/tests/any.rs
new file mode 100644 (file)
index 0000000..2d3e81a
--- /dev/null
@@ -0,0 +1,125 @@
+// 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 core::any::*;
+
+#[derive(PartialEq, Debug)]
+struct Test;
+
+static TEST: &'static str = "Test";
+
+#[test]
+fn any_referenced() {
+    let (a, b, c) = (&5 as &Any, &TEST as &Any, &Test as &Any);
+
+    assert!(a.is::<i32>());
+    assert!(!b.is::<i32>());
+    assert!(!c.is::<i32>());
+
+    assert!(!a.is::<&'static str>());
+    assert!(b.is::<&'static str>());
+    assert!(!c.is::<&'static str>());
+
+    assert!(!a.is::<Test>());
+    assert!(!b.is::<Test>());
+    assert!(c.is::<Test>());
+}
+
+#[test]
+fn any_owning() {
+    let (a, b, c) = (box 5_usize as Box<Any>, box TEST as Box<Any>, box Test as Box<Any>);
+
+    assert!(a.is::<usize>());
+    assert!(!b.is::<usize>());
+    assert!(!c.is::<usize>());
+
+    assert!(!a.is::<&'static str>());
+    assert!(b.is::<&'static str>());
+    assert!(!c.is::<&'static str>());
+
+    assert!(!a.is::<Test>());
+    assert!(!b.is::<Test>());
+    assert!(c.is::<Test>());
+}
+
+#[test]
+fn any_downcast_ref() {
+    let a = &5_usize as &Any;
+
+    match a.downcast_ref::<usize>() {
+        Some(&5) => {}
+        x => panic!("Unexpected value {:?}", x)
+    }
+
+    match a.downcast_ref::<Test>() {
+        None => {}
+        x => panic!("Unexpected value {:?}", x)
+    }
+}
+
+#[test]
+fn any_downcast_mut() {
+    let mut a = 5_usize;
+    let mut b: Box<_> = box 7_usize;
+
+    let a_r = &mut a as &mut Any;
+    let tmp: &mut usize = &mut *b;
+    let b_r = tmp as &mut Any;
+
+    match a_r.downcast_mut::<usize>() {
+        Some(x) => {
+            assert_eq!(*x, 5);
+            *x = 612;
+        }
+        x => panic!("Unexpected value {:?}", x)
+    }
+
+    match b_r.downcast_mut::<usize>() {
+        Some(x) => {
+            assert_eq!(*x, 7);
+            *x = 413;
+        }
+        x => panic!("Unexpected value {:?}", x)
+    }
+
+    match a_r.downcast_mut::<Test>() {
+        None => (),
+        x => panic!("Unexpected value {:?}", x)
+    }
+
+    match b_r.downcast_mut::<Test>() {
+        None => (),
+        x => panic!("Unexpected value {:?}", x)
+    }
+
+    match a_r.downcast_mut::<usize>() {
+        Some(&mut 612) => {}
+        x => panic!("Unexpected value {:?}", x)
+    }
+
+    match b_r.downcast_mut::<usize>() {
+        Some(&mut 413) => {}
+        x => panic!("Unexpected value {:?}", x)
+    }
+}
+
+#[test]
+fn any_fixed_vec() {
+    let test = [0_usize; 8];
+    let test = &test as &Any;
+    assert!(test.is::<[usize; 8]>());
+    assert!(!test.is::<[usize; 10]>());
+}
+
+#[test]
+fn any_unsized() {
+    fn is_any<T: Any + ?Sized>() {}
+    is_any::<[i32]>();
+}
diff --git a/src/libcore/tests/array.rs b/src/libcore/tests/array.rs
new file mode 100644 (file)
index 0000000..6af031d
--- /dev/null
@@ -0,0 +1,28 @@
+// 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 core::array::FixedSizeArray;
+
+#[test]
+fn fixed_size_array() {
+    let mut array = [0; 64];
+    let mut zero_sized = [(); 64];
+    let mut empty_array = [0; 0];
+    let mut empty_zero_sized = [(); 0];
+
+    assert_eq!(FixedSizeArray::as_slice(&array).len(), 64);
+    assert_eq!(FixedSizeArray::as_slice(&zero_sized).len(), 64);
+    assert_eq!(FixedSizeArray::as_slice(&empty_array).len(), 0);
+    assert_eq!(FixedSizeArray::as_slice(&empty_zero_sized).len(), 0);
+
+    assert_eq!(FixedSizeArray::as_mut_slice(&mut array).len(), 64);
+    assert_eq!(FixedSizeArray::as_mut_slice(&mut zero_sized).len(), 64);
+    assert_eq!(FixedSizeArray::as_mut_slice(&mut empty_array).len(), 0);
+    assert_eq!(FixedSizeArray::as_mut_slice(&mut empty_zero_sized).len(), 0);
+}
diff --git a/src/libcore/tests/atomic.rs b/src/libcore/tests/atomic.rs
new file mode 100644 (file)
index 0000000..b6bb5fd
--- /dev/null
@@ -0,0 +1,84 @@
+// 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 core::sync::atomic::*;
+use core::sync::atomic::Ordering::SeqCst;
+
+#[test]
+fn bool_() {
+    let a = AtomicBool::new(false);
+    assert_eq!(a.compare_and_swap(false, true, SeqCst), false);
+    assert_eq!(a.compare_and_swap(false, true, SeqCst), true);
+
+    a.store(false, SeqCst);
+    assert_eq!(a.compare_and_swap(false, true, SeqCst), false);
+}
+
+#[test]
+fn bool_and() {
+    let a = AtomicBool::new(true);
+    assert_eq!(a.fetch_and(false, SeqCst),true);
+    assert_eq!(a.load(SeqCst),false);
+}
+
+#[test]
+fn uint_and() {
+    let x = AtomicUsize::new(0xf731);
+    assert_eq!(x.fetch_and(0x137f, SeqCst), 0xf731);
+    assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
+}
+
+#[test]
+fn uint_or() {
+    let x = AtomicUsize::new(0xf731);
+    assert_eq!(x.fetch_or(0x137f, SeqCst), 0xf731);
+    assert_eq!(x.load(SeqCst), 0xf731 | 0x137f);
+}
+
+#[test]
+fn uint_xor() {
+    let x = AtomicUsize::new(0xf731);
+    assert_eq!(x.fetch_xor(0x137f, SeqCst), 0xf731);
+    assert_eq!(x.load(SeqCst), 0xf731 ^ 0x137f);
+}
+
+#[test]
+fn int_and() {
+    let x = AtomicIsize::new(0xf731);
+    assert_eq!(x.fetch_and(0x137f, SeqCst), 0xf731);
+    assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
+}
+
+#[test]
+fn int_or() {
+    let x = AtomicIsize::new(0xf731);
+    assert_eq!(x.fetch_or(0x137f, SeqCst), 0xf731);
+    assert_eq!(x.load(SeqCst), 0xf731 | 0x137f);
+}
+
+#[test]
+fn int_xor() {
+    let x = AtomicIsize::new(0xf731);
+    assert_eq!(x.fetch_xor(0x137f, SeqCst), 0xf731);
+    assert_eq!(x.load(SeqCst), 0xf731 ^ 0x137f);
+}
+
+static S_FALSE: AtomicBool = AtomicBool::new(false);
+static S_TRUE: AtomicBool = AtomicBool::new(true);
+static S_INT: AtomicIsize  = AtomicIsize::new(0);
+static S_UINT: AtomicUsize = AtomicUsize::new(0);
+
+#[test]
+fn static_init() {
+    assert!(!S_FALSE.load(SeqCst));
+    assert!(S_TRUE.load(SeqCst));
+    assert!(S_INT.load(SeqCst) == 0);
+    assert!(S_UINT.load(SeqCst) == 0);
+}
diff --git a/src/libcore/tests/cell.rs b/src/libcore/tests/cell.rs
new file mode 100644 (file)
index 0000000..8585f2f
--- /dev/null
@@ -0,0 +1,289 @@
+// 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 core::cell::*;
+use core::default::Default;
+use std::mem::drop;
+
+#[test]
+fn smoketest_cell() {
+    let x = Cell::new(10);
+    assert!(x == Cell::new(10));
+    assert!(x.get() == 10);
+    x.set(20);
+    assert!(x == Cell::new(20));
+    assert!(x.get() == 20);
+
+    let y = Cell::new((30, 40));
+    assert!(y == Cell::new((30, 40)));
+    assert!(y.get() == (30, 40));
+}
+
+#[test]
+fn cell_has_sensible_show() {
+    let x = Cell::new("foo bar");
+    assert!(format!("{:?}", x).contains(x.get()));
+
+    x.set("baz qux");
+    assert!(format!("{:?}", x).contains(x.get()));
+}
+
+#[test]
+fn ref_and_refmut_have_sensible_show() {
+    let refcell = RefCell::new("foo");
+
+    let refcell_refmut = refcell.borrow_mut();
+    assert!(format!("{:?}", refcell_refmut).contains("foo"));
+    drop(refcell_refmut);
+
+    let refcell_ref = refcell.borrow();
+    assert!(format!("{:?}", refcell_ref).contains("foo"));
+    drop(refcell_ref);
+}
+
+#[test]
+fn double_imm_borrow() {
+    let x = RefCell::new(0);
+    let _b1 = x.borrow();
+    x.borrow();
+}
+
+#[test]
+fn no_mut_then_imm_borrow() {
+    let x = RefCell::new(0);
+    let _b1 = x.borrow_mut();
+    assert!(x.try_borrow().is_err());
+}
+
+#[test]
+fn no_imm_then_borrow_mut() {
+    let x = RefCell::new(0);
+    let _b1 = x.borrow();
+    assert!(x.try_borrow_mut().is_err());
+}
+
+#[test]
+fn no_double_borrow_mut() {
+    let x = RefCell::new(0);
+    assert!(x.try_borrow().is_ok());
+    let _b1 = x.borrow_mut();
+    assert!(x.try_borrow().is_err());
+}
+
+#[test]
+fn imm_release_borrow_mut() {
+    let x = RefCell::new(0);
+    {
+        let _b1 = x.borrow();
+    }
+    x.borrow_mut();
+}
+
+#[test]
+fn mut_release_borrow_mut() {
+    let x = RefCell::new(0);
+    {
+        let _b1 = x.borrow_mut();
+    }
+    x.borrow();
+}
+
+#[test]
+fn double_borrow_single_release_no_borrow_mut() {
+    let x = RefCell::new(0);
+    let _b1 = x.borrow();
+    {
+        let _b2 = x.borrow();
+    }
+    assert!(x.try_borrow().is_ok());
+    assert!(x.try_borrow_mut().is_err());
+}
+
+#[test]
+#[should_panic]
+fn discard_doesnt_unborrow() {
+    let x = RefCell::new(0);
+    let _b = x.borrow();
+    let _ = _b;
+    let _b = x.borrow_mut();
+}
+
+#[test]
+fn ref_clone_updates_flag() {
+    let x = RefCell::new(0);
+    {
+        let b1 = x.borrow();
+        assert!(x.try_borrow().is_ok());
+        assert!(x.try_borrow_mut().is_err());
+        {
+            let _b2 = Ref::clone(&b1);
+            assert!(x.try_borrow().is_ok());
+            assert!(x.try_borrow_mut().is_err());
+        }
+        assert!(x.try_borrow().is_ok());
+        assert!(x.try_borrow_mut().is_err());
+    }
+    assert!(x.try_borrow().is_ok());
+    assert!(x.try_borrow_mut().is_ok());
+}
+
+#[test]
+fn ref_map_does_not_update_flag() {
+    let x = RefCell::new(Some(5));
+    {
+        let b1: Ref<Option<u32>> = x.borrow();
+        assert!(x.try_borrow().is_ok());
+        assert!(x.try_borrow_mut().is_err());
+        {
+            let b2: Ref<u32> = Ref::map(b1, |o| o.as_ref().unwrap());
+            assert_eq!(*b2, 5);
+            assert!(x.try_borrow().is_ok());
+            assert!(x.try_borrow_mut().is_err());
+        }
+        assert!(x.try_borrow().is_ok());
+        assert!(x.try_borrow_mut().is_ok());
+    }
+    assert!(x.try_borrow().is_ok());
+    assert!(x.try_borrow_mut().is_ok());
+}
+
+#[test]
+fn ref_map_accessor() {
+    struct X(RefCell<(u32, char)>);
+    impl X {
+        fn accessor(&self) -> Ref<u32> {
+            Ref::map(self.0.borrow(), |tuple| &tuple.0)
+        }
+    }
+    let x = X(RefCell::new((7, 'z')));
+    let d: Ref<u32> = x.accessor();
+    assert_eq!(*d, 7);
+}
+
+#[test]
+fn ref_mut_map_accessor() {
+    struct X(RefCell<(u32, char)>);
+    impl X {
+        fn accessor(&self) -> RefMut<u32> {
+            RefMut::map(self.0.borrow_mut(), |tuple| &mut tuple.0)
+        }
+    }
+    let x = X(RefCell::new((7, 'z')));
+    {
+        let mut d: RefMut<u32> = x.accessor();
+        assert_eq!(*d, 7);
+        *d += 1;
+    }
+    assert_eq!(*x.0.borrow(), (8, 'z'));
+}
+
+#[test]
+fn as_ptr() {
+    let c1: Cell<usize> = Cell::new(0);
+    c1.set(1);
+    assert_eq!(1, unsafe { *c1.as_ptr() });
+
+    let c2: Cell<usize> = Cell::new(0);
+    unsafe { *c2.as_ptr() = 1; }
+    assert_eq!(1, c2.get());
+
+    let r1: RefCell<usize> = RefCell::new(0);
+    *r1.borrow_mut() = 1;
+    assert_eq!(1, unsafe { *r1.as_ptr() });
+
+    let r2: RefCell<usize> = RefCell::new(0);
+    unsafe { *r2.as_ptr() = 1; }
+    assert_eq!(1, *r2.borrow());
+}
+
+#[test]
+fn cell_default() {
+    let cell: Cell<u32> = Default::default();
+    assert_eq!(0, cell.get());
+}
+
+#[test]
+fn cell_set() {
+    let cell = Cell::new(10);
+    cell.set(20);
+    assert_eq!(20, cell.get());
+
+    let cell = Cell::new("Hello".to_owned());
+    cell.set("World".to_owned());
+    assert_eq!("World".to_owned(), cell.into_inner());
+}
+
+#[test]
+fn cell_replace() {
+    let cell = Cell::new(10);
+    assert_eq!(10, cell.replace(20));
+    assert_eq!(20, cell.get());
+
+    let cell = Cell::new("Hello".to_owned());
+    assert_eq!("Hello".to_owned(), cell.replace("World".to_owned()));
+    assert_eq!("World".to_owned(), cell.into_inner());
+}
+
+#[test]
+fn cell_into_inner() {
+    let cell = Cell::new(10);
+    assert_eq!(10, cell.into_inner());
+
+    let cell = Cell::new("Hello world".to_owned());
+    assert_eq!("Hello world".to_owned(), cell.into_inner());
+}
+
+#[test]
+fn refcell_default() {
+    let cell: RefCell<u64> = Default::default();
+    assert_eq!(0, *cell.borrow());
+}
+
+#[test]
+fn unsafe_cell_unsized() {
+    let cell: &UnsafeCell<[i32]> = &UnsafeCell::new([1, 2, 3]);
+    {
+        let val: &mut [i32] = unsafe { &mut *cell.get() };
+        val[0] = 4;
+        val[2] = 5;
+    }
+    let comp: &mut [i32] = &mut [4, 2, 5];
+    assert_eq!(unsafe { &mut *cell.get() }, comp);
+}
+
+#[test]
+fn refcell_unsized() {
+    let cell: &RefCell<[i32]> = &RefCell::new([1, 2, 3]);
+    {
+        let b = &mut *cell.borrow_mut();
+        b[0] = 4;
+        b[2] = 5;
+    }
+    let comp: &mut [i32] = &mut [4, 2, 5];
+    assert_eq!(&*cell.borrow(), comp);
+}
+
+#[test]
+fn refcell_ref_coercion() {
+    let cell: RefCell<[i32; 3]> = RefCell::new([1, 2, 3]);
+    {
+        let mut cellref: RefMut<[i32; 3]> = cell.borrow_mut();
+        cellref[0] = 4;
+        let mut coerced: RefMut<[i32]> = cellref;
+        coerced[2] = 5;
+    }
+    {
+        let comp: &mut [i32] = &mut [4, 2, 5];
+        let cellref: Ref<[i32; 3]> = cell.borrow();
+        assert_eq!(&*cellref, comp);
+        let coerced: Ref<[i32]> = cellref;
+        assert_eq!(&*coerced, comp);
+    }
+}
diff --git a/src/libcore/tests/char.rs b/src/libcore/tests/char.rs
new file mode 100644 (file)
index 0000000..e4012ec
--- /dev/null
@@ -0,0 +1,404 @@
+// 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::{char,str};
+use std::convert::TryFrom;
+
+#[test]
+fn test_convert() {
+    assert_eq!(u32::from('a'), 0x61);
+    assert_eq!(char::from(b'\0'), '\0');
+    assert_eq!(char::from(b'a'), 'a');
+    assert_eq!(char::from(b'\xFF'), '\u{FF}');
+    assert_eq!(char::try_from(0_u32), Ok('\0'));
+    assert_eq!(char::try_from(0x61_u32), Ok('a'));
+    assert_eq!(char::try_from(0xD7FF_u32), Ok('\u{D7FF}'));
+    assert!(char::try_from(0xD800_u32).is_err());
+    assert!(char::try_from(0xDFFF_u32).is_err());
+    assert_eq!(char::try_from(0xE000_u32), Ok('\u{E000}'));
+    assert_eq!(char::try_from(0x10FFFF_u32), Ok('\u{10FFFF}'));
+    assert!(char::try_from(0x110000_u32).is_err());
+    assert!(char::try_from(0xFFFF_FFFF_u32).is_err());
+}
+
+#[test]
+fn test_is_lowercase() {
+    assert!('a'.is_lowercase());
+    assert!('ö'.is_lowercase());
+    assert!('ß'.is_lowercase());
+    assert!(!'Ü'.is_lowercase());
+    assert!(!'P'.is_lowercase());
+}
+
+#[test]
+fn test_is_uppercase() {
+    assert!(!'h'.is_uppercase());
+    assert!(!'ä'.is_uppercase());
+    assert!(!'ß'.is_uppercase());
+    assert!('Ö'.is_uppercase());
+    assert!('T'.is_uppercase());
+}
+
+#[test]
+fn test_is_whitespace() {
+    assert!(' '.is_whitespace());
+    assert!('\u{2007}'.is_whitespace());
+    assert!('\t'.is_whitespace());
+    assert!('\n'.is_whitespace());
+    assert!(!'a'.is_whitespace());
+    assert!(!'_'.is_whitespace());
+    assert!(!'\u{0}'.is_whitespace());
+}
+
+#[test]
+fn test_to_digit() {
+    assert_eq!('0'.to_digit(10), Some(0));
+    assert_eq!('1'.to_digit(2), Some(1));
+    assert_eq!('2'.to_digit(3), Some(2));
+    assert_eq!('9'.to_digit(10), Some(9));
+    assert_eq!('a'.to_digit(16), Some(10));
+    assert_eq!('A'.to_digit(16), Some(10));
+    assert_eq!('b'.to_digit(16), Some(11));
+    assert_eq!('B'.to_digit(16), Some(11));
+    assert_eq!('z'.to_digit(36), Some(35));
+    assert_eq!('Z'.to_digit(36), Some(35));
+    assert_eq!(' '.to_digit(10), None);
+    assert_eq!('$'.to_digit(36), None);
+}
+
+#[test]
+fn test_to_lowercase() {
+    fn lower(c: char) -> String {
+        let iter: String = c.to_lowercase().collect();
+        let disp: String = c.to_lowercase().to_string();
+        assert_eq!(iter, disp);
+        iter
+    }
+    assert_eq!(lower('A'), "a");
+    assert_eq!(lower('Ö'), "ö");
+    assert_eq!(lower('ß'), "ß");
+    assert_eq!(lower('Ü'), "ü");
+    assert_eq!(lower('💩'), "💩");
+    assert_eq!(lower('Σ'), "σ");
+    assert_eq!(lower('Τ'), "τ");
+    assert_eq!(lower('Ι'), "ι");
+    assert_eq!(lower('Γ'), "γ");
+    assert_eq!(lower('Μ'), "μ");
+    assert_eq!(lower('Α'), "α");
+    assert_eq!(lower('Σ'), "σ");
+    assert_eq!(lower('Dž'), "dž");
+    assert_eq!(lower('fi'), "fi");
+    assert_eq!(lower('İ'), "i\u{307}");
+}
+
+#[test]
+fn test_to_uppercase() {
+    fn upper(c: char) -> String {
+        let iter: String = c.to_uppercase().collect();
+        let disp: String = c.to_uppercase().to_string();
+        assert_eq!(iter, disp);
+        iter
+    }
+    assert_eq!(upper('a'), "A");
+    assert_eq!(upper('ö'), "Ö");
+    assert_eq!(upper('ß'), "SS"); // not ẞ: Latin capital letter sharp s
+    assert_eq!(upper('ü'), "Ü");
+    assert_eq!(upper('💩'), "💩");
+
+    assert_eq!(upper('σ'), "Σ");
+    assert_eq!(upper('τ'), "Τ");
+    assert_eq!(upper('ι'), "Ι");
+    assert_eq!(upper('γ'), "Γ");
+    assert_eq!(upper('μ'), "Μ");
+    assert_eq!(upper('α'), "Α");
+    assert_eq!(upper('ς'), "Σ");
+    assert_eq!(upper('Dž'), "DŽ");
+    assert_eq!(upper('fi'), "FI");
+    assert_eq!(upper('ᾀ'), "ἈΙ");
+}
+
+#[test]
+fn test_is_control() {
+    assert!('\u{0}'.is_control());
+    assert!('\u{3}'.is_control());
+    assert!('\u{6}'.is_control());
+    assert!('\u{9}'.is_control());
+    assert!('\u{7f}'.is_control());
+    assert!('\u{92}'.is_control());
+    assert!(!'\u{20}'.is_control());
+    assert!(!'\u{55}'.is_control());
+    assert!(!'\u{68}'.is_control());
+}
+
+#[test]
+fn test_is_digit() {
+   assert!('2'.is_numeric());
+   assert!('7'.is_numeric());
+   assert!(!'c'.is_numeric());
+   assert!(!'i'.is_numeric());
+   assert!(!'z'.is_numeric());
+   assert!(!'Q'.is_numeric());
+}
+
+#[test]
+fn test_escape_debug() {
+    fn string(c: char) -> String {
+        let iter: String = c.escape_debug().collect();
+        let disp: String = c.escape_debug().to_string();
+        assert_eq!(iter, disp);
+        iter
+    }
+    assert_eq!(string('\n'), "\\n");
+    assert_eq!(string('\r'), "\\r");
+    assert_eq!(string('\''), "\\'");
+    assert_eq!(string('"'), "\\\"");
+    assert_eq!(string(' '), " ");
+    assert_eq!(string('a'), "a");
+    assert_eq!(string('~'), "~");
+    assert_eq!(string('é'), "é");
+    assert_eq!(string('文'), "文");
+    assert_eq!(string('\x00'), "\\u{0}");
+    assert_eq!(string('\x1f'), "\\u{1f}");
+    assert_eq!(string('\x7f'), "\\u{7f}");
+    assert_eq!(string('\u{80}'), "\\u{80}");
+    assert_eq!(string('\u{ff}'), "\u{ff}");
+    assert_eq!(string('\u{11b}'), "\u{11b}");
+    assert_eq!(string('\u{1d4b6}'), "\u{1d4b6}");
+    assert_eq!(string('\u{200b}'),"\\u{200b}");      // zero width space
+    assert_eq!(string('\u{e000}'), "\\u{e000}");     // private use 1
+    assert_eq!(string('\u{100000}'), "\\u{100000}"); // private use 2
+}
+
+#[test]
+fn test_escape_default() {
+    fn string(c: char) -> String {
+        let iter: String = c.escape_default().collect();
+        let disp: String = c.escape_default().to_string();
+        assert_eq!(iter, disp);
+        iter
+    }
+    assert_eq!(string('\n'), "\\n");
+    assert_eq!(string('\r'), "\\r");
+    assert_eq!(string('\''), "\\'");
+    assert_eq!(string('"'), "\\\"");
+    assert_eq!(string(' '), " ");
+    assert_eq!(string('a'), "a");
+    assert_eq!(string('~'), "~");
+    assert_eq!(string('é'), "\\u{e9}");
+    assert_eq!(string('\x00'), "\\u{0}");
+    assert_eq!(string('\x1f'), "\\u{1f}");
+    assert_eq!(string('\x7f'), "\\u{7f}");
+    assert_eq!(string('\u{80}'), "\\u{80}");
+    assert_eq!(string('\u{ff}'), "\\u{ff}");
+    assert_eq!(string('\u{11b}'), "\\u{11b}");
+    assert_eq!(string('\u{1d4b6}'), "\\u{1d4b6}");
+    assert_eq!(string('\u{200b}'), "\\u{200b}"); // zero width space
+    assert_eq!(string('\u{e000}'), "\\u{e000}"); // private use 1
+    assert_eq!(string('\u{100000}'), "\\u{100000}"); // private use 2
+}
+
+#[test]
+fn test_escape_unicode() {
+    fn string(c: char) -> String {
+        let iter: String = c.escape_unicode().collect();
+        let disp: String = c.escape_unicode().to_string();
+        assert_eq!(iter, disp);
+        iter
+    }
+
+    assert_eq!(string('\x00'), "\\u{0}");
+    assert_eq!(string('\n'), "\\u{a}");
+    assert_eq!(string(' '), "\\u{20}");
+    assert_eq!(string('a'), "\\u{61}");
+    assert_eq!(string('\u{11b}'), "\\u{11b}");
+    assert_eq!(string('\u{1d4b6}'), "\\u{1d4b6}");
+}
+
+#[test]
+fn test_encode_utf8() {
+    fn check(input: char, expect: &[u8]) {
+        let mut buf = [0; 4];
+        let ptr = buf.as_ptr();
+        let s = input.encode_utf8(&mut buf);
+        assert_eq!(s.as_ptr() as usize, ptr as usize);
+        assert!(str::from_utf8(s.as_bytes()).is_ok());
+        assert_eq!(s.as_bytes(), expect);
+    }
+
+    check('x', &[0x78]);
+    check('\u{e9}', &[0xc3, 0xa9]);
+    check('\u{a66e}', &[0xea, 0x99, 0xae]);
+    check('\u{1f4a9}', &[0xf0, 0x9f, 0x92, 0xa9]);
+}
+
+#[test]
+fn test_encode_utf16() {
+    fn check(input: char, expect: &[u16]) {
+        let mut buf = [0; 2];
+        let ptr = buf.as_mut_ptr();
+        let b = input.encode_utf16(&mut buf);
+        assert_eq!(b.as_mut_ptr() as usize, ptr as usize);
+        assert_eq!(b, expect);
+    }
+
+    check('x', &[0x0078]);
+    check('\u{e9}', &[0x00e9]);
+    check('\u{a66e}', &[0xa66e]);
+    check('\u{1f4a9}', &[0xd83d, 0xdca9]);
+}
+
+#[test]
+fn test_len_utf16() {
+    assert!('x'.len_utf16() == 1);
+    assert!('\u{e9}'.len_utf16() == 1);
+    assert!('\u{a66e}'.len_utf16() == 1);
+    assert!('\u{1f4a9}'.len_utf16() == 2);
+}
+
+#[test]
+fn test_decode_utf16() {
+    fn check(s: &[u16], expected: &[Result<char, u16>]) {
+        let v = char::decode_utf16(s.iter().cloned())
+                     .map(|r| r.map_err(|e| e.unpaired_surrogate()))
+                     .collect::<Vec<_>>();
+        assert_eq!(v, expected);
+    }
+    check(&[0xD800, 0x41, 0x42], &[Err(0xD800), Ok('A'), Ok('B')]);
+    check(&[0xD800, 0], &[Err(0xD800), Ok('\0')]);
+}
+
+#[test]
+fn ed_iterator_specializations() {
+    // Check counting
+    assert_eq!('\n'.escape_default().count(), 2);
+    assert_eq!('c'.escape_default().count(), 1);
+    assert_eq!(' '.escape_default().count(), 1);
+    assert_eq!('\\'.escape_default().count(), 2);
+    assert_eq!('\''.escape_default().count(), 2);
+
+    // Check nth
+
+    // Check that OoB is handled correctly
+    assert_eq!('\n'.escape_default().nth(2), None);
+    assert_eq!('c'.escape_default().nth(1), None);
+    assert_eq!(' '.escape_default().nth(1), None);
+    assert_eq!('\\'.escape_default().nth(2), None);
+    assert_eq!('\''.escape_default().nth(2), None);
+
+    // Check the first char
+    assert_eq!('\n'.escape_default().nth(0), Some('\\'));
+    assert_eq!('c'.escape_default().nth(0), Some('c'));
+    assert_eq!(' '.escape_default().nth(0), Some(' '));
+    assert_eq!('\\'.escape_default().nth(0), Some('\\'));
+    assert_eq!('\''.escape_default().nth(0), Some('\\'));
+
+    // Check the second char
+    assert_eq!('\n'.escape_default().nth(1), Some('n'));
+    assert_eq!('\\'.escape_default().nth(1), Some('\\'));
+    assert_eq!('\''.escape_default().nth(1), Some('\''));
+
+    // Check the last char
+    assert_eq!('\n'.escape_default().last(), Some('n'));
+    assert_eq!('c'.escape_default().last(), Some('c'));
+    assert_eq!(' '.escape_default().last(), Some(' '));
+    assert_eq!('\\'.escape_default().last(), Some('\\'));
+    assert_eq!('\''.escape_default().last(), Some('\''));
+}
+
+#[test]
+fn eu_iterator_specializations() {
+    fn check(c: char) {
+        let len = c.escape_unicode().count();
+
+        // Check OoB
+        assert_eq!(c.escape_unicode().nth(len), None);
+
+        // For all possible in-bound offsets
+        let mut iter = c.escape_unicode();
+        for offset in 0..len {
+            // Check last
+            assert_eq!(iter.clone().last(), Some('}'));
+
+            // Check len
+            assert_eq!(iter.len(), len - offset);
+
+            // Check size_hint (= len in ExactSizeIterator)
+            assert_eq!(iter.size_hint(), (iter.len(), Some(iter.len())));
+
+            // Check counting
+            assert_eq!(iter.clone().count(), len - offset);
+
+            // Check nth
+            assert_eq!(c.escape_unicode().nth(offset), iter.next());
+        }
+
+        // Check post-last
+        assert_eq!(iter.clone().last(), None);
+        assert_eq!(iter.clone().count(), 0);
+    }
+
+    check('\u{0}');
+    check('\u{1}');
+    check('\u{12}');
+    check('\u{123}');
+    check('\u{1234}');
+    check('\u{12340}');
+    check('\u{10FFFF}');
+}
+
+#[test]
+fn test_decode_utf8() {
+    macro_rules! assert_decode_utf8 {
+        ($input_bytes: expr, $expected_str: expr) => {
+            let input_bytes: &[u8] = &$input_bytes;
+            let s = char::decode_utf8(input_bytes.iter().cloned())
+                .map(|r_b| r_b.unwrap_or('\u{FFFD}'))
+                .collect::<String>();
+            assert_eq!(s, $expected_str,
+                       "input bytes: {:?}, expected str: {:?}, result: {:?}",
+                       input_bytes, $expected_str, s);
+            assert_eq!(String::from_utf8_lossy(&$input_bytes), $expected_str);
+        }
+    }
+
+    assert_decode_utf8!([], "");
+    assert_decode_utf8!([0x41], "A");
+    assert_decode_utf8!([0xC1, 0x81], "��");
+    assert_decode_utf8!([0xE2, 0x99, 0xA5], "♥");
+    assert_decode_utf8!([0xE2, 0x99, 0xA5, 0x41], "♥A");
+    assert_decode_utf8!([0xE2, 0x99], "�");
+    assert_decode_utf8!([0xE2, 0x99, 0x41], "�A");
+    assert_decode_utf8!([0xC0], "�");
+    assert_decode_utf8!([0xC0, 0x41], "�A");
+    assert_decode_utf8!([0x80], "�");
+    assert_decode_utf8!([0x80, 0x41], "�A");
+    assert_decode_utf8!([0xFE], "�");
+    assert_decode_utf8!([0xFE, 0x41], "�A");
+    assert_decode_utf8!([0xFF], "�");
+    assert_decode_utf8!([0xFF, 0x41], "�A");
+    assert_decode_utf8!([0xC0, 0x80], "��");
+
+    // Surrogates
+    assert_decode_utf8!([0xED, 0x9F, 0xBF], "\u{D7FF}");
+    assert_decode_utf8!([0xED, 0xA0, 0x80], "���");
+    assert_decode_utf8!([0xED, 0xBF, 0x80], "���");
+    assert_decode_utf8!([0xEE, 0x80, 0x80], "\u{E000}");
+
+    // char::MAX
+    assert_decode_utf8!([0xF4, 0x8F, 0xBF, 0xBF], "\u{10FFFF}");
+    assert_decode_utf8!([0xF4, 0x8F, 0xBF, 0x41], "�A");
+    assert_decode_utf8!([0xF4, 0x90, 0x80, 0x80], "����");
+
+    // 5 and 6 bytes sequence
+    // Part of the original design of UTF-8,
+    // but invalid now that UTF-8 is artificially restricted to match the range of UTF-16.
+    assert_decode_utf8!([0xF8, 0x80, 0x80, 0x80, 0x80], "�����");
+    assert_decode_utf8!([0xFC, 0x80, 0x80, 0x80, 0x80, 0x80], "������");
+}
diff --git a/src/libcore/tests/clone.rs b/src/libcore/tests/clone.rs
new file mode 100644 (file)
index 0000000..91d68ba
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2014-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.
+
+#[test]
+fn test_borrowed_clone() {
+    let x = 5;
+    let y: &i32 = &x;
+    let z: &i32 = (&y).clone();
+    assert_eq!(*z, 5);
+}
+
+#[test]
+fn test_clone_from() {
+    let a = box 5;
+    let mut b = box 10;
+    b.clone_from(&a);
+    assert_eq!(*b, 5);
+}
diff --git a/src/libcore/tests/cmp.rs b/src/libcore/tests/cmp.rs
new file mode 100644 (file)
index 0000000..e3c65ad
--- /dev/null
@@ -0,0 +1,88 @@
+// 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 core::cmp::Ordering::{Less, Greater, Equal};
+
+#[test]
+fn test_int_totalord() {
+    assert_eq!(5.cmp(&10), Less);
+    assert_eq!(10.cmp(&5), Greater);
+    assert_eq!(5.cmp(&5), Equal);
+    assert_eq!((-5).cmp(&12), Less);
+    assert_eq!(12.cmp(&-5), Greater);
+}
+
+#[test]
+fn test_mut_int_totalord() {
+    assert_eq!((&mut 5).cmp(&&mut 10), Less);
+    assert_eq!((&mut 10).cmp(&&mut 5), Greater);
+    assert_eq!((&mut 5).cmp(&&mut 5), Equal);
+    assert_eq!((&mut -5).cmp(&&mut 12), Less);
+    assert_eq!((&mut 12).cmp(&&mut -5), Greater);
+}
+
+#[test]
+fn test_ordering_reverse() {
+    assert_eq!(Less.reverse(), Greater);
+    assert_eq!(Equal.reverse(), Equal);
+    assert_eq!(Greater.reverse(), Less);
+}
+
+#[test]
+fn test_ordering_order() {
+    assert!(Less < Equal);
+    assert_eq!(Greater.cmp(&Less), Greater);
+}
+
+#[test]
+fn test_ordering_then() {
+    assert_eq!(Equal.then(Less), Less);
+    assert_eq!(Equal.then(Equal), Equal);
+    assert_eq!(Equal.then(Greater), Greater);
+    assert_eq!(Less.then(Less), Less);
+    assert_eq!(Less.then(Equal), Less);
+    assert_eq!(Less.then(Greater), Less);
+    assert_eq!(Greater.then(Less), Greater);
+    assert_eq!(Greater.then(Equal), Greater);
+    assert_eq!(Greater.then(Greater), Greater);
+}
+
+#[test]
+fn test_ordering_then_with() {
+    assert_eq!(Equal.then_with(|| Less), Less);
+    assert_eq!(Equal.then_with(|| Equal), Equal);
+    assert_eq!(Equal.then_with(|| Greater), Greater);
+    assert_eq!(Less.then_with(|| Less), Less);
+    assert_eq!(Less.then_with(|| Equal), Less);
+    assert_eq!(Less.then_with(|| Greater), Less);
+    assert_eq!(Greater.then_with(|| Less), Greater);
+    assert_eq!(Greater.then_with(|| Equal), Greater);
+    assert_eq!(Greater.then_with(|| Greater), Greater);
+}
+
+#[test]
+fn test_user_defined_eq() {
+    // Our type.
+    struct SketchyNum {
+        num : isize
+    }
+
+    // Our implementation of `PartialEq` to support `==` and `!=`.
+    impl PartialEq for SketchyNum {
+        // Our custom eq allows numbers which are near each other to be equal! :D
+        fn eq(&self, other: &SketchyNum) -> bool {
+            (self.num - other.num).abs() < 5
+        }
+    }
+
+    // Now these binary operators will work when applied!
+    assert!(SketchyNum {num: 37} == SketchyNum {num: 34});
+    assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
+}
diff --git a/src/libcore/tests/fmt/builders.rs b/src/libcore/tests/fmt/builders.rs
new file mode 100644 (file)
index 0000000..e71e61b
--- /dev/null
@@ -0,0 +1,498 @@
+// 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 debug_struct {
+    use std::fmt;
+
+    #[test]
+    fn test_empty() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_struct("Foo").finish()
+            }
+        }
+
+        assert_eq!("Foo", format!("{:?}", Foo));
+        assert_eq!("Foo", format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_single() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_struct("Foo")
+                    .field("bar", &true)
+                    .finish()
+            }
+        }
+
+        assert_eq!("Foo { bar: true }", format!("{:?}", Foo));
+        assert_eq!(
+"Foo {
+    bar: true
+}",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_multiple() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_struct("Foo")
+                    .field("bar", &true)
+                    .field("baz", &format_args!("{}/{}", 10, 20))
+                    .finish()
+            }
+        }
+
+        assert_eq!("Foo { bar: true, baz: 10/20 }", format!("{:?}", Foo));
+        assert_eq!(
+"Foo {
+    bar: true,
+    baz: 10/20
+}",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_nested() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_struct("Foo")
+                    .field("bar", &true)
+                    .field("baz", &format_args!("{}/{}", 10, 20))
+                    .finish()
+            }
+        }
+
+        struct Bar;
+
+        impl fmt::Debug for Bar {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_struct("Bar")
+                    .field("foo", &Foo)
+                    .field("hello", &"world")
+                    .finish()
+            }
+        }
+
+        assert_eq!("Bar { foo: Foo { bar: true, baz: 10/20 }, hello: \"world\" }",
+                   format!("{:?}", Bar));
+        assert_eq!(
+"Bar {
+    foo: Foo {
+        bar: true,
+        baz: 10/20
+    },
+    hello: \"world\"
+}",
+                   format!("{:#?}", Bar));
+    }
+}
+
+mod debug_tuple {
+    use std::fmt;
+
+    #[test]
+    fn test_empty() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_tuple("Foo").finish()
+            }
+        }
+
+        assert_eq!("Foo", format!("{:?}", Foo));
+        assert_eq!("Foo", format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_single() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_tuple("Foo")
+                    .field(&true)
+                    .finish()
+            }
+        }
+
+        assert_eq!("Foo(true)", format!("{:?}", Foo));
+        assert_eq!(
+"Foo(
+    true
+)",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_multiple() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_tuple("Foo")
+                    .field(&true)
+                    .field(&format_args!("{}/{}", 10, 20))
+                    .finish()
+            }
+        }
+
+        assert_eq!("Foo(true, 10/20)", format!("{:?}", Foo));
+        assert_eq!(
+"Foo(
+    true,
+    10/20
+)",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_nested() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_tuple("Foo")
+                    .field(&true)
+                    .field(&format_args!("{}/{}", 10, 20))
+                    .finish()
+            }
+        }
+
+        struct Bar;
+
+        impl fmt::Debug for Bar {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_tuple("Bar")
+                    .field(&Foo)
+                    .field(&"world")
+                    .finish()
+            }
+        }
+
+        assert_eq!("Bar(Foo(true, 10/20), \"world\")",
+                   format!("{:?}", Bar));
+        assert_eq!(
+"Bar(
+    Foo(
+        true,
+        10/20
+    ),
+    \"world\"
+)",
+                   format!("{:#?}", Bar));
+    }
+}
+
+mod debug_map {
+    use std::fmt;
+
+    #[test]
+    fn test_empty() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_map().finish()
+            }
+        }
+
+        assert_eq!("{}", format!("{:?}", Foo));
+        assert_eq!("{}", format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_single() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_map()
+                    .entry(&"bar", &true)
+                    .finish()
+            }
+        }
+
+        assert_eq!("{\"bar\": true}", format!("{:?}", Foo));
+        assert_eq!(
+"{
+    \"bar\": true
+}",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_multiple() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_map()
+                    .entry(&"bar", &true)
+                    .entry(&10, &format_args!("{}/{}", 10, 20))
+                    .finish()
+            }
+        }
+
+        assert_eq!("{\"bar\": true, 10: 10/20}", format!("{:?}", Foo));
+        assert_eq!(
+"{
+    \"bar\": true,
+    10: 10/20
+}",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_nested() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_map()
+                    .entry(&"bar", &true)
+                    .entry(&10, &format_args!("{}/{}", 10, 20))
+                    .finish()
+            }
+        }
+
+        struct Bar;
+
+        impl fmt::Debug for Bar {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_map()
+                    .entry(&"foo", &Foo)
+                    .entry(&Foo, &"world")
+                    .finish()
+            }
+        }
+
+        assert_eq!("{\"foo\": {\"bar\": true, 10: 10/20}, \
+                    {\"bar\": true, 10: 10/20}: \"world\"}",
+                   format!("{:?}", Bar));
+        assert_eq!(
+"{
+    \"foo\": {
+        \"bar\": true,
+        10: 10/20
+    },
+    {
+        \"bar\": true,
+        10: 10/20
+    }: \"world\"
+}",
+                   format!("{:#?}", Bar));
+    }
+}
+
+mod debug_set {
+    use std::fmt;
+
+    #[test]
+    fn test_empty() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_set().finish()
+            }
+        }
+
+        assert_eq!("{}", format!("{:?}", Foo));
+        assert_eq!("{}", format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_single() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_set()
+                    .entry(&true)
+                    .finish()
+            }
+        }
+
+        assert_eq!("{true}", format!("{:?}", Foo));
+        assert_eq!(
+"{
+    true
+}",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_multiple() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_set()
+                    .entry(&true)
+                    .entry(&format_args!("{}/{}", 10, 20))
+                    .finish()
+            }
+        }
+
+        assert_eq!("{true, 10/20}", format!("{:?}", Foo));
+        assert_eq!(
+"{
+    true,
+    10/20
+}",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_nested() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_set()
+                    .entry(&true)
+                    .entry(&format_args!("{}/{}", 10, 20))
+                    .finish()
+            }
+        }
+
+        struct Bar;
+
+        impl fmt::Debug for Bar {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_set()
+                    .entry(&Foo)
+                    .entry(&"world")
+                    .finish()
+            }
+        }
+
+        assert_eq!("{{true, 10/20}, \"world\"}",
+                   format!("{:?}", Bar));
+        assert_eq!(
+"{
+    {
+        true,
+        10/20
+    },
+    \"world\"
+}",
+                   format!("{:#?}", Bar));
+    }
+}
+
+mod debug_list {
+    use std::fmt;
+
+    #[test]
+    fn test_empty() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_list().finish()
+            }
+        }
+
+        assert_eq!("[]", format!("{:?}", Foo));
+        assert_eq!("[]", format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_single() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_list()
+                    .entry(&true)
+                    .finish()
+            }
+        }
+
+        assert_eq!("[true]", format!("{:?}", Foo));
+        assert_eq!(
+"[
+    true
+]",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_multiple() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_list()
+                    .entry(&true)
+                    .entry(&format_args!("{}/{}", 10, 20))
+                    .finish()
+            }
+        }
+
+        assert_eq!("[true, 10/20]", format!("{:?}", Foo));
+        assert_eq!(
+"[
+    true,
+    10/20
+]",
+                   format!("{:#?}", Foo));
+    }
+
+    #[test]
+    fn test_nested() {
+        struct Foo;
+
+        impl fmt::Debug for Foo {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_list()
+                    .entry(&true)
+                    .entry(&format_args!("{}/{}", 10, 20))
+                    .finish()
+            }
+        }
+
+        struct Bar;
+
+        impl fmt::Debug for Bar {
+            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+                fmt.debug_list()
+                    .entry(&Foo)
+                    .entry(&"world")
+                    .finish()
+            }
+        }
+
+        assert_eq!("[[true, 10/20], \"world\"]",
+                   format!("{:?}", Bar));
+        assert_eq!(
+"[
+    [
+        true,
+        10/20
+    ],
+    \"world\"
+]",
+                   format!("{:#?}", Bar));
+    }
+}
diff --git a/src/libcore/tests/fmt/float.rs b/src/libcore/tests/fmt/float.rs
new file mode 100644 (file)
index 0000000..6950013
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[test]
+fn test_format_f64() {
+    assert_eq!("1", format!("{:.0}", 1.0f64));
+    assert_eq!("9", format!("{:.0}", 9.4f64));
+    assert_eq!("10", format!("{:.0}", 9.9f64));
+    assert_eq!("9.8", format!("{:.1}", 9.849f64));
+    assert_eq!("9.9", format!("{:.1}", 9.851f64));
+    assert_eq!("1", format!("{:.0}", 0.5f64));
+    assert_eq!("1.23456789e6", format!("{:e}", 1234567.89f64));
+    assert_eq!("1.23456789e3", format!("{:e}", 1234.56789f64));
+    assert_eq!("1.23456789E6", format!("{:E}", 1234567.89f64));
+    assert_eq!("1.23456789E3", format!("{:E}", 1234.56789f64));
+}
+
+#[test]
+fn test_format_f32() {
+    assert_eq!("1", format!("{:.0}", 1.0f32));
+    assert_eq!("9", format!("{:.0}", 9.4f32));
+    assert_eq!("10", format!("{:.0}", 9.9f32));
+    assert_eq!("9.8", format!("{:.1}", 9.849f32));
+    assert_eq!("9.9", format!("{:.1}", 9.851f32));
+    assert_eq!("1", format!("{:.0}", 0.5f32));
+    assert_eq!("1.2345679e6", format!("{:e}", 1234567.89f32));
+    assert_eq!("1.2345679e3", format!("{:e}", 1234.56789f32));
+    assert_eq!("1.2345679E6", format!("{:E}", 1234567.89f32));
+    assert_eq!("1.2345679E3", format!("{:E}", 1234.56789f32));
+}
diff --git a/src/libcore/tests/fmt/mod.rs b/src/libcore/tests/fmt/mod.rs
new file mode 100644 (file)
index 0000000..5d204c7
--- /dev/null
@@ -0,0 +1,40 @@
+// 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 builders;
+mod float;
+mod num;
+
+#[test]
+fn test_format_flags() {
+    // No residual flags left by pointer formatting
+    let p = "".as_ptr();
+    assert_eq!(format!("{:p} {:x}", p, 16), format!("{:p} 10", p));
+
+    assert_eq!(format!("{: >3}", 'a'), "  a");
+}
+
+#[test]
+fn test_pointer_formats_data_pointer() {
+    let b: &[u8] = b"";
+    let s: &str = "";
+    assert_eq!(format!("{:p}", s), format!("{:p}", s.as_ptr()));
+    assert_eq!(format!("{:p}", b), format!("{:p}", b.as_ptr()));
+}
+
+#[test]
+fn test_estimated_capacity() {
+    assert_eq!(format_args!("").estimated_capacity(), 0);
+    assert_eq!(format_args!("{}", "").estimated_capacity(), 0);
+    assert_eq!(format_args!("Hello").estimated_capacity(), 5);
+    assert_eq!(format_args!("Hello, {}!", "").estimated_capacity(), 16);
+    assert_eq!(format_args!("{}, hello!", "World").estimated_capacity(), 0);
+    assert_eq!(format_args!("{}. 16-bytes piece", "World").estimated_capacity(), 32);
+}
diff --git a/src/libcore/tests/fmt/num.rs b/src/libcore/tests/fmt/num.rs
new file mode 100644 (file)
index 0000000..4ddedd9
--- /dev/null
@@ -0,0 +1,152 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[test]
+fn test_format_int() {
+    // Formatting integers should select the right implementation based off
+    // the type of the argument. Also, hex/octal/binary should be defined
+    // for integers, but they shouldn't emit the negative sign.
+    assert!(format!("{}", 1isize) == "1");
+    assert!(format!("{}", 1i8) == "1");
+    assert!(format!("{}", 1i16) == "1");
+    assert!(format!("{}", 1i32) == "1");
+    assert!(format!("{}", 1i64) == "1");
+    assert!(format!("{}", -1isize) == "-1");
+    assert!(format!("{}", -1i8) == "-1");
+    assert!(format!("{}", -1i16) == "-1");
+    assert!(format!("{}", -1i32) == "-1");
+    assert!(format!("{}", -1i64) == "-1");
+    assert!(format!("{:?}", 1isize) == "1");
+    assert!(format!("{:?}", 1i8) == "1");
+    assert!(format!("{:?}", 1i16) == "1");
+    assert!(format!("{:?}", 1i32) == "1");
+    assert!(format!("{:?}", 1i64) == "1");
+    assert!(format!("{:b}", 1isize) == "1");
+    assert!(format!("{:b}", 1i8) == "1");
+    assert!(format!("{:b}", 1i16) == "1");
+    assert!(format!("{:b}", 1i32) == "1");
+    assert!(format!("{:b}", 1i64) == "1");
+    assert!(format!("{:x}", 1isize) == "1");
+    assert!(format!("{:x}", 1i8) == "1");
+    assert!(format!("{:x}", 1i16) == "1");
+    assert!(format!("{:x}", 1i32) == "1");
+    assert!(format!("{:x}", 1i64) == "1");
+    assert!(format!("{:X}", 1isize) == "1");
+    assert!(format!("{:X}", 1i8) == "1");
+    assert!(format!("{:X}", 1i16) == "1");
+    assert!(format!("{:X}", 1i32) == "1");
+    assert!(format!("{:X}", 1i64) == "1");
+    assert!(format!("{:o}", 1isize) == "1");
+    assert!(format!("{:o}", 1i8) == "1");
+    assert!(format!("{:o}", 1i16) == "1");
+    assert!(format!("{:o}", 1i32) == "1");
+    assert!(format!("{:o}", 1i64) == "1");
+
+    assert!(format!("{}", 1usize) == "1");
+    assert!(format!("{}", 1u8) == "1");
+    assert!(format!("{}", 1u16) == "1");
+    assert!(format!("{}", 1u32) == "1");
+    assert!(format!("{}", 1u64) == "1");
+    assert!(format!("{:?}", 1usize) == "1");
+    assert!(format!("{:?}", 1u8) == "1");
+    assert!(format!("{:?}", 1u16) == "1");
+    assert!(format!("{:?}", 1u32) == "1");
+    assert!(format!("{:?}", 1u64) == "1");
+    assert!(format!("{:b}", 1usize) == "1");
+    assert!(format!("{:b}", 1u8) == "1");
+    assert!(format!("{:b}", 1u16) == "1");
+    assert!(format!("{:b}", 1u32) == "1");
+    assert!(format!("{:b}", 1u64) == "1");
+    assert!(format!("{:x}", 1usize) == "1");
+    assert!(format!("{:x}", 1u8) == "1");
+    assert!(format!("{:x}", 1u16) == "1");
+    assert!(format!("{:x}", 1u32) == "1");
+    assert!(format!("{:x}", 1u64) == "1");
+    assert!(format!("{:X}", 1usize) == "1");
+    assert!(format!("{:X}", 1u8) == "1");
+    assert!(format!("{:X}", 1u16) == "1");
+    assert!(format!("{:X}", 1u32) == "1");
+    assert!(format!("{:X}", 1u64) == "1");
+    assert!(format!("{:o}", 1usize) == "1");
+    assert!(format!("{:o}", 1u8) == "1");
+    assert!(format!("{:o}", 1u16) == "1");
+    assert!(format!("{:o}", 1u32) == "1");
+    assert!(format!("{:o}", 1u64) == "1");
+
+    // Test a larger number
+    assert!(format!("{:b}", 55) == "110111");
+    assert!(format!("{:o}", 55) == "67");
+    assert!(format!("{}", 55) == "55");
+    assert!(format!("{:x}", 55) == "37");
+    assert!(format!("{:X}", 55) == "37");
+}
+
+#[test]
+fn test_format_int_zero() {
+    assert!(format!("{}", 0) == "0");
+    assert!(format!("{:?}", 0) == "0");
+    assert!(format!("{:b}", 0) == "0");
+    assert!(format!("{:o}", 0) == "0");
+    assert!(format!("{:x}", 0) == "0");
+    assert!(format!("{:X}", 0) == "0");
+
+    assert!(format!("{}", 0u32) == "0");
+    assert!(format!("{:?}", 0u32) == "0");
+    assert!(format!("{:b}", 0u32) == "0");
+    assert!(format!("{:o}", 0u32) == "0");
+    assert!(format!("{:x}", 0u32) == "0");
+    assert!(format!("{:X}", 0u32) == "0");
+}
+
+#[test]
+fn test_format_int_flags() {
+    assert!(format!("{:3}", 1) == "  1");
+    assert!(format!("{:>3}", 1) == "  1");
+    assert!(format!("{:>+3}", 1) == " +1");
+    assert!(format!("{:<3}", 1) == "1  ");
+    assert!(format!("{:#}", 1) == "1");
+    assert!(format!("{:#x}", 10) == "0xa");
+    assert!(format!("{:#X}", 10) == "0xA");
+    assert!(format!("{:#5x}", 10) == "  0xa");
+    assert!(format!("{:#o}", 10) == "0o12");
+    assert!(format!("{:08x}", 10) == "0000000a");
+    assert!(format!("{:8x}", 10) == "       a");
+    assert!(format!("{:<8x}", 10) == "a       ");
+    assert!(format!("{:>8x}", 10) == "       a");
+    assert!(format!("{:#08x}", 10) == "0x00000a");
+    assert!(format!("{:08}", -10) == "-0000010");
+    assert!(format!("{:x}", !0u8) == "ff");
+    assert!(format!("{:X}", !0u8) == "FF");
+    assert!(format!("{:b}", !0u8) == "11111111");
+    assert!(format!("{:o}", !0u8) == "377");
+    assert!(format!("{:#x}", !0u8) == "0xff");
+    assert!(format!("{:#X}", !0u8) == "0xFF");
+    assert!(format!("{:#b}", !0u8) == "0b11111111");
+    assert!(format!("{:#o}", !0u8) == "0o377");
+}
+
+#[test]
+fn test_format_int_sign_padding() {
+    assert!(format!("{:+5}", 1) == "   +1");
+    assert!(format!("{:+5}", -1) == "   -1");
+    assert!(format!("{:05}", 1) == "00001");
+    assert!(format!("{:05}", -1) == "-0001");
+    assert!(format!("{:+05}", 1) == "+0001");
+    assert!(format!("{:+05}", -1) == "-0001");
+}
+
+#[test]
+fn test_format_int_twos_complement() {
+    use core::{i8, i16, i32, i64};
+    assert!(format!("{}", i8::MIN) == "-128");
+    assert!(format!("{}", i16::MIN) == "-32768");
+    assert!(format!("{}", i32::MIN) == "-2147483648");
+    assert!(format!("{}", i64::MIN) == "-9223372036854775808");
+}
diff --git a/src/libcore/tests/hash/mod.rs b/src/libcore/tests/hash/mod.rs
new file mode 100644 (file)
index 0000000..53ac17c
--- /dev/null
@@ -0,0 +1,111 @@
+// 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 sip;
+
+use std::hash::{Hash, Hasher};
+use std::default::Default;
+
+struct MyHasher {
+    hash: u64,
+}
+
+impl Default for MyHasher {
+    fn default() -> MyHasher {
+        MyHasher { hash: 0 }
+    }
+}
+
+impl Hasher for MyHasher {
+    fn write(&mut self, buf: &[u8]) {
+        for byte in buf {
+            self.hash += *byte as u64;
+        }
+    }
+    fn finish(&self) -> u64 { self.hash }
+}
+
+
+#[test]
+fn test_writer_hasher() {
+    fn hash<T: Hash>(t: &T) -> u64 {
+        let mut s = MyHasher { hash: 0 };
+        t.hash(&mut s);
+        s.finish()
+    }
+
+    assert_eq!(hash(&()), 0);
+
+    assert_eq!(hash(&5_u8), 5);
+    assert_eq!(hash(&5_u16), 5);
+    assert_eq!(hash(&5_u32), 5);
+    assert_eq!(hash(&5_u64), 5);
+    assert_eq!(hash(&5_usize), 5);
+
+    assert_eq!(hash(&5_i8), 5);
+    assert_eq!(hash(&5_i16), 5);
+    assert_eq!(hash(&5_i32), 5);
+    assert_eq!(hash(&5_i64), 5);
+    assert_eq!(hash(&5_isize), 5);
+
+    assert_eq!(hash(&false), 0);
+    assert_eq!(hash(&true), 1);
+
+    assert_eq!(hash(&'a'), 97);
+
+    let s: &str = "a";
+    assert_eq!(hash(& s), 97 + 0xFF);
+    let s: Box<str> = String::from("a").into_boxed_str();
+    assert_eq!(hash(& s), 97 + 0xFF);
+    let cs: &[u8] = &[1, 2, 3];
+    assert_eq!(hash(& cs), 9);
+    let cs: Box<[u8]> = Box::new([1, 2, 3]);
+    assert_eq!(hash(& cs), 9);
+
+    // FIXME (#18248) Add tests for hashing Rc<str> and Rc<[T]>
+
+    let ptr = 5_usize as *const i32;
+    assert_eq!(hash(&ptr), 5);
+
+    let ptr = 5_usize as *mut i32;
+    assert_eq!(hash(&ptr), 5);
+}
+
+struct Custom { hash: u64 }
+struct CustomHasher { output: u64 }
+
+impl Hasher for CustomHasher {
+    fn finish(&self) -> u64 { self.output }
+    fn write(&mut self, _: &[u8]) { panic!() }
+    fn write_u64(&mut self, data: u64) { self.output = data; }
+}
+
+impl Default for CustomHasher {
+    fn default() -> CustomHasher {
+        CustomHasher { output: 0 }
+    }
+}
+
+impl Hash for Custom {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        state.write_u64(self.hash);
+    }
+}
+
+#[test]
+fn test_custom_state() {
+    fn hash<T: Hash>(t: &T) -> u64 {
+        let mut c = CustomHasher { output: 0 };
+        t.hash(&mut c);
+        c.finish()
+    }
+
+    assert_eq!(hash(&Custom { hash: 5 }), 5);
+}
diff --git a/src/libcore/tests/hash/sip.rs b/src/libcore/tests/hash/sip.rs
new file mode 100644 (file)
index 0000000..4a9657e
--- /dev/null
@@ -0,0 +1,342 @@
+// 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.
+
+#![allow(deprecated)]
+
+use core::hash::{Hash, Hasher};
+use core::hash::{SipHasher, SipHasher13, SipHasher24};
+use core::{slice, mem};
+
+// Hash just the bytes of the slice, without length prefix
+struct Bytes<'a>(&'a [u8]);
+
+impl<'a> Hash for Bytes<'a> {
+    #[allow(unused_must_use)]
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        let Bytes(v) = *self;
+        state.write(v);
+    }
+}
+
+macro_rules! u8to64_le {
+    ($buf:expr, $i:expr) =>
+    ($buf[0+$i] as u64 |
+     ($buf[1+$i] as u64) << 8 |
+     ($buf[2+$i] as u64) << 16 |
+     ($buf[3+$i] as u64) << 24 |
+     ($buf[4+$i] as u64) << 32 |
+     ($buf[5+$i] as u64) << 40 |
+     ($buf[6+$i] as u64) << 48 |
+     ($buf[7+$i] as u64) << 56);
+    ($buf:expr, $i:expr, $len:expr) =>
+    ({
+        let mut t = 0;
+        let mut out = 0;
+        while t < $len {
+            out |= ($buf[t+$i] as u64) << t*8;
+            t += 1;
+        }
+        out
+    });
+}
+
+fn hash_with<H: Hasher, T: Hash>(mut st: H, x: &T) -> u64 {
+    x.hash(&mut st);
+    st.finish()
+}
+
+fn hash<T: Hash>(x: &T) -> u64 {
+    hash_with(SipHasher::new(), x)
+}
+
+#[test]
+#[allow(unused_must_use)]
+fn test_siphash_1_3() {
+    let vecs : [[u8; 8]; 64] = [
+        [ 0xdc, 0xc4, 0x0f, 0x05, 0x58, 0x01, 0xac, 0xab ],
+        [ 0x93, 0xca, 0x57, 0x7d, 0xf3, 0x9b, 0xf4, 0xc9 ],
+        [ 0x4d, 0xd4, 0xc7, 0x4d, 0x02, 0x9b, 0xcb, 0x82 ],
+        [ 0xfb, 0xf7, 0xdd, 0xe7, 0xb8, 0x0a, 0xf8, 0x8b ],
+        [ 0x28, 0x83, 0xd3, 0x88, 0x60, 0x57, 0x75, 0xcf ],
+        [ 0x67, 0x3b, 0x53, 0x49, 0x2f, 0xd5, 0xf9, 0xde ],
+        [ 0xa7, 0x22, 0x9f, 0xc5, 0x50, 0x2b, 0x0d, 0xc5 ],
+        [ 0x40, 0x11, 0xb1, 0x9b, 0x98, 0x7d, 0x92, 0xd3 ],
+        [ 0x8e, 0x9a, 0x29, 0x8d, 0x11, 0x95, 0x90, 0x36 ],
+        [ 0xe4, 0x3d, 0x06, 0x6c, 0xb3, 0x8e, 0xa4, 0x25 ],
+        [ 0x7f, 0x09, 0xff, 0x92, 0xee, 0x85, 0xde, 0x79 ],
+        [ 0x52, 0xc3, 0x4d, 0xf9, 0xc1, 0x18, 0xc1, 0x70 ],
+        [ 0xa2, 0xd9, 0xb4, 0x57, 0xb1, 0x84, 0xa3, 0x78 ],
+        [ 0xa7, 0xff, 0x29, 0x12, 0x0c, 0x76, 0x6f, 0x30 ],
+        [ 0x34, 0x5d, 0xf9, 0xc0, 0x11, 0xa1, 0x5a, 0x60 ],
+        [ 0x56, 0x99, 0x51, 0x2a, 0x6d, 0xd8, 0x20, 0xd3 ],
+        [ 0x66, 0x8b, 0x90, 0x7d, 0x1a, 0xdd, 0x4f, 0xcc ],
+        [ 0x0c, 0xd8, 0xdb, 0x63, 0x90, 0x68, 0xf2, 0x9c ],
+        [ 0x3e, 0xe6, 0x73, 0xb4, 0x9c, 0x38, 0xfc, 0x8f ],
+        [ 0x1c, 0x7d, 0x29, 0x8d, 0xe5, 0x9d, 0x1f, 0xf2 ],
+        [ 0x40, 0xe0, 0xcc, 0xa6, 0x46, 0x2f, 0xdc, 0xc0 ],
+        [ 0x44, 0xf8, 0x45, 0x2b, 0xfe, 0xab, 0x92, 0xb9 ],
+        [ 0x2e, 0x87, 0x20, 0xa3, 0x9b, 0x7b, 0xfe, 0x7f ],
+        [ 0x23, 0xc1, 0xe6, 0xda, 0x7f, 0x0e, 0x5a, 0x52 ],
+        [ 0x8c, 0x9c, 0x34, 0x67, 0xb2, 0xae, 0x64, 0xf4 ],
+        [ 0x79, 0x09, 0x5b, 0x70, 0x28, 0x59, 0xcd, 0x45 ],
+        [ 0xa5, 0x13, 0x99, 0xca, 0xe3, 0x35, 0x3e, 0x3a ],
+        [ 0x35, 0x3b, 0xde, 0x4a, 0x4e, 0xc7, 0x1d, 0xa9 ],
+        [ 0x0d, 0xd0, 0x6c, 0xef, 0x02, 0xed, 0x0b, 0xfb ],
+        [ 0xf4, 0xe1, 0xb1, 0x4a, 0xb4, 0x3c, 0xd9, 0x88 ],
+        [ 0x63, 0xe6, 0xc5, 0x43, 0xd6, 0x11, 0x0f, 0x54 ],
+        [ 0xbc, 0xd1, 0x21, 0x8c, 0x1f, 0xdd, 0x70, 0x23 ],
+        [ 0x0d, 0xb6, 0xa7, 0x16, 0x6c, 0x7b, 0x15, 0x81 ],
+        [ 0xbf, 0xf9, 0x8f, 0x7a, 0xe5, 0xb9, 0x54, 0x4d ],
+        [ 0x3e, 0x75, 0x2a, 0x1f, 0x78, 0x12, 0x9f, 0x75 ],
+        [ 0x91, 0x6b, 0x18, 0xbf, 0xbe, 0xa3, 0xa1, 0xce ],
+        [ 0x06, 0x62, 0xa2, 0xad, 0xd3, 0x08, 0xf5, 0x2c ],
+        [ 0x57, 0x30, 0xc3, 0xa3, 0x2d, 0x1c, 0x10, 0xb6 ],
+        [ 0xa1, 0x36, 0x3a, 0xae, 0x96, 0x74, 0xf4, 0xb3 ],
+        [ 0x92, 0x83, 0x10, 0x7b, 0x54, 0x57, 0x6b, 0x62 ],
+        [ 0x31, 0x15, 0xe4, 0x99, 0x32, 0x36, 0xd2, 0xc1 ],
+        [ 0x44, 0xd9, 0x1a, 0x3f, 0x92, 0xc1, 0x7c, 0x66 ],
+        [ 0x25, 0x88, 0x13, 0xc8, 0xfe, 0x4f, 0x70, 0x65 ],
+        [ 0xa6, 0x49, 0x89, 0xc2, 0xd1, 0x80, 0xf2, 0x24 ],
+        [ 0x6b, 0x87, 0xf8, 0xfa, 0xed, 0x1c, 0xca, 0xc2 ],
+        [ 0x96, 0x21, 0x04, 0x9f, 0xfc, 0x4b, 0x16, 0xc2 ],
+        [ 0x23, 0xd6, 0xb1, 0x68, 0x93, 0x9c, 0x6e, 0xa1 ],
+        [ 0xfd, 0x14, 0x51, 0x8b, 0x9c, 0x16, 0xfb, 0x49 ],
+        [ 0x46, 0x4c, 0x07, 0xdf, 0xf8, 0x43, 0x31, 0x9f ],
+        [ 0xb3, 0x86, 0xcc, 0x12, 0x24, 0xaf, 0xfd, 0xc6 ],
+        [ 0x8f, 0x09, 0x52, 0x0a, 0xd1, 0x49, 0xaf, 0x7e ],
+        [ 0x9a, 0x2f, 0x29, 0x9d, 0x55, 0x13, 0xf3, 0x1c ],
+        [ 0x12, 0x1f, 0xf4, 0xa2, 0xdd, 0x30, 0x4a, 0xc4 ],
+        [ 0xd0, 0x1e, 0xa7, 0x43, 0x89, 0xe9, 0xfa, 0x36 ],
+        [ 0xe6, 0xbc, 0xf0, 0x73, 0x4c, 0xb3, 0x8f, 0x31 ],
+        [ 0x80, 0xe9, 0xa7, 0x70, 0x36, 0xbf, 0x7a, 0xa2 ],
+        [ 0x75, 0x6d, 0x3c, 0x24, 0xdb, 0xc0, 0xbc, 0xb4 ],
+        [ 0x13, 0x15, 0xb7, 0xfd, 0x52, 0xd8, 0xf8, 0x23 ],
+        [ 0x08, 0x8a, 0x7d, 0xa6, 0x4d, 0x5f, 0x03, 0x8f ],
+        [ 0x48, 0xf1, 0xe8, 0xb7, 0xe5, 0xd0, 0x9c, 0xd8 ],
+        [ 0xee, 0x44, 0xa6, 0xf7, 0xbc, 0xe6, 0xf4, 0xf6 ],
+        [ 0xf2, 0x37, 0x18, 0x0f, 0xd8, 0x9a, 0xc5, 0xae ],
+        [ 0xe0, 0x94, 0x66, 0x4b, 0x15, 0xf6, 0xb2, 0xc3 ],
+        [ 0xa8, 0xb3, 0xbb, 0xb7, 0x62, 0x90, 0x19, 0x9d ]
+    ];
+
+    let k0 = 0x_07_06_05_04_03_02_01_00;
+    let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08;
+    let mut buf = Vec::new();
+    let mut t = 0;
+    let mut state_inc = SipHasher13::new_with_keys(k0, k1);
+
+    while t < 64 {
+        let vec = u8to64_le!(vecs[t], 0);
+        let out = hash_with(SipHasher13::new_with_keys(k0, k1), &Bytes(&buf));
+        assert_eq!(vec, out);
+
+        let full = hash_with(SipHasher13::new_with_keys(k0, k1), &Bytes(&buf));
+        let i = state_inc.finish();
+
+        assert_eq!(full, i);
+        assert_eq!(full, vec);
+
+        buf.push(t as u8);
+        Hasher::write(&mut state_inc, &[t as u8]);
+
+        t += 1;
+    }
+}
+
+#[test]
+#[allow(unused_must_use)]
+fn test_siphash_2_4() {
+    let vecs : [[u8; 8]; 64] = [
+        [ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, ],
+        [ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, ],
+        [ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, ],
+        [ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, ],
+        [ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, ],
+        [ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, ],
+        [ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, ],
+        [ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, ],
+        [ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, ],
+        [ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, ],
+        [ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, ],
+        [ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, ],
+        [ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, ],
+        [ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, ],
+        [ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, ],
+        [ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, ],
+        [ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, ],
+        [ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, ],
+        [ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, ],
+        [ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, ],
+        [ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, ],
+        [ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, ],
+        [ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, ],
+        [ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, ],
+        [ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, ],
+        [ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, ],
+        [ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, ],
+        [ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, ],
+        [ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, ],
+        [ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, ],
+        [ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, ],
+        [ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, ],
+        [ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, ],
+        [ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, ],
+        [ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, ],
+        [ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, ],
+        [ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, ],
+        [ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, ],
+        [ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, ],
+        [ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, ],
+        [ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, ],
+        [ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, ],
+        [ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, ],
+        [ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, ],
+        [ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, ],
+        [ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, ],
+        [ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, ],
+        [ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, ],
+        [ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, ],
+        [ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, ],
+        [ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, ],
+        [ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, ],
+        [ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, ],
+        [ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, ],
+        [ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, ],
+        [ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, ],
+        [ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, ],
+        [ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, ],
+        [ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, ],
+        [ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, ],
+        [ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, ],
+        [ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, ],
+        [ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, ],
+        [ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, ]
+    ];
+
+    let k0 = 0x_07_06_05_04_03_02_01_00;
+    let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08;
+    let mut buf = Vec::new();
+    let mut t = 0;
+    let mut state_inc = SipHasher24::new_with_keys(k0, k1);
+
+    while t < 64 {
+        let vec = u8to64_le!(vecs[t], 0);
+        let out = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf));
+        assert_eq!(vec, out);
+
+        let full = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf));
+        let i = state_inc.finish();
+
+        assert_eq!(full, i);
+        assert_eq!(full, vec);
+
+        buf.push(t as u8);
+        Hasher::write(&mut state_inc, &[t as u8]);
+
+        t += 1;
+    }
+}
+#[test] #[cfg(target_arch = "arm")]
+fn test_hash_usize() {
+    let val = 0xdeadbeef_deadbeef_u64;
+    assert!(hash(&(val as u64)) != hash(&(val as usize)));
+    assert_eq!(hash(&(val as u32)), hash(&(val as usize)));
+}
+#[test] #[cfg(target_arch = "x86_64")]
+fn test_hash_usize() {
+    let val = 0xdeadbeef_deadbeef_u64;
+    assert_eq!(hash(&(val as u64)), hash(&(val as usize)));
+    assert!(hash(&(val as u32)) != hash(&(val as usize)));
+}
+#[test] #[cfg(target_arch = "x86")]
+fn test_hash_usize() {
+    let val = 0xdeadbeef_deadbeef_u64;
+    assert!(hash(&(val as u64)) != hash(&(val as usize)));
+    assert_eq!(hash(&(val as u32)), hash(&(val as usize)));
+}
+
+#[test]
+fn test_hash_idempotent() {
+    let val64 = 0xdeadbeef_deadbeef_u64;
+    assert_eq!(hash(&val64), hash(&val64));
+    let val32 = 0xdeadbeef_u32;
+    assert_eq!(hash(&val32), hash(&val32));
+}
+
+#[test]
+fn test_hash_no_bytes_dropped_64() {
+    let val = 0xdeadbeef_deadbeef_u64;
+
+    assert!(hash(&val) != hash(&zero_byte(val, 0)));
+    assert!(hash(&val) != hash(&zero_byte(val, 1)));
+    assert!(hash(&val) != hash(&zero_byte(val, 2)));
+    assert!(hash(&val) != hash(&zero_byte(val, 3)));
+    assert!(hash(&val) != hash(&zero_byte(val, 4)));
+    assert!(hash(&val) != hash(&zero_byte(val, 5)));
+    assert!(hash(&val) != hash(&zero_byte(val, 6)));
+    assert!(hash(&val) != hash(&zero_byte(val, 7)));
+
+    fn zero_byte(val: u64, byte: usize) -> u64 {
+        assert!(byte < 8);
+        val & !(0xff << (byte * 8))
+    }
+}
+
+#[test]
+fn test_hash_no_bytes_dropped_32() {
+    let val = 0xdeadbeef_u32;
+
+    assert!(hash(&val) != hash(&zero_byte(val, 0)));
+    assert!(hash(&val) != hash(&zero_byte(val, 1)));
+    assert!(hash(&val) != hash(&zero_byte(val, 2)));
+    assert!(hash(&val) != hash(&zero_byte(val, 3)));
+
+    fn zero_byte(val: u32, byte: usize) -> u32 {
+        assert!(byte < 4);
+        val & !(0xff << (byte * 8))
+    }
+}
+
+#[test]
+fn test_hash_no_concat_alias() {
+    let s = ("aa", "bb");
+    let t = ("aabb", "");
+    let u = ("a", "abb");
+
+    assert!(s != t && t != u);
+    assert!(hash(&s) != hash(&t) && hash(&s) != hash(&u));
+
+    let u = [1, 0, 0, 0];
+    let v = (&u[..1], &u[1..3], &u[3..]);
+    let w = (&u[..], &u[4..4], &u[4..4]);
+
+    assert!(v != w);
+    assert!(hash(&v) != hash(&w));
+}
+
+#[test]
+fn test_write_short_works() {
+    let test_usize = 0xd0c0b0a0usize;
+    let mut h1 = SipHasher24::new();
+    h1.write_usize(test_usize);
+    h1.write(b"bytes");
+    h1.write(b"string");
+    h1.write_u8(0xFFu8);
+    h1.write_u8(0x01u8);
+    let mut h2 = SipHasher24::new();
+    h2.write(unsafe {
+        slice::from_raw_parts(&test_usize as *const _ as *const u8,
+                              mem::size_of::<usize>())
+    });
+    h2.write(b"bytes");
+    h2.write(b"string");
+    h2.write(&[0xFFu8, 0x01u8]);
+    assert_eq!(h1.finish(), h2.finish());
+}
diff --git a/src/libcore/tests/intrinsics.rs b/src/libcore/tests/intrinsics.rs
new file mode 100644 (file)
index 0000000..2b380ab
--- /dev/null
@@ -0,0 +1,30 @@
+// 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 core::any::TypeId;
+
+#[test]
+fn test_typeid_sized_types() {
+    struct X; struct Y(u32);
+
+    assert_eq!(TypeId::of::<X>(), TypeId::of::<X>());
+    assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());
+    assert!(TypeId::of::<X>() != TypeId::of::<Y>());
+}
+
+#[test]
+fn test_typeid_unsized_types() {
+    trait Z {}
+    struct X(str); struct Y(Z + 'static);
+
+    assert_eq!(TypeId::of::<X>(), TypeId::of::<X>());
+    assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());
+    assert!(TypeId::of::<X>() != TypeId::of::<Y>());
+}
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
new file mode 100644 (file)
index 0000000..08442f9
--- /dev/null
@@ -0,0 +1,1084 @@
+// 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 core::iter::*;
+use core::{i8, i16, isize};
+use core::usize;
+
+#[test]
+fn test_lt() {
+    let empty: [isize; 0] = [];
+    let xs = [1,2,3];
+    let ys = [1,2,0];
+
+    assert!(!xs.iter().lt(ys.iter()));
+    assert!(!xs.iter().le(ys.iter()));
+    assert!( xs.iter().gt(ys.iter()));
+    assert!( xs.iter().ge(ys.iter()));
+
+    assert!( ys.iter().lt(xs.iter()));
+    assert!( ys.iter().le(xs.iter()));
+    assert!(!ys.iter().gt(xs.iter()));
+    assert!(!ys.iter().ge(xs.iter()));
+
+    assert!( empty.iter().lt(xs.iter()));
+    assert!( empty.iter().le(xs.iter()));
+    assert!(!empty.iter().gt(xs.iter()));
+    assert!(!empty.iter().ge(xs.iter()));
+
+    // Sequence with NaN
+    let u = [1.0f64, 2.0];
+    let v = [0.0f64/0.0, 3.0];
+
+    assert!(!u.iter().lt(v.iter()));
+    assert!(!u.iter().le(v.iter()));
+    assert!(!u.iter().gt(v.iter()));
+    assert!(!u.iter().ge(v.iter()));
+
+    let a = [0.0f64/0.0];
+    let b = [1.0f64];
+    let c = [2.0f64];
+
+    assert!(a.iter().lt(b.iter()) == (a[0] <  b[0]));
+    assert!(a.iter().le(b.iter()) == (a[0] <= b[0]));
+    assert!(a.iter().gt(b.iter()) == (a[0] >  b[0]));
+    assert!(a.iter().ge(b.iter()) == (a[0] >= b[0]));
+
+    assert!(c.iter().lt(b.iter()) == (c[0] <  b[0]));
+    assert!(c.iter().le(b.iter()) == (c[0] <= b[0]));
+    assert!(c.iter().gt(b.iter()) == (c[0] >  b[0]));
+    assert!(c.iter().ge(b.iter()) == (c[0] >= b[0]));
+}
+
+#[test]
+fn test_multi_iter() {
+    let xs = [1,2,3,4];
+    let ys = [4,3,2,1];
+    assert!(xs.iter().eq(ys.iter().rev()));
+    assert!(xs.iter().lt(xs.iter().skip(2)));
+}
+
+#[test]
+fn test_counter_from_iter() {
+    let it = (0..).step_by(5).take(10);
+    let xs: Vec<isize> = FromIterator::from_iter(it);
+    assert_eq!(xs, [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
+}
+
+#[test]
+fn test_iterator_chain() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let ys = [30, 40, 50, 60];
+    let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
+    let it = xs.iter().chain(&ys);
+    let mut i = 0;
+    for &x in it {
+        assert_eq!(x, expected[i]);
+        i += 1;
+    }
+    assert_eq!(i, expected.len());
+
+    let ys = (30..).step_by(10).take(4);
+    let it = xs.iter().cloned().chain(ys);
+    let mut i = 0;
+    for x in it {
+        assert_eq!(x, expected[i]);
+        i += 1;
+    }
+    assert_eq!(i, expected.len());
+}
+
+#[test]
+fn test_iterator_chain_nth() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let ys = [30, 40, 50, 60];
+    let zs = [];
+    let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
+    for (i, x) in expected.iter().enumerate() {
+        assert_eq!(Some(x), xs.iter().chain(&ys).nth(i));
+    }
+    assert_eq!(zs.iter().chain(&xs).nth(0), Some(&0));
+
+    let mut it = xs.iter().chain(&zs);
+    assert_eq!(it.nth(5), Some(&5));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_iterator_chain_last() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let ys = [30, 40, 50, 60];
+    let zs = [];
+    assert_eq!(xs.iter().chain(&ys).last(), Some(&60));
+    assert_eq!(zs.iter().chain(&ys).last(), Some(&60));
+    assert_eq!(ys.iter().chain(&zs).last(), Some(&60));
+    assert_eq!(zs.iter().chain(&zs).last(), None);
+}
+
+#[test]
+fn test_iterator_chain_count() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let ys = [30, 40, 50, 60];
+    let zs = [];
+    assert_eq!(xs.iter().chain(&ys).count(), 10);
+    assert_eq!(zs.iter().chain(&ys).count(), 4);
+}
+
+#[test]
+fn test_iterator_chain_find() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let ys = [30, 40, 50, 60];
+    let mut iter = xs.iter().chain(&ys);
+    assert_eq!(iter.find(|&&i| i == 4), Some(&4));
+    assert_eq!(iter.next(), Some(&5));
+    assert_eq!(iter.find(|&&i| i == 40), Some(&40));
+    assert_eq!(iter.next(), Some(&50));
+    assert_eq!(iter.find(|&&i| i == 100), None);
+    assert_eq!(iter.next(), None);
+}
+
+#[test]
+fn test_filter_map() {
+    let it = (0..).step_by(1).take(10)
+        .filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None });
+    assert_eq!(it.collect::<Vec<usize>>(), [0*0, 2*2, 4*4, 6*6, 8*8]);
+}
+
+#[test]
+fn test_iterator_enumerate() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let it = xs.iter().enumerate();
+    for (i, &x) in it {
+        assert_eq!(i, x);
+    }
+}
+
+#[test]
+fn test_iterator_enumerate_nth() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    for (i, &x) in xs.iter().enumerate() {
+        assert_eq!(i, x);
+    }
+
+    let mut it = xs.iter().enumerate();
+    while let Some((i, &x)) = it.nth(0) {
+        assert_eq!(i, x);
+    }
+
+    let mut it = xs.iter().enumerate();
+    while let Some((i, &x)) = it.nth(1) {
+        assert_eq!(i, x);
+    }
+
+    let (i, &x) = xs.iter().enumerate().nth(3).unwrap();
+    assert_eq!(i, x);
+    assert_eq!(i, 3);
+}
+
+#[test]
+fn test_iterator_enumerate_count() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    assert_eq!(xs.iter().count(), 6);
+}
+
+#[test]
+fn test_iterator_filter_count() {
+    let xs = [0, 1, 2, 3, 4, 5, 6, 7, 8];
+    assert_eq!(xs.iter().filter(|&&x| x % 2 == 0).count(), 5);
+}
+
+#[test]
+fn test_iterator_peekable() {
+    let xs = vec![0, 1, 2, 3, 4, 5];
+    let mut it = xs.iter().cloned().peekable();
+
+    assert_eq!(it.len(), 6);
+    assert_eq!(it.peek().unwrap(), &0);
+    assert_eq!(it.len(), 6);
+    assert_eq!(it.next().unwrap(), 0);
+    assert_eq!(it.len(), 5);
+    assert_eq!(it.next().unwrap(), 1);
+    assert_eq!(it.len(), 4);
+    assert_eq!(it.next().unwrap(), 2);
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.peek().unwrap(), &3);
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.peek().unwrap(), &3);
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.next().unwrap(), 3);
+    assert_eq!(it.len(), 2);
+    assert_eq!(it.next().unwrap(), 4);
+    assert_eq!(it.len(), 1);
+    assert_eq!(it.peek().unwrap(), &5);
+    assert_eq!(it.len(), 1);
+    assert_eq!(it.next().unwrap(), 5);
+    assert_eq!(it.len(), 0);
+    assert!(it.peek().is_none());
+    assert_eq!(it.len(), 0);
+    assert!(it.next().is_none());
+    assert_eq!(it.len(), 0);
+}
+
+#[test]
+fn test_iterator_peekable_count() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let ys = [10];
+    let zs: [i32; 0] = [];
+
+    assert_eq!(xs.iter().peekable().count(), 6);
+
+    let mut it = xs.iter().peekable();
+    assert_eq!(it.peek(), Some(&&0));
+    assert_eq!(it.count(), 6);
+
+    assert_eq!(ys.iter().peekable().count(), 1);
+
+    let mut it = ys.iter().peekable();
+    assert_eq!(it.peek(), Some(&&10));
+    assert_eq!(it.count(), 1);
+
+    assert_eq!(zs.iter().peekable().count(), 0);
+
+    let mut it = zs.iter().peekable();
+    assert_eq!(it.peek(), None);
+
+}
+
+#[test]
+fn test_iterator_peekable_nth() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let mut it = xs.iter().peekable();
+
+    assert_eq!(it.peek(), Some(&&0));
+    assert_eq!(it.nth(0), Some(&0));
+    assert_eq!(it.peek(), Some(&&1));
+    assert_eq!(it.nth(1), Some(&2));
+    assert_eq!(it.peek(), Some(&&3));
+    assert_eq!(it.nth(2), Some(&5));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_iterator_peekable_last() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let ys = [0];
+
+    let mut it = xs.iter().peekable();
+    assert_eq!(it.peek(), Some(&&0));
+    assert_eq!(it.last(), Some(&5));
+
+    let mut it = ys.iter().peekable();
+    assert_eq!(it.peek(), Some(&&0));
+    assert_eq!(it.last(), Some(&0));
+
+    let mut it = ys.iter().peekable();
+    assert_eq!(it.next(), Some(&0));
+    assert_eq!(it.peek(), None);
+    assert_eq!(it.last(), None);
+}
+
+/// This is an iterator that follows the Iterator contract,
+/// but it is not fused. After having returned None once, it will start
+/// producing elements if .next() is called again.
+pub struct CycleIter<'a, T: 'a> {
+    index: usize,
+    data: &'a [T],
+}
+
+pub fn cycle<T>(data: &[T]) -> CycleIter<T> {
+    CycleIter {
+        index: 0,
+        data: data,
+    }
+}
+
+impl<'a, T> Iterator for CycleIter<'a, T> {
+    type Item = &'a T;
+    fn next(&mut self) -> Option<Self::Item> {
+        let elt = self.data.get(self.index);
+        self.index += 1;
+        self.index %= 1 + self.data.len();
+        elt
+    }
+}
+
+#[test]
+fn test_iterator_peekable_remember_peek_none_1() {
+    // Check that the loop using .peek() terminates
+    let data = [1, 2, 3];
+    let mut iter = cycle(&data).peekable();
+
+    let mut n = 0;
+    while let Some(_) = iter.next() {
+        let is_the_last = iter.peek().is_none();
+        assert_eq!(is_the_last, n == data.len() - 1);
+        n += 1;
+        if n > data.len() { break; }
+    }
+    assert_eq!(n, data.len());
+}
+
+#[test]
+fn test_iterator_peekable_remember_peek_none_2() {
+    let data = [0];
+    let mut iter = cycle(&data).peekable();
+    iter.next();
+    assert_eq!(iter.peek(), None);
+    assert_eq!(iter.last(), None);
+}
+
+#[test]
+fn test_iterator_peekable_remember_peek_none_3() {
+    let data = [0];
+    let mut iter = cycle(&data).peekable();
+    iter.peek();
+    assert_eq!(iter.nth(0), Some(&0));
+
+    let mut iter = cycle(&data).peekable();
+    iter.next();
+    assert_eq!(iter.peek(), None);
+    assert_eq!(iter.nth(0), None);
+}
+
+#[test]
+fn test_iterator_take_while() {
+    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19];
+    let ys = [0, 1, 2, 3, 5, 13];
+    let it = xs.iter().take_while(|&x| *x < 15);
+    let mut i = 0;
+    for x in it {
+        assert_eq!(*x, ys[i]);
+        i += 1;
+    }
+    assert_eq!(i, ys.len());
+}
+
+#[test]
+fn test_iterator_skip_while() {
+    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19];
+    let ys = [15, 16, 17, 19];
+    let it = xs.iter().skip_while(|&x| *x < 15);
+    let mut i = 0;
+    for x in it {
+        assert_eq!(*x, ys[i]);
+        i += 1;
+    }
+    assert_eq!(i, ys.len());
+}
+
+#[test]
+fn test_iterator_skip() {
+    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
+    let ys = [13, 15, 16, 17, 19, 20, 30];
+    let mut it = xs.iter().skip(5);
+    let mut i = 0;
+    while let Some(&x) = it.next() {
+        assert_eq!(x, ys[i]);
+        i += 1;
+        assert_eq!(it.len(), xs.len()-5-i);
+    }
+    assert_eq!(i, ys.len());
+    assert_eq!(it.len(), 0);
+}
+
+#[test]
+fn test_iterator_skip_doubleended() {
+    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
+    let mut it = xs.iter().rev().skip(5);
+    assert_eq!(it.next(), Some(&15));
+    assert_eq!(it.by_ref().rev().next(), Some(&0));
+    assert_eq!(it.next(), Some(&13));
+    assert_eq!(it.by_ref().rev().next(), Some(&1));
+    assert_eq!(it.next(), Some(&5));
+    assert_eq!(it.by_ref().rev().next(), Some(&2));
+    assert_eq!(it.next(), Some(&3));
+    assert_eq!(it.next(), None);
+    let mut it = xs.iter().rev().skip(5).rev();
+    assert_eq!(it.next(), Some(&0));
+    assert_eq!(it.rev().next(), Some(&15));
+    let mut it_base = xs.iter();
+    {
+        let mut it = it_base.by_ref().skip(5).rev();
+        assert_eq!(it.next(), Some(&30));
+        assert_eq!(it.next(), Some(&20));
+        assert_eq!(it.next(), Some(&19));
+        assert_eq!(it.next(), Some(&17));
+        assert_eq!(it.next(), Some(&16));
+        assert_eq!(it.next(), Some(&15));
+        assert_eq!(it.next(), Some(&13));
+        assert_eq!(it.next(), None);
+    }
+    // make sure the skipped parts have not been consumed
+    assert_eq!(it_base.next(), Some(&0));
+    assert_eq!(it_base.next(), Some(&1));
+    assert_eq!(it_base.next(), Some(&2));
+    assert_eq!(it_base.next(), Some(&3));
+    assert_eq!(it_base.next(), Some(&5));
+    assert_eq!(it_base.next(), None);
+    let it = xs.iter().skip(5).rev();
+    assert_eq!(it.last(), Some(&13));
+}
+
+#[test]
+fn test_iterator_skip_nth() {
+    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
+
+    let mut it = xs.iter().skip(0);
+    assert_eq!(it.nth(0), Some(&0));
+    assert_eq!(it.nth(1), Some(&2));
+
+    let mut it = xs.iter().skip(5);
+    assert_eq!(it.nth(0), Some(&13));
+    assert_eq!(it.nth(1), Some(&16));
+
+    let mut it = xs.iter().skip(12);
+    assert_eq!(it.nth(0), None);
+
+}
+
+#[test]
+fn test_iterator_skip_count() {
+    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
+
+    assert_eq!(xs.iter().skip(0).count(), 12);
+    assert_eq!(xs.iter().skip(1).count(), 11);
+    assert_eq!(xs.iter().skip(11).count(), 1);
+    assert_eq!(xs.iter().skip(12).count(), 0);
+    assert_eq!(xs.iter().skip(13).count(), 0);
+}
+
+#[test]
+fn test_iterator_skip_last() {
+    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
+
+    assert_eq!(xs.iter().skip(0).last(), Some(&30));
+    assert_eq!(xs.iter().skip(1).last(), Some(&30));
+    assert_eq!(xs.iter().skip(11).last(), Some(&30));
+    assert_eq!(xs.iter().skip(12).last(), None);
+    assert_eq!(xs.iter().skip(13).last(), None);
+
+    let mut it = xs.iter().skip(5);
+    assert_eq!(it.next(), Some(&13));
+    assert_eq!(it.last(), Some(&30));
+}
+
+#[test]
+fn test_iterator_take() {
+    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19];
+    let ys = [0, 1, 2, 3, 5];
+    let mut it = xs.iter().take(5);
+    let mut i = 0;
+    assert_eq!(it.len(), 5);
+    while let Some(&x) = it.next() {
+        assert_eq!(x, ys[i]);
+        i += 1;
+        assert_eq!(it.len(), 5-i);
+    }
+    assert_eq!(i, ys.len());
+    assert_eq!(it.len(), 0);
+}
+
+#[test]
+fn test_iterator_take_nth() {
+    let xs = [0, 1, 2, 4, 5];
+    let mut it = xs.iter();
+    {
+        let mut take = it.by_ref().take(3);
+        let mut i = 0;
+        while let Some(&x) = take.nth(0) {
+            assert_eq!(x, i);
+            i += 1;
+        }
+    }
+    assert_eq!(it.nth(1), Some(&5));
+    assert_eq!(it.nth(0), None);
+
+    let xs = [0, 1, 2, 3, 4];
+    let mut it = xs.iter().take(7);
+    let mut i = 1;
+    while let Some(&x) = it.nth(1) {
+        assert_eq!(x, i);
+        i += 2;
+    }
+}
+
+#[test]
+fn test_iterator_take_short() {
+    let xs = [0, 1, 2, 3];
+    let ys = [0, 1, 2, 3];
+    let mut it = xs.iter().take(5);
+    let mut i = 0;
+    assert_eq!(it.len(), 4);
+    while let Some(&x) = it.next() {
+        assert_eq!(x, ys[i]);
+        i += 1;
+        assert_eq!(it.len(), 4-i);
+    }
+    assert_eq!(i, ys.len());
+    assert_eq!(it.len(), 0);
+}
+
+#[test]
+fn test_iterator_scan() {
+    // test the type inference
+    fn add(old: &mut isize, new: &usize) -> Option<f64> {
+        *old += *new as isize;
+        Some(*old as f64)
+    }
+    let xs = [0, 1, 2, 3, 4];
+    let ys = [0f64, 1.0, 3.0, 6.0, 10.0];
+
+    let it = xs.iter().scan(0, add);
+    let mut i = 0;
+    for x in it {
+        assert_eq!(x, ys[i]);
+        i += 1;
+    }
+    assert_eq!(i, ys.len());
+}
+
+#[test]
+fn test_iterator_flat_map() {
+    let xs = [0, 3, 6];
+    let ys = [0, 1, 2, 3, 4, 5, 6, 7, 8];
+    let it = xs.iter().flat_map(|&x| (x..).step_by(1).take(3));
+    let mut i = 0;
+    for x in it {
+        assert_eq!(x, ys[i]);
+        i += 1;
+    }
+    assert_eq!(i, ys.len());
+}
+
+#[test]
+fn test_inspect() {
+    let xs = [1, 2, 3, 4];
+    let mut n = 0;
+
+    let ys = xs.iter()
+               .cloned()
+               .inspect(|_| n += 1)
+               .collect::<Vec<usize>>();
+
+    assert_eq!(n, xs.len());
+    assert_eq!(&xs[..], &ys[..]);
+}
+
+#[test]
+fn test_cycle() {
+    let cycle_len = 3;
+    let it = (0..).step_by(1).take(cycle_len).cycle();
+    assert_eq!(it.size_hint(), (usize::MAX, None));
+    for (i, x) in it.take(100).enumerate() {
+        assert_eq!(i % cycle_len, x);
+    }
+
+    let mut it = (0..).step_by(1).take(0).cycle();
+    assert_eq!(it.size_hint(), (0, Some(0)));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_iterator_nth() {
+    let v: &[_] = &[0, 1, 2, 3, 4];
+    for i in 0..v.len() {
+        assert_eq!(v.iter().nth(i).unwrap(), &v[i]);
+    }
+    assert_eq!(v.iter().nth(v.len()), None);
+}
+
+#[test]
+fn test_iterator_last() {
+    let v: &[_] = &[0, 1, 2, 3, 4];
+    assert_eq!(v.iter().last().unwrap(), &4);
+    assert_eq!(v[..1].iter().last().unwrap(), &0);
+}
+
+#[test]
+fn test_iterator_len() {
+    let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    assert_eq!(v[..4].iter().count(), 4);
+    assert_eq!(v[..10].iter().count(), 10);
+    assert_eq!(v[..0].iter().count(), 0);
+}
+
+#[test]
+fn test_iterator_sum() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    assert_eq!(v[..4].iter().cloned().sum::<i32>(), 6);
+    assert_eq!(v.iter().cloned().sum::<i32>(), 55);
+    assert_eq!(v[..0].iter().cloned().sum::<i32>(), 0);
+}
+
+#[test]
+fn test_iterator_sum_result() {
+    let v: &[Result<i32, ()>] = &[Ok(1), Ok(2), Ok(3), Ok(4)];
+    assert_eq!(v.iter().cloned().sum::<Result<i32, _>>(), Ok(10));
+    let v: &[Result<i32, ()>] = &[Ok(1), Err(()), Ok(3), Ok(4)];
+    assert_eq!(v.iter().cloned().sum::<Result<i32, _>>(), Err(()));
+}
+
+#[test]
+fn test_iterator_product() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    assert_eq!(v[..4].iter().cloned().product::<i32>(), 0);
+    assert_eq!(v[1..5].iter().cloned().product::<i32>(), 24);
+    assert_eq!(v[..0].iter().cloned().product::<i32>(), 1);
+}
+
+#[test]
+fn test_iterator_product_result() {
+    let v: &[Result<i32, ()>] = &[Ok(1), Ok(2), Ok(3), Ok(4)];
+    assert_eq!(v.iter().cloned().product::<Result<i32, _>>(), Ok(24));
+    let v: &[Result<i32, ()>] = &[Ok(1), Err(()), Ok(3), Ok(4)];
+    assert_eq!(v.iter().cloned().product::<Result<i32, _>>(), Err(()));
+}
+
+#[test]
+fn test_iterator_max() {
+    let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    assert_eq!(v[..4].iter().cloned().max(), Some(3));
+    assert_eq!(v.iter().cloned().max(), Some(10));
+    assert_eq!(v[..0].iter().cloned().max(), None);
+}
+
+#[test]
+fn test_iterator_min() {
+    let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    assert_eq!(v[..4].iter().cloned().min(), Some(0));
+    assert_eq!(v.iter().cloned().min(), Some(0));
+    assert_eq!(v[..0].iter().cloned().min(), None);
+}
+
+#[test]
+fn test_iterator_size_hint() {
+    let c = (0..).step_by(1);
+    let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+    let v2 = &[10, 11, 12];
+    let vi = v.iter();
+
+    assert_eq!(c.size_hint(), (usize::MAX, None));
+    assert_eq!(vi.clone().size_hint(), (10, Some(10)));
+
+    assert_eq!(c.clone().take(5).size_hint(), (5, Some(5)));
+    assert_eq!(c.clone().skip(5).size_hint().1, None);
+    assert_eq!(c.clone().take_while(|_| false).size_hint(), (0, None));
+    assert_eq!(c.clone().skip_while(|_| false).size_hint(), (0, None));
+    assert_eq!(c.clone().enumerate().size_hint(), (usize::MAX, None));
+    assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (usize::MAX, None));
+    assert_eq!(c.clone().zip(vi.clone()).size_hint(), (10, Some(10)));
+    assert_eq!(c.clone().scan(0, |_,_| Some(0)).size_hint(), (0, None));
+    assert_eq!(c.clone().filter(|_| false).size_hint(), (0, None));
+    assert_eq!(c.clone().map(|_| 0).size_hint(), (usize::MAX, None));
+    assert_eq!(c.filter_map(|_| Some(0)).size_hint(), (0, None));
+
+    assert_eq!(vi.clone().take(5).size_hint(), (5, Some(5)));
+    assert_eq!(vi.clone().take(12).size_hint(), (10, Some(10)));
+    assert_eq!(vi.clone().skip(3).size_hint(), (7, Some(7)));
+    assert_eq!(vi.clone().skip(12).size_hint(), (0, Some(0)));
+    assert_eq!(vi.clone().take_while(|_| false).size_hint(), (0, Some(10)));
+    assert_eq!(vi.clone().skip_while(|_| false).size_hint(), (0, Some(10)));
+    assert_eq!(vi.clone().enumerate().size_hint(), (10, Some(10)));
+    assert_eq!(vi.clone().chain(v2).size_hint(), (13, Some(13)));
+    assert_eq!(vi.clone().zip(v2).size_hint(), (3, Some(3)));
+    assert_eq!(vi.clone().scan(0, |_,_| Some(0)).size_hint(), (0, Some(10)));
+    assert_eq!(vi.clone().filter(|_| false).size_hint(), (0, Some(10)));
+    assert_eq!(vi.clone().map(|&i| i+1).size_hint(), (10, Some(10)));
+    assert_eq!(vi.filter_map(|_| Some(0)).size_hint(), (0, Some(10)));
+}
+
+#[test]
+fn test_collect() {
+    let a = vec![1, 2, 3, 4, 5];
+    let b: Vec<isize> = a.iter().cloned().collect();
+    assert!(a == b);
+}
+
+#[test]
+fn test_all() {
+    let v: Box<[isize]> = Box::new([1, 2, 3, 4, 5]);
+    assert!(v.iter().all(|&x| x < 10));
+    assert!(!v.iter().all(|&x| x % 2 == 0));
+    assert!(!v.iter().all(|&x| x > 100));
+    assert!(v[..0].iter().all(|_| panic!()));
+}
+
+#[test]
+fn test_any() {
+    let v: Box<[isize]> = Box::new([1, 2, 3, 4, 5]);
+    assert!(v.iter().any(|&x| x < 10));
+    assert!(v.iter().any(|&x| x % 2 == 0));
+    assert!(!v.iter().any(|&x| x > 100));
+    assert!(!v[..0].iter().any(|_| panic!()));
+}
+
+#[test]
+fn test_find() {
+    let v: &[isize] = &[1, 3, 9, 27, 103, 14, 11];
+    assert_eq!(*v.iter().find(|&&x| x & 1 == 0).unwrap(), 14);
+    assert_eq!(*v.iter().find(|&&x| x % 3 == 0).unwrap(), 3);
+    assert!(v.iter().find(|&&x| x % 12 == 0).is_none());
+}
+
+#[test]
+fn test_position() {
+    let v = &[1, 3, 9, 27, 103, 14, 11];
+    assert_eq!(v.iter().position(|x| *x & 1 == 0).unwrap(), 5);
+    assert_eq!(v.iter().position(|x| *x % 3 == 0).unwrap(), 1);
+    assert!(v.iter().position(|x| *x % 12 == 0).is_none());
+}
+
+#[test]
+fn test_count() {
+    let xs = &[1, 2, 2, 1, 5, 9, 0, 2];
+    assert_eq!(xs.iter().filter(|x| **x == 2).count(), 3);
+    assert_eq!(xs.iter().filter(|x| **x == 5).count(), 1);
+    assert_eq!(xs.iter().filter(|x| **x == 95).count(), 0);
+}
+
+#[test]
+fn test_max_by_key() {
+    let xs: &[isize] = &[-3, 0, 1, 5, -10];
+    assert_eq!(*xs.iter().max_by_key(|x| x.abs()).unwrap(), -10);
+}
+
+#[test]
+fn test_max_by() {
+    let xs: &[isize] = &[-3, 0, 1, 5, -10];
+    assert_eq!(*xs.iter().max_by(|x, y| x.abs().cmp(&y.abs())).unwrap(), -10);
+}
+
+#[test]
+fn test_min_by_key() {
+    let xs: &[isize] = &[-3, 0, 1, 5, -10];
+    assert_eq!(*xs.iter().min_by_key(|x| x.abs()).unwrap(), 0);
+}
+
+#[test]
+fn test_min_by() {
+    let xs: &[isize] = &[-3, 0, 1, 5, -10];
+    assert_eq!(*xs.iter().min_by(|x, y| x.abs().cmp(&y.abs())).unwrap(), 0);
+}
+
+#[test]
+fn test_by_ref() {
+    let mut xs = 0..10;
+    // sum the first five values
+    let partial_sum = xs.by_ref().take(5).fold(0, |a, b| a + b);
+    assert_eq!(partial_sum, 10);
+    assert_eq!(xs.next(), Some(5));
+}
+
+#[test]
+fn test_rev() {
+    let xs = [2, 4, 6, 8, 10, 12, 14, 16];
+    let mut it = xs.iter();
+    it.next();
+    it.next();
+    assert!(it.rev().cloned().collect::<Vec<isize>>() ==
+            vec![16, 14, 12, 10, 8, 6]);
+}
+
+#[test]
+fn test_cloned() {
+    let xs = [2, 4, 6, 8];
+
+    let mut it = xs.iter().cloned();
+    assert_eq!(it.len(), 4);
+    assert_eq!(it.next(), Some(2));
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.next(), Some(4));
+    assert_eq!(it.len(), 2);
+    assert_eq!(it.next_back(), Some(8));
+    assert_eq!(it.len(), 1);
+    assert_eq!(it.next_back(), Some(6));
+    assert_eq!(it.len(), 0);
+    assert_eq!(it.next_back(), None);
+}
+
+#[test]
+fn test_double_ended_map() {
+    let xs = [1, 2, 3, 4, 5, 6];
+    let mut it = xs.iter().map(|&x| x * -1);
+    assert_eq!(it.next(), Some(-1));
+    assert_eq!(it.next(), Some(-2));
+    assert_eq!(it.next_back(), Some(-6));
+    assert_eq!(it.next_back(), Some(-5));
+    assert_eq!(it.next(), Some(-3));
+    assert_eq!(it.next_back(), Some(-4));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_double_ended_enumerate() {
+    let xs = [1, 2, 3, 4, 5, 6];
+    let mut it = xs.iter().cloned().enumerate();
+    assert_eq!(it.next(), Some((0, 1)));
+    assert_eq!(it.next(), Some((1, 2)));
+    assert_eq!(it.next_back(), Some((5, 6)));
+    assert_eq!(it.next_back(), Some((4, 5)));
+    assert_eq!(it.next_back(), Some((3, 4)));
+    assert_eq!(it.next_back(), Some((2, 3)));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_double_ended_zip() {
+    let xs = [1, 2, 3, 4, 5, 6];
+    let ys = [1, 2, 3, 7];
+    let a = xs.iter().cloned();
+    let b = ys.iter().cloned();
+    let mut it = a.zip(b);
+    assert_eq!(it.next(), Some((1, 1)));
+    assert_eq!(it.next(), Some((2, 2)));
+    assert_eq!(it.next_back(), Some((4, 7)));
+    assert_eq!(it.next_back(), Some((3, 3)));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_double_ended_filter() {
+    let xs = [1, 2, 3, 4, 5, 6];
+    let mut it = xs.iter().filter(|&x| *x & 1 == 0);
+    assert_eq!(it.next_back().unwrap(), &6);
+    assert_eq!(it.next_back().unwrap(), &4);
+    assert_eq!(it.next().unwrap(), &2);
+    assert_eq!(it.next_back(), None);
+}
+
+#[test]
+fn test_double_ended_filter_map() {
+    let xs = [1, 2, 3, 4, 5, 6];
+    let mut it = xs.iter().filter_map(|&x| if x & 1 == 0 { Some(x * 2) } else { None });
+    assert_eq!(it.next_back().unwrap(), 12);
+    assert_eq!(it.next_back().unwrap(), 8);
+    assert_eq!(it.next().unwrap(), 4);
+    assert_eq!(it.next_back(), None);
+}
+
+#[test]
+fn test_double_ended_chain() {
+    let xs = [1, 2, 3, 4, 5];
+    let ys = [7, 9, 11];
+    let mut it = xs.iter().chain(&ys).rev();
+    assert_eq!(it.next().unwrap(), &11);
+    assert_eq!(it.next().unwrap(), &9);
+    assert_eq!(it.next_back().unwrap(), &1);
+    assert_eq!(it.next_back().unwrap(), &2);
+    assert_eq!(it.next_back().unwrap(), &3);
+    assert_eq!(it.next_back().unwrap(), &4);
+    assert_eq!(it.next_back().unwrap(), &5);
+    assert_eq!(it.next_back().unwrap(), &7);
+    assert_eq!(it.next_back(), None);
+
+
+    // test that .chain() is well behaved with an unfused iterator
+    struct CrazyIterator(bool);
+    impl CrazyIterator { fn new() -> CrazyIterator { CrazyIterator(false) } }
+    impl Iterator for CrazyIterator {
+        type Item = i32;
+        fn next(&mut self) -> Option<i32> {
+            if self.0 { Some(99) } else { self.0 = true; None }
+        }
+    }
+
+    impl DoubleEndedIterator for CrazyIterator {
+        fn next_back(&mut self) -> Option<i32> {
+            self.next()
+        }
+    }
+
+    assert_eq!(CrazyIterator::new().chain(0..10).rev().last(), Some(0));
+    assert!((0..10).chain(CrazyIterator::new()).rev().any(|i| i == 0));
+}
+
+#[test]
+fn test_rposition() {
+    fn f(xy: &(isize, char)) -> bool { let (_x, y) = *xy; y == 'b' }
+    fn g(xy: &(isize, char)) -> bool { let (_x, y) = *xy; y == 'd' }
+    let v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
+
+    assert_eq!(v.iter().rposition(f), Some(3));
+    assert!(v.iter().rposition(g).is_none());
+}
+
+#[test]
+#[should_panic]
+fn test_rposition_panic() {
+    let v: [(Box<_>, Box<_>); 4] =
+        [(box 0, box 0), (box 0, box 0),
+         (box 0, box 0), (box 0, box 0)];
+    let mut i = 0;
+    v.iter().rposition(|_elt| {
+        if i == 2 {
+            panic!()
+        }
+        i += 1;
+        false
+    });
+}
+
+
+#[test]
+fn test_double_ended_flat_map() {
+    let u = [0,1];
+    let v = [5,6,7,8];
+    let mut it = u.iter().flat_map(|x| &v[*x..v.len()]);
+    assert_eq!(it.next_back().unwrap(), &8);
+    assert_eq!(it.next().unwrap(),      &5);
+    assert_eq!(it.next_back().unwrap(), &7);
+    assert_eq!(it.next_back().unwrap(), &6);
+    assert_eq!(it.next_back().unwrap(), &8);
+    assert_eq!(it.next().unwrap(),      &6);
+    assert_eq!(it.next_back().unwrap(), &7);
+    assert_eq!(it.next_back(), None);
+    assert_eq!(it.next(),      None);
+    assert_eq!(it.next_back(), None);
+}
+
+#[test]
+fn test_double_ended_range() {
+    assert_eq!((11..14).rev().collect::<Vec<_>>(), [13, 12, 11]);
+    for _ in (10..0).rev() {
+        panic!("unreachable");
+    }
+
+    assert_eq!((11..14).rev().collect::<Vec<_>>(), [13, 12, 11]);
+    for _ in (10..0).rev() {
+        panic!("unreachable");
+    }
+}
+
+#[test]
+fn test_range() {
+    assert_eq!((0..5).collect::<Vec<_>>(), [0, 1, 2, 3, 4]);
+    assert_eq!((-10..-1).collect::<Vec<_>>(), [-10, -9, -8, -7, -6, -5, -4, -3, -2]);
+    assert_eq!((0..5).rev().collect::<Vec<_>>(), [4, 3, 2, 1, 0]);
+    assert_eq!((200..-5).count(), 0);
+    assert_eq!((200..-5).rev().count(), 0);
+    assert_eq!((200..200).count(), 0);
+    assert_eq!((200..200).rev().count(), 0);
+
+    assert_eq!((0..100).size_hint(), (100, Some(100)));
+    // this test is only meaningful when sizeof usize < sizeof u64
+    assert_eq!((usize::MAX - 1..usize::MAX).size_hint(), (1, Some(1)));
+    assert_eq!((-10..-1).size_hint(), (9, Some(9)));
+    assert_eq!((-1..-10).size_hint(), (0, Some(0)));
+
+    assert_eq!((-70..58).size_hint(), (128, Some(128)));
+    assert_eq!((-128..127).size_hint(), (255, Some(255)));
+    assert_eq!((-2..isize::MAX).size_hint(),
+               (isize::MAX as usize + 2, Some(isize::MAX as usize + 2)));
+}
+
+#[test]
+fn test_range_step() {
+    assert_eq!((0..20).step_by(5).collect::<Vec<isize>>(), [0, 5, 10, 15]);
+    assert_eq!((20..0).step_by(-5).collect::<Vec<isize>>(), [20, 15, 10, 5]);
+    assert_eq!((20..0).step_by(-6).collect::<Vec<isize>>(), [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<isize>>(), []);
+    assert_eq!((200..200).step_by(1).collect::<Vec<isize>>(), []);
+
+    assert_eq!((0..20).step_by(1).size_hint(), (20, Some(20)));
+    assert_eq!((0..20).step_by(21).size_hint(), (1, Some(1)));
+    assert_eq!((0..20).step_by(5).size_hint(), (4, Some(4)));
+    assert_eq!((20..0).step_by(-5).size_hint(), (4, Some(4)));
+    assert_eq!((20..0).step_by(-6).size_hint(), (4, Some(4)));
+    assert_eq!((20..-5).step_by(1).size_hint(), (0, Some(0)));
+    assert_eq!((20..20).step_by(1).size_hint(), (0, Some(0)));
+    assert_eq!((0..1).step_by(0).size_hint(), (0, None));
+    assert_eq!((i8::MAX..i8::MIN).step_by(i8::MIN).size_hint(), (2, Some(2)));
+    assert_eq!((i16::MIN..i16::MAX).step_by(i16::MAX).size_hint(), (3, Some(3)));
+    assert_eq!((isize::MIN..isize::MAX).step_by(1).size_hint(), (usize::MAX, Some(usize::MAX)));
+}
+
+#[test]
+fn test_repeat() {
+    let mut it = repeat(42);
+    assert_eq!(it.next(), Some(42));
+    assert_eq!(it.next(), Some(42));
+    assert_eq!(it.next(), Some(42));
+}
+
+#[test]
+fn test_fuse() {
+    let mut it = 0..3;
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.next(), Some(0));
+    assert_eq!(it.len(), 2);
+    assert_eq!(it.next(), Some(1));
+    assert_eq!(it.len(), 1);
+    assert_eq!(it.next(), Some(2));
+    assert_eq!(it.len(), 0);
+    assert_eq!(it.next(), None);
+    assert_eq!(it.len(), 0);
+    assert_eq!(it.next(), None);
+    assert_eq!(it.len(), 0);
+    assert_eq!(it.next(), None);
+    assert_eq!(it.len(), 0);
+}
+
+#[test]
+fn test_fuse_nth() {
+    let xs = [0, 1, 2];
+    let mut it = xs.iter();
+
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.nth(2), Some(&2));
+    assert_eq!(it.len(), 0);
+    assert_eq!(it.nth(2), None);
+    assert_eq!(it.len(), 0);
+}
+
+#[test]
+fn test_fuse_last() {
+    let xs = [0, 1, 2];
+    let it = xs.iter();
+
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.last(), Some(&2));
+}
+
+#[test]
+fn test_fuse_count() {
+    let xs = [0, 1, 2];
+    let it = xs.iter();
+
+    assert_eq!(it.len(), 3);
+    assert_eq!(it.count(), 3);
+    // Can't check len now because count consumes.
+}
+
+#[test]
+fn test_once() {
+    let mut it = once(42);
+    assert_eq!(it.next(), Some(42));
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_empty() {
+    let mut it = empty::<i32>();
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_chain_fold() {
+    let xs = [1, 2, 3];
+    let ys = [1, 2, 0];
+
+    let mut iter = xs.iter().chain(&ys);
+    iter.next();
+    let mut result = Vec::new();
+    iter.fold((), |(), &elt| result.push(elt));
+    assert_eq!(&[2, 3, 1, 2, 0], &result[..]);
+}
+
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
new file mode 100644 (file)
index 0000000..d92c378
--- /dev/null
@@ -0,0 +1,63 @@
+// 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.
+
+#![deny(warnings)]
+
+#![feature(box_syntax)]
+#![feature(char_escape_debug)]
+#![feature(const_fn)]
+#![feature(core_private_bignum)]
+#![feature(core_private_diy_float)]
+#![feature(dec2flt)]
+#![feature(decode_utf8)]
+#![feature(fixed_size_array)]
+#![feature(flt2dec)]
+#![feature(fmt_internals)]
+#![feature(libc)]
+#![feature(nonzero)]
+#![feature(rand)]
+#![feature(raw)]
+#![feature(sip_hash_13)]
+#![feature(slice_patterns)]
+#![feature(sort_internals)]
+#![feature(sort_unstable)]
+#![feature(step_by)]
+#![feature(test)]
+#![feature(try_from)]
+#![feature(unicode)]
+#![feature(unique)]
+
+extern crate core;
+extern crate test;
+extern crate libc;
+extern crate std_unicode;
+extern crate rand;
+
+mod any;
+mod array;
+mod atomic;
+mod cell;
+mod char;
+mod clone;
+mod cmp;
+mod fmt;
+mod hash;
+mod intrinsics;
+mod iter;
+mod mem;
+mod nonzero;
+mod num;
+mod ops;
+mod option;
+mod ptr;
+mod result;
+mod slice;
+mod str;
+mod tuple;
diff --git a/src/libcore/tests/mem.rs b/src/libcore/tests/mem.rs
new file mode 100644 (file)
index 0000000..86e59c7
--- /dev/null
@@ -0,0 +1,123 @@
+// Copyright 2014-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 core::mem::*;
+
+#[test]
+fn size_of_basic() {
+    assert_eq!(size_of::<u8>(), 1);
+    assert_eq!(size_of::<u16>(), 2);
+    assert_eq!(size_of::<u32>(), 4);
+    assert_eq!(size_of::<u64>(), 8);
+}
+
+#[test]
+#[cfg(target_pointer_width = "16")]
+fn size_of_16() {
+    assert_eq!(size_of::<usize>(), 2);
+    assert_eq!(size_of::<*const usize>(), 2);
+}
+
+#[test]
+#[cfg(target_pointer_width = "32")]
+fn size_of_32() {
+    assert_eq!(size_of::<usize>(), 4);
+    assert_eq!(size_of::<*const usize>(), 4);
+}
+
+#[test]
+#[cfg(target_pointer_width = "64")]
+fn size_of_64() {
+    assert_eq!(size_of::<usize>(), 8);
+    assert_eq!(size_of::<*const usize>(), 8);
+}
+
+#[test]
+fn size_of_val_basic() {
+    assert_eq!(size_of_val(&1u8), 1);
+    assert_eq!(size_of_val(&1u16), 2);
+    assert_eq!(size_of_val(&1u32), 4);
+    assert_eq!(size_of_val(&1u64), 8);
+}
+
+#[test]
+fn align_of_basic() {
+    assert_eq!(align_of::<u8>(), 1);
+    assert_eq!(align_of::<u16>(), 2);
+    assert_eq!(align_of::<u32>(), 4);
+}
+
+#[test]
+#[cfg(target_pointer_width = "16")]
+fn align_of_16() {
+    assert_eq!(align_of::<usize>(), 2);
+    assert_eq!(align_of::<*const usize>(), 2);
+}
+
+#[test]
+#[cfg(target_pointer_width = "32")]
+fn align_of_32() {
+    assert_eq!(align_of::<usize>(), 4);
+    assert_eq!(align_of::<*const usize>(), 4);
+}
+
+#[test]
+#[cfg(target_pointer_width = "64")]
+fn align_of_64() {
+    assert_eq!(align_of::<usize>(), 8);
+    assert_eq!(align_of::<*const usize>(), 8);
+}
+
+#[test]
+fn align_of_val_basic() {
+    assert_eq!(align_of_val(&1u8), 1);
+    assert_eq!(align_of_val(&1u16), 2);
+    assert_eq!(align_of_val(&1u32), 4);
+}
+
+#[test]
+fn test_swap() {
+    let mut x = 31337;
+    let mut y = 42;
+    swap(&mut x, &mut y);
+    assert_eq!(x, 42);
+    assert_eq!(y, 31337);
+}
+
+#[test]
+fn test_replace() {
+    let mut x = Some("test".to_string());
+    let y = replace(&mut x, None);
+    assert!(x.is_none());
+    assert!(y.is_some());
+}
+
+#[test]
+fn test_transmute_copy() {
+    assert_eq!(1, unsafe { transmute_copy(&1) });
+}
+
+#[test]
+fn test_transmute() {
+    trait Foo { fn dummy(&self) { } }
+    impl Foo for isize {}
+
+    let a = box 100isize as Box<Foo>;
+    unsafe {
+        let x: ::core::raw::TraitObject = transmute(a);
+        assert!(*(x.data as *const isize) == 100);
+        let _x: Box<Foo> = transmute(x);
+    }
+
+    unsafe {
+        assert_eq!(transmute::<_, Vec<u8>>("L".to_string()), [76]);
+    }
+}
+
diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs
new file mode 100644 (file)
index 0000000..7a367dd
--- /dev/null
@@ -0,0 +1,100 @@
+// 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 core::nonzero::NonZero;
+use core::option::Option;
+use core::option::Option::{Some, None};
+use std::mem::size_of;
+
+#[test]
+fn test_create_nonzero_instance() {
+    let _a = unsafe {
+        NonZero::new(21)
+    };
+}
+
+#[test]
+fn test_size_nonzero_in_option() {
+    assert_eq!(size_of::<NonZero<u32>>(), size_of::<Option<NonZero<u32>>>());
+}
+
+#[test]
+fn test_match_on_nonzero_option() {
+    let a = Some(unsafe {
+        NonZero::new(42)
+    });
+    match a {
+        Some(val) => assert_eq!(*val, 42),
+        None => panic!("unexpected None while matching on Some(NonZero(_))")
+    }
+
+    match unsafe { Some(NonZero::new(43)) } {
+        Some(val) => assert_eq!(*val, 43),
+        None => panic!("unexpected None while matching on Some(NonZero(_))")
+    }
+}
+
+#[test]
+fn test_match_option_empty_vec() {
+    let a: Option<Vec<isize>> = Some(vec![]);
+    match a {
+        None => panic!("unexpected None while matching on Some(vec![])"),
+        _ => {}
+    }
+}
+
+#[test]
+fn test_match_option_vec() {
+    let a = Some(vec![1, 2, 3, 4]);
+    match a {
+        Some(v) => assert_eq!(v, [1, 2, 3, 4]),
+        None => panic!("unexpected None while matching on Some(vec![1, 2, 3, 4])")
+    }
+}
+
+#[test]
+fn test_match_option_rc() {
+    use std::rc::Rc;
+
+    let five = Rc::new(5);
+    match Some(five) {
+        Some(r) => assert_eq!(*r, 5),
+        None => panic!("unexpected None while matching on Some(Rc::new(5))")
+    }
+}
+
+#[test]
+fn test_match_option_arc() {
+    use std::sync::Arc;
+
+    let five = Arc::new(5);
+    match Some(five) {
+        Some(a) => assert_eq!(*a, 5),
+        None => panic!("unexpected None while matching on Some(Arc::new(5))")
+    }
+}
+
+#[test]
+fn test_match_option_empty_string() {
+    let a = Some(String::new());
+    match a {
+        None => panic!("unexpected None while matching on Some(String::new())"),
+        _ => {}
+    }
+}
+
+#[test]
+fn test_match_option_string() {
+    let five = "Five".to_string();
+    match Some(five) {
+        Some(s) => assert_eq!(s, "Five"),
+        None => panic!("unexpected None while matching on Some(String { ... })")
+    }
+}
diff --git a/src/libcore/tests/num/bignum.rs b/src/libcore/tests/num/bignum.rs
new file mode 100644 (file)
index 0000000..58a9dd1
--- /dev/null
@@ -0,0 +1,249 @@
+// 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::prelude::v1::*;
+use core::num::bignum::tests::Big8x3 as Big;
+
+#[test]
+#[should_panic]
+fn test_from_u64_overflow() {
+    Big::from_u64(0x1000000);
+}
+
+#[test]
+fn test_add() {
+    assert_eq!(*Big::from_small(3).add(&Big::from_small(4)), Big::from_small(7));
+    assert_eq!(*Big::from_small(3).add(&Big::from_small(0)), Big::from_small(3));
+    assert_eq!(*Big::from_small(0).add(&Big::from_small(3)), Big::from_small(3));
+    assert_eq!(*Big::from_small(3).add(&Big::from_u64(0xfffe)), Big::from_u64(0x10001));
+    assert_eq!(*Big::from_u64(0xfedc).add(&Big::from_u64(0x789)), Big::from_u64(0x10665));
+    assert_eq!(*Big::from_u64(0x789).add(&Big::from_u64(0xfedc)), Big::from_u64(0x10665));
+}
+
+#[test]
+#[should_panic]
+fn test_add_overflow_1() {
+    Big::from_small(1).add(&Big::from_u64(0xffffff));
+}
+
+#[test]
+#[should_panic]
+fn test_add_overflow_2() {
+    Big::from_u64(0xffffff).add(&Big::from_small(1));
+}
+
+#[test]
+fn test_add_small() {
+    assert_eq!(*Big::from_small(3).add_small(4), Big::from_small(7));
+    assert_eq!(*Big::from_small(3).add_small(0), Big::from_small(3));
+    assert_eq!(*Big::from_small(0).add_small(3), Big::from_small(3));
+    assert_eq!(*Big::from_small(7).add_small(250), Big::from_u64(257));
+    assert_eq!(*Big::from_u64(0x7fff).add_small(1), Big::from_u64(0x8000));
+    assert_eq!(*Big::from_u64(0x2ffe).add_small(0x35), Big::from_u64(0x3033));
+    assert_eq!(*Big::from_small(0xdc).add_small(0x89), Big::from_u64(0x165));
+}
+
+#[test]
+#[should_panic]
+fn test_add_small_overflow() {
+    Big::from_u64(0xffffff).add_small(1);
+}
+
+#[test]
+fn test_sub() {
+    assert_eq!(*Big::from_small(7).sub(&Big::from_small(4)), Big::from_small(3));
+    assert_eq!(*Big::from_u64(0x10665).sub(&Big::from_u64(0x789)), Big::from_u64(0xfedc));
+    assert_eq!(*Big::from_u64(0x10665).sub(&Big::from_u64(0xfedc)), Big::from_u64(0x789));
+    assert_eq!(*Big::from_u64(0x10665).sub(&Big::from_u64(0x10664)), Big::from_small(1));
+    assert_eq!(*Big::from_u64(0x10665).sub(&Big::from_u64(0x10665)), Big::from_small(0));
+}
+
+#[test]
+#[should_panic]
+fn test_sub_underflow_1() {
+    Big::from_u64(0x10665).sub(&Big::from_u64(0x10666));
+}
+
+#[test]
+#[should_panic]
+fn test_sub_underflow_2() {
+    Big::from_small(0).sub(&Big::from_u64(0x123456));
+}
+
+#[test]
+fn test_mul_small() {
+    assert_eq!(*Big::from_small(7).mul_small(5), Big::from_small(35));
+    assert_eq!(*Big::from_small(0xff).mul_small(0xff), Big::from_u64(0xfe01));
+    assert_eq!(*Big::from_u64(0xffffff/13).mul_small(13), Big::from_u64(0xffffff));
+}
+
+#[test]
+#[should_panic]
+fn test_mul_small_overflow() {
+    Big::from_u64(0x800000).mul_small(2);
+}
+
+#[test]
+fn test_mul_pow2() {
+    assert_eq!(*Big::from_small(0x7).mul_pow2(4), Big::from_small(0x70));
+    assert_eq!(*Big::from_small(0xff).mul_pow2(1), Big::from_u64(0x1fe));
+    assert_eq!(*Big::from_small(0xff).mul_pow2(12), Big::from_u64(0xff000));
+    assert_eq!(*Big::from_small(0x1).mul_pow2(23), Big::from_u64(0x800000));
+    assert_eq!(*Big::from_u64(0x123).mul_pow2(0), Big::from_u64(0x123));
+    assert_eq!(*Big::from_u64(0x123).mul_pow2(7), Big::from_u64(0x9180));
+    assert_eq!(*Big::from_u64(0x123).mul_pow2(15), Big::from_u64(0x918000));
+    assert_eq!(*Big::from_small(0).mul_pow2(23), Big::from_small(0));
+}
+
+#[test]
+#[should_panic]
+fn test_mul_pow2_overflow_1() {
+    Big::from_u64(0x1).mul_pow2(24);
+}
+
+#[test]
+#[should_panic]
+fn test_mul_pow2_overflow_2() {
+    Big::from_u64(0x123).mul_pow2(16);
+}
+
+#[test]
+fn test_mul_pow5() {
+    assert_eq!(*Big::from_small(42).mul_pow5(0), Big::from_small(42));
+    assert_eq!(*Big::from_small(1).mul_pow5(2), Big::from_small(25));
+    assert_eq!(*Big::from_small(1).mul_pow5(4), Big::from_u64(25 * 25));
+    assert_eq!(*Big::from_small(4).mul_pow5(3), Big::from_u64(500));
+    assert_eq!(*Big::from_small(140).mul_pow5(2), Big::from_u64(25 * 140));
+    assert_eq!(*Big::from_small(25).mul_pow5(1), Big::from_small(125));
+    assert_eq!(*Big::from_small(125).mul_pow5(7), Big::from_u64(9765625));
+    assert_eq!(*Big::from_small(0).mul_pow5(127), Big::from_small(0));
+}
+
+#[test]
+#[should_panic]
+fn test_mul_pow5_overflow_1() {
+    Big::from_small(1).mul_pow5(12);
+}
+
+#[test]
+#[should_panic]
+fn test_mul_pow5_overflow_2() {
+    Big::from_small(230).mul_pow5(8);
+}
+
+#[test]
+fn test_mul_digits() {
+    assert_eq!(*Big::from_small(3).mul_digits(&[5]), Big::from_small(15));
+    assert_eq!(*Big::from_small(0xff).mul_digits(&[0xff]), Big::from_u64(0xfe01));
+    assert_eq!(*Big::from_u64(0x123).mul_digits(&[0x56, 0x4]), Big::from_u64(0x4edc2));
+    assert_eq!(*Big::from_u64(0x12345).mul_digits(&[0x67]), Big::from_u64(0x7530c3));
+    assert_eq!(*Big::from_small(0x12).mul_digits(&[0x67, 0x45, 0x3]), Big::from_u64(0x3ae13e));
+    assert_eq!(*Big::from_u64(0xffffff/13).mul_digits(&[13]), Big::from_u64(0xffffff));
+    assert_eq!(*Big::from_small(13).mul_digits(&[0x3b, 0xb1, 0x13]), Big::from_u64(0xffffff));
+}
+
+#[test]
+#[should_panic]
+fn test_mul_digits_overflow_1() {
+    Big::from_u64(0x800000).mul_digits(&[2]);
+}
+
+#[test]
+#[should_panic]
+fn test_mul_digits_overflow_2() {
+    Big::from_u64(0x1000).mul_digits(&[0, 0x10]);
+}
+
+#[test]
+fn test_div_rem_small() {
+    let as_val = |(q, r): (&mut Big, u8)| (q.clone(), r);
+    assert_eq!(as_val(Big::from_small(0xff).div_rem_small(15)), (Big::from_small(17), 0));
+    assert_eq!(as_val(Big::from_small(0xff).div_rem_small(16)), (Big::from_small(15), 15));
+    assert_eq!(as_val(Big::from_small(3).div_rem_small(40)), (Big::from_small(0), 3));
+    assert_eq!(as_val(Big::from_u64(0xffffff).div_rem_small(123)),
+               (Big::from_u64(0xffffff / 123), (0xffffffu64 % 123) as u8));
+    assert_eq!(as_val(Big::from_u64(0x10000).div_rem_small(123)),
+               (Big::from_u64(0x10000 / 123), (0x10000u64 % 123) as u8));
+}
+
+#[test]
+fn test_div_rem() {
+    fn div_rem(n: u64, d: u64) -> (Big, Big) {
+        let mut q = Big::from_small(42);
+        let mut r = Big::from_small(42);
+        Big::from_u64(n).div_rem(&Big::from_u64(d), &mut q, &mut r);
+        (q, r)
+    }
+    assert_eq!(div_rem(1, 1), (Big::from_small(1), Big::from_small(0)));
+    assert_eq!(div_rem(4, 3), (Big::from_small(1), Big::from_small(1)));
+    assert_eq!(div_rem(1, 7), (Big::from_small(0), Big::from_small(1)));
+    assert_eq!(div_rem(45, 9), (Big::from_small(5), Big::from_small(0)));
+    assert_eq!(div_rem(103, 9), (Big::from_small(11), Big::from_small(4)));
+    assert_eq!(div_rem(123456, 77), (Big::from_u64(1603), Big::from_small(25)));
+    assert_eq!(div_rem(0xffff, 1), (Big::from_u64(0xffff), Big::from_small(0)));
+    assert_eq!(div_rem(0xeeee, 0xffff), (Big::from_small(0), Big::from_u64(0xeeee)));
+    assert_eq!(div_rem(2_000_000, 2), (Big::from_u64(1_000_000), Big::from_u64(0)));
+}
+
+#[test]
+fn test_is_zero() {
+    assert!(Big::from_small(0).is_zero());
+    assert!(!Big::from_small(3).is_zero());
+    assert!(!Big::from_u64(0x123).is_zero());
+    assert!(!Big::from_u64(0xffffff).sub(&Big::from_u64(0xfffffe)).is_zero());
+    assert!(Big::from_u64(0xffffff).sub(&Big::from_u64(0xffffff)).is_zero());
+}
+
+#[test]
+fn test_get_bit() {
+    let x = Big::from_small(0b1101);
+    assert_eq!(x.get_bit(0), 1);
+    assert_eq!(x.get_bit(1), 0);
+    assert_eq!(x.get_bit(2), 1);
+    assert_eq!(x.get_bit(3), 1);
+    let y = Big::from_u64(1 << 15);
+    assert_eq!(y.get_bit(14), 0);
+    assert_eq!(y.get_bit(15), 1);
+    assert_eq!(y.get_bit(16), 0);
+}
+
+#[test]
+#[should_panic]
+fn test_get_bit_out_of_range() {
+    Big::from_small(42).get_bit(24);
+}
+
+#[test]
+fn test_bit_length() {
+    assert_eq!(Big::from_small(0).bit_length(), 0);
+    assert_eq!(Big::from_small(1).bit_length(), 1);
+    assert_eq!(Big::from_small(5).bit_length(), 3);
+    assert_eq!(Big::from_small(0x18).bit_length(), 5);
+    assert_eq!(Big::from_u64(0x4073).bit_length(), 15);
+    assert_eq!(Big::from_u64(0xffffff).bit_length(), 24);
+}
+
+#[test]
+fn test_ord() {
+    assert!(Big::from_u64(0) < Big::from_u64(0xffffff));
+    assert!(Big::from_u64(0x102) < Big::from_u64(0x201));
+}
+
+#[test]
+fn test_fmt() {
+    assert_eq!(format!("{:?}", Big::from_u64(0)), "0x0");
+    assert_eq!(format!("{:?}", Big::from_u64(0x1)), "0x1");
+    assert_eq!(format!("{:?}", Big::from_u64(0x12)), "0x12");
+    assert_eq!(format!("{:?}", Big::from_u64(0x123)), "0x1_23");
+    assert_eq!(format!("{:?}", Big::from_u64(0x1234)), "0x12_34");
+    assert_eq!(format!("{:?}", Big::from_u64(0x12345)), "0x1_23_45");
+    assert_eq!(format!("{:?}", Big::from_u64(0x123456)), "0x12_34_56");
+}
+
diff --git a/src/libcore/tests/num/dec2flt/mod.rs b/src/libcore/tests/num/dec2flt/mod.rs
new file mode 100644 (file)
index 0000000..5d546c6
--- /dev/null
@@ -0,0 +1,145 @@
+// 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(overflowing_literals)]
+
+use std::{i64, f32, f64};
+
+mod parse;
+mod rawfp;
+
+// Take a float literal, turn it into a string in various ways (that are all trusted
+// to be correct) and see if those strings are parsed back to the value of the literal.
+// Requires a *polymorphic literal*, i.e. one that can serve as f64 as well as f32.
+macro_rules! test_literal {
+    ($x: expr) => ({
+        let x32: f32 = $x;
+        let x64: f64 = $x;
+        let inputs = &[stringify!($x).into(), format!("{:?}", x64), format!("{:e}", x64)];
+        for input in inputs {
+            assert_eq!(input.parse(), Ok(x64));
+            assert_eq!(input.parse(), Ok(x32));
+            let neg_input = &format!("-{}", input);
+            assert_eq!(neg_input.parse(), Ok(-x64));
+            assert_eq!(neg_input.parse(), Ok(-x32));
+        }
+    })
+}
+
+#[test]
+fn ordinary() {
+    test_literal!(1.0);
+    test_literal!(3e-5);
+    test_literal!(0.1);
+    test_literal!(12345.);
+    test_literal!(0.9999999);
+    test_literal!(2.2250738585072014e-308);
+}
+
+#[test]
+fn special_code_paths() {
+    test_literal!(36893488147419103229.0); // 2^65 - 3, triggers half-to-even with even significand
+    test_literal!(101e-33); // Triggers the tricky underflow case in AlgorithmM (for f32)
+    test_literal!(1e23); // Triggers AlgorithmR
+    test_literal!(2075e23); // Triggers another path through AlgorithmR
+    test_literal!(8713e-23); // ... and yet another.
+}
+
+#[test]
+fn large() {
+    test_literal!(1e300);
+    test_literal!(123456789.34567e250);
+    test_literal!(943794359898089732078308743689303290943794359843568973207830874368930329.);
+}
+
+#[test]
+fn subnormals() {
+    test_literal!(5e-324);
+    test_literal!(91e-324);
+    test_literal!(1e-322);
+    test_literal!(13245643e-320);
+    test_literal!(2.22507385851e-308);
+    test_literal!(2.1e-308);
+    test_literal!(4.9406564584124654e-324);
+}
+
+#[test]
+fn infinity() {
+    test_literal!(1e400);
+    test_literal!(1e309);
+    test_literal!(2e308);
+    test_literal!(1.7976931348624e308);
+}
+
+#[test]
+fn zero() {
+    test_literal!(0.0);
+    test_literal!(1e-325);
+    test_literal!(1e-326);
+    test_literal!(1e-500);
+}
+
+#[test]
+fn fast_path_correct() {
+    // This number triggers the fast path and is handled incorrectly when compiling on
+    // x86 without SSE2 (i.e., using the x87 FPU stack).
+    test_literal!(1.448997445238699);
+}
+
+#[test]
+fn lonely_dot() {
+    assert!(".".parse::<f32>().is_err());
+    assert!(".".parse::<f64>().is_err());
+}
+
+#[test]
+fn lonely_sign() {
+    assert!("+".parse::<f32>().is_err());
+    assert!("-".parse::<f64>().is_err());
+}
+
+#[test]
+fn whitespace() {
+    assert!(" 1.0".parse::<f32>().is_err());
+    assert!("1.0 ".parse::<f64>().is_err());
+}
+
+#[test]
+fn nan() {
+    assert!("NaN".parse::<f32>().unwrap().is_nan());
+    assert!("NaN".parse::<f64>().unwrap().is_nan());
+}
+
+#[test]
+fn inf() {
+    assert_eq!("inf".parse(), Ok(f64::INFINITY));
+    assert_eq!("-inf".parse(), Ok(f64::NEG_INFINITY));
+    assert_eq!("inf".parse(), Ok(f32::INFINITY));
+    assert_eq!("-inf".parse(), Ok(f32::NEG_INFINITY));
+}
+
+#[test]
+fn massive_exponent() {
+    let max = i64::MAX;
+    assert_eq!(format!("1e{}000", max).parse(), Ok(f64::INFINITY));
+    assert_eq!(format!("1e-{}000", max).parse(), Ok(0.0));
+    assert_eq!(format!("1e{}000", max).parse(), Ok(f64::INFINITY));
+}
+
+#[test]
+fn borderline_overflow() {
+    let mut s = "0.".to_string();
+    for _ in 0..375 {
+        s.push('3');
+    }
+    // At the time of this writing, this returns Err(..), but this is a bug that should be fixed.
+    // It makes no sense to enshrine that in a test, the important part is that it doesn't panic.
+    let _ = s.parse::<f64>();
+}
diff --git a/src/libcore/tests/num/dec2flt/parse.rs b/src/libcore/tests/num/dec2flt/parse.rs
new file mode 100644 (file)
index 0000000..09acf2b
--- /dev/null
@@ -0,0 +1,52 @@
+// 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::iter;
+use core::num::dec2flt::parse::{Decimal, parse_decimal};
+use core::num::dec2flt::parse::ParseResult::{Valid, Invalid};
+
+#[test]
+fn missing_pieces() {
+    let permutations = &[".e", "1e", "e4", "e", ".12e", "321.e", "32.12e+", "12.32e-"];
+    for &s in permutations {
+        assert_eq!(parse_decimal(s), Invalid);
+    }
+}
+
+#[test]
+fn invalid_chars() {
+    let invalid = "r,?<j";
+    let valid_strings = &["123", "666.", ".1", "5e1", "7e-3", "0.0e+1"];
+    for c in invalid.chars() {
+        for s in valid_strings {
+            for i in 0..s.len() {
+                let mut input = String::new();
+                input.push_str(s);
+                input.insert(i, c);
+                assert!(parse_decimal(&input) == Invalid, "did not reject invalid {:?}", input);
+            }
+        }
+    }
+}
+
+#[test]
+fn valid() {
+    assert_eq!(parse_decimal("123.456e789"), Valid(Decimal::new(b"123", b"456", 789)));
+    assert_eq!(parse_decimal("123.456e+789"), Valid(Decimal::new(b"123", b"456", 789)));
+    assert_eq!(parse_decimal("123.456e-789"), Valid(Decimal::new(b"123", b"456", -789)));
+    assert_eq!(parse_decimal(".050"), Valid(Decimal::new(b"", b"050", 0)));
+    assert_eq!(parse_decimal("999"), Valid(Decimal::new(b"999", b"", 0)));
+    assert_eq!(parse_decimal("1.e300"), Valid(Decimal::new(b"1", b"", 300)));
+    assert_eq!(parse_decimal(".1e300"), Valid(Decimal::new(b"", b"1", 300)));
+    assert_eq!(parse_decimal("101e-33"), Valid(Decimal::new(b"101", b"", -33)));
+    let zeros: String = iter::repeat('0').take(25).collect();
+    let s = format!("1.5e{}", zeros);
+    assert_eq!(parse_decimal(&s), Valid(Decimal::new(b"1", b"5", 0)));
+}
diff --git a/src/libcore/tests/num/dec2flt/rawfp.rs b/src/libcore/tests/num/dec2flt/rawfp.rs
new file mode 100644 (file)
index 0000000..1a35333
--- /dev/null
@@ -0,0 +1,154 @@
+// 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::f64;
+use std::mem;
+use core::num::diy_float::Fp;
+use core::num::dec2flt::rawfp::{fp_to_float, prev_float, next_float, round_normal};
+
+fn integer_decode(f: f64) -> (u64, i16, i8) {
+    let bits: u64 = unsafe { mem::transmute(f) };
+    let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
+    let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
+    let mantissa = if exponent == 0 {
+        (bits & 0xfffffffffffff) << 1
+    } else {
+        (bits & 0xfffffffffffff) | 0x10000000000000
+    };
+    // Exponent bias + mantissa shift
+    exponent -= 1023 + 52;
+    (mantissa, exponent, sign)
+}
+
+#[test]
+fn fp_to_float_half_to_even() {
+    fn is_normalized(sig: u64) -> bool {
+        // intentionally written without {min,max}_sig() as a sanity check
+        sig >> 52 == 1 && sig >> 53 == 0
+    }
+
+    fn conv(sig: u64) -> u64 {
+        // The significands are perfectly in range, so the exponent should not matter
+        let (m1, e1, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: 0 }));
+        assert_eq!(e1, 0 + 64 - 53);
+        let (m2, e2, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: 55 }));
+        assert_eq!(e2, 55 + 64 - 53);
+        assert_eq!(m2, m1);
+        let (m3, e3, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: -78 }));
+        assert_eq!(e3, -78 + 64 - 53);
+        assert_eq!(m3, m2);
+        m3
+    }
+
+    let odd = 0x1F_EDCB_A012_345F;
+    let even = odd - 1;
+    assert!(is_normalized(odd));
+    assert!(is_normalized(even));
+    assert_eq!(conv(odd << 11), odd);
+    assert_eq!(conv(even << 11), even);
+    assert_eq!(conv(odd << 11 | 1 << 10), odd + 1);
+    assert_eq!(conv(even << 11 | 1 << 10), even);
+    assert_eq!(conv(even << 11 | 1 << 10 | 1), even + 1);
+    assert_eq!(conv(odd << 11 | 1 << 9), odd);
+    assert_eq!(conv(even << 11 | 1 << 9), even);
+    assert_eq!(conv(odd << 11 | 0x7FF), odd + 1);
+    assert_eq!(conv(even << 11 | 0x7FF), even + 1);
+    assert_eq!(conv(odd << 11 | 0x3FF), odd);
+    assert_eq!(conv(even << 11 | 0x3FF), even);
+}
+
+#[test]
+fn integers_to_f64() {
+    assert_eq!(fp_to_float::<f64>(Fp { f: 1, e: 0 }), 1.0);
+    assert_eq!(fp_to_float::<f64>(Fp { f: 42, e: 7 }), (42 << 7) as f64);
+    assert_eq!(fp_to_float::<f64>(Fp { f: 1 << 20, e: 30 }), (1u64 << 50) as f64);
+    assert_eq!(fp_to_float::<f64>(Fp { f: 4, e: -3 }), 0.5);
+}
+
+const SOME_FLOATS: [f64; 9] =
+    [0.1f64, 33.568, 42.1e-5, 777.0e9, 1.1111, 0.347997,
+     9843579834.35892, 12456.0e-150, 54389573.0e-150];
+
+
+#[test]
+fn human_f64_roundtrip() {
+    for &x in &SOME_FLOATS {
+        let (f, e, _) = integer_decode(x);
+        let fp = Fp { f: f, e: e};
+        assert_eq!(fp_to_float::<f64>(fp), x);
+    }
+}
+
+#[test]
+fn rounding_overflow() {
+    let x = Fp { f: 0xFF_FF_FF_FF_FF_FF_FF_00u64, e: 42 };
+    let rounded = round_normal::<f64>(x);
+    let adjusted_k = x.e + 64 - 53;
+    assert_eq!(rounded.sig, 1 << 52);
+    assert_eq!(rounded.k, adjusted_k + 1);
+}
+
+#[test]
+fn prev_float_monotonic() {
+    let mut x = 1.0;
+    for _ in 0..100 {
+        let x1 = prev_float(x);
+        assert!(x1 < x);
+        assert!(x - x1 < 1e-15);
+        x = x1;
+    }
+}
+
+const MIN_SUBNORMAL: f64 = 5e-324;
+
+#[test]
+fn next_float_zero() {
+    let tiny = next_float(0.0);
+    assert_eq!(tiny, MIN_SUBNORMAL);
+    assert!(tiny != 0.0);
+}
+
+#[test]
+fn next_float_subnormal() {
+    let second = next_float(MIN_SUBNORMAL);
+    // For subnormals, MIN_SUBNORMAL is the ULP
+    assert!(second != MIN_SUBNORMAL);
+    assert!(second > 0.0);
+    assert_eq!(second - MIN_SUBNORMAL, MIN_SUBNORMAL);
+}
+
+#[test]
+fn next_float_inf() {
+    assert_eq!(next_float(f64::MAX), f64::INFINITY);
+    assert_eq!(next_float(f64::INFINITY), f64::INFINITY);
+}
+
+#[test]
+fn next_prev_identity() {
+    for &x in &SOME_FLOATS {
+        assert_eq!(prev_float(next_float(x)), x);
+        assert_eq!(prev_float(prev_float(next_float(next_float(x)))), x);
+        assert_eq!(next_float(prev_float(x)), x);
+        assert_eq!(next_float(next_float(prev_float(prev_float(x)))), x);
+    }
+}
+
+#[test]
+fn next_float_monotonic() {
+    let mut x = 0.49999999999999;
+    assert!(x < 0.5);
+    for _ in 0..200 {
+        let x1 = next_float(x);
+        assert!(x1 > x);
+        assert!(x1 - x < 1e-15, "next_float_monotonic: delta = {:?}", x1 - x);
+        x = x1;
+    }
+    assert!(x > 0.5);
+}
diff --git a/src/libcore/tests/num/flt2dec/estimator.rs b/src/libcore/tests/num/flt2dec/estimator.rs
new file mode 100644 (file)
index 0000000..0bca616
--- /dev/null
@@ -0,0 +1,65 @@
+// 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.
+
+// FIXME https://github.com/kripken/emscripten/issues/4563
+// NB we have to actually not compile this test to avoid
+// an undefined symbol error
+#![cfg(not(target_os = "emscripten"))]
+
+use core::num::flt2dec::estimator::*;
+
+#[test]
+fn test_estimate_scaling_factor() {
+    macro_rules! assert_almost_eq {
+        ($actual:expr, $expected:expr) => ({
+            let actual = $actual;
+            let expected = $expected;
+            println!("{} - {} = {} - {} = {}", stringify!($expected), stringify!($actual),
+                     expected, actual, expected - actual);
+            assert!(expected == actual || expected == actual + 1,
+                    "expected {}, actual {}", expected, actual);
+        })
+    }
+
+    assert_almost_eq!(estimate_scaling_factor(1, 0), 0);
+    assert_almost_eq!(estimate_scaling_factor(2, 0), 1);
+    assert_almost_eq!(estimate_scaling_factor(10, 0), 1);
+    assert_almost_eq!(estimate_scaling_factor(11, 0), 2);
+    assert_almost_eq!(estimate_scaling_factor(100, 0), 2);
+    assert_almost_eq!(estimate_scaling_factor(101, 0), 3);
+    assert_almost_eq!(estimate_scaling_factor(10000000000000000000, 0), 19);
+    assert_almost_eq!(estimate_scaling_factor(10000000000000000001, 0), 20);
+
+    // 1/2^20 = 0.00000095367...
+    assert_almost_eq!(estimate_scaling_factor(1 * 1048576 / 1000000, -20), -6);
+    assert_almost_eq!(estimate_scaling_factor(1 * 1048576 / 1000000 + 1, -20), -5);
+    assert_almost_eq!(estimate_scaling_factor(10 * 1048576 / 1000000, -20), -5);
+    assert_almost_eq!(estimate_scaling_factor(10 * 1048576 / 1000000 + 1, -20), -4);
+    assert_almost_eq!(estimate_scaling_factor(100 * 1048576 / 1000000, -20), -4);
+    assert_almost_eq!(estimate_scaling_factor(100 * 1048576 / 1000000 + 1, -20), -3);
+    assert_almost_eq!(estimate_scaling_factor(1048575, -20), 0);
+    assert_almost_eq!(estimate_scaling_factor(1048576, -20), 0);
+    assert_almost_eq!(estimate_scaling_factor(1048577, -20), 1);
+    assert_almost_eq!(estimate_scaling_factor(10485759999999999999, -20), 13);
+    assert_almost_eq!(estimate_scaling_factor(10485760000000000000, -20), 13);
+    assert_almost_eq!(estimate_scaling_factor(10485760000000000001, -20), 14);
+
+    // extreme values:
+    // 2^-1074 = 4.94065... * 10^-324
+    // (2^53-1) * 2^971 = 1.79763... * 10^308
+    assert_almost_eq!(estimate_scaling_factor(1, -1074), -323);
+    assert_almost_eq!(estimate_scaling_factor(0x1fffffffffffff, 971), 309);
+
+    for i in -1074..972 {
+        let expected = super::ldexp_f64(1.0, i).log10().ceil();
+        assert_almost_eq!(estimate_scaling_factor(1, i as i16), expected as i16);
+    }
+}
+
diff --git a/src/libcore/tests/num/flt2dec/mod.rs b/src/libcore/tests/num/flt2dec/mod.rs
new file mode 100644 (file)
index 0000000..0f4d19e
--- /dev/null
@@ -0,0 +1,1201 @@
+// 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::prelude::v1::*;
+use std::{str, mem, i16, f32, f64, fmt};
+use std::__rand as rand;
+use rand::{Rand, XorShiftRng};
+use rand::distributions::{IndependentSample, Range};
+
+use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded};
+use core::num::flt2dec::{MAX_SIG_DIGITS, round_up, Part, Formatted, Sign};
+use core::num::flt2dec::{to_shortest_str, to_shortest_exp_str,
+                         to_exact_exp_str, to_exact_fixed_str};
+
+pub use test::Bencher;
+
+mod estimator;
+mod strategy {
+    mod dragon;
+    mod grisu;
+}
+
+pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
+    match decode(v).1 {
+        FullDecoded::Finite(decoded) => decoded,
+        full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
+    }
+}
+
+macro_rules! check_shortest {
+    ($f:ident($v:expr) => $buf:expr, $exp:expr) => (
+        check_shortest!($f($v) => $buf, $exp;
+                        "shortest mismatch for v={v}: actual {actual:?}, expected {expected:?}",
+                        v = stringify!($v))
+    );
+
+    ($f:ident{$($k:ident: $v:expr),+} => $buf:expr, $exp:expr) => (
+        check_shortest!($f{$($k: $v),+} => $buf, $exp;
+                        "shortest mismatch for {v:?}: actual {actual:?}, expected {expected:?}",
+                        v = Decoded { $($k: $v),+ })
+    );
+
+    ($f:ident($v:expr) => $buf:expr, $exp:expr; $fmt:expr, $($key:ident = $val:expr),*) => ({
+        let mut buf = [b'_'; MAX_SIG_DIGITS];
+        let (len, k) = $f(&decode_finite($v), &mut buf);
+        assert!((&buf[..len], k) == ($buf, $exp),
+                $fmt, actual = (str::from_utf8(&buf[..len]).unwrap(), k),
+                      expected = (str::from_utf8($buf).unwrap(), $exp),
+                      $($key = $val),*);
+    });
+
+    ($f:ident{$($k:ident: $v:expr),+} => $buf:expr, $exp:expr;
+                                         $fmt:expr, $($key:ident = $val:expr),*) => ({
+        let mut buf = [b'_'; MAX_SIG_DIGITS];
+        let (len, k) = $f(&Decoded { $($k: $v),+ }, &mut buf);
+        assert!((&buf[..len], k) == ($buf, $exp),
+                $fmt, actual = (str::from_utf8(&buf[..len]).unwrap(), k),
+                      expected = (str::from_utf8($buf).unwrap(), $exp),
+                      $($key = $val),*);
+    })
+}
+
+macro_rules! try_exact {
+    ($f:ident($decoded:expr) => $buf:expr, $expected:expr, $expectedk:expr;
+                                $fmt:expr, $($key:ident = $val:expr),*) => ({
+        let (len, k) = $f($decoded, &mut $buf[..$expected.len()], i16::MIN);
+        assert!((&$buf[..len], k) == ($expected, $expectedk),
+                $fmt, actual = (str::from_utf8(&$buf[..len]).unwrap(), k),
+                      expected = (str::from_utf8($expected).unwrap(), $expectedk),
+                      $($key = $val),*);
+    })
+}
+
+macro_rules! try_fixed {
+    ($f:ident($decoded:expr) => $buf:expr, $request:expr, $expected:expr, $expectedk:expr;
+                                $fmt:expr, $($key:ident = $val:expr),*) => ({
+        let (len, k) = $f($decoded, &mut $buf[..], $request);
+        assert!((&$buf[..len], k) == ($expected, $expectedk),
+                $fmt, actual = (str::from_utf8(&$buf[..len]).unwrap(), k),
+                      expected = (str::from_utf8($expected).unwrap(), $expectedk),
+                      $($key = $val),*);
+    })
+}
+
+fn ldexp_f32(a: f32, b: i32) -> f32 {
+    ldexp_f64(a as f64, b) as f32
+}
+
+fn ldexp_f64(a: f64, b: i32) -> f64 {
+    extern {
+        fn ldexp(x: f64, n: i32) -> f64;
+    }
+    unsafe { ldexp(a, b) }
+}
+
+fn check_exact<F, T>(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16)
+        where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
+    // use a large enough buffer
+    let mut buf = [b'_'; 1024];
+    let mut expected_ = [b'_'; 1024];
+
+    let decoded = decode_finite(v);
+    let cut = expected.iter().position(|&c| c == b' ');
+
+    // check significant digits
+    for i in 1..cut.unwrap_or(expected.len() - 1) {
+        expected_[..i].copy_from_slice(&expected[..i]);
+        let mut expectedk_ = expectedk;
+        if expected[i] >= b'5' {
+            // check if this is a rounding-to-even case.
+            // we avoid rounding ...x5000... (with infinite zeroes) to ...(x+1) when x is even.
+            if !(i+1 < expected.len() && expected[i-1] & 1 == 0 &&
+                                         expected[i] == b'5' &&
+                                         expected[i+1] == b' ') {
+                // if this returns true, expected_[..i] is all `9`s and being rounded up.
+                // we should always return `100..00` (`i` digits) instead, since that's
+                // what we can came up with `i` digits anyway. `round_up` assumes that
+                // the adjustment to the length is done by caller, which we simply ignore.
+                if let Some(_) = round_up(&mut expected_, i) { expectedk_ += 1; }
+            }
+        }
+
+        try_exact!(f(&decoded) => &mut buf, &expected_[..i], expectedk_;
+                   "exact sigdigit mismatch for v={v}, i={i}: \
+                    actual {actual:?}, expected {expected:?}",
+                   v = vstr, i = i);
+        try_fixed!(f(&decoded) => &mut buf, expectedk_ - i as i16, &expected_[..i], expectedk_;
+                   "fixed sigdigit mismatch for v={v}, i={i}: \
+                    actual {actual:?}, expected {expected:?}",
+                   v = vstr, i = i);
+    }
+
+    // check exact rounding for zero- and negative-width cases
+    let start;
+    if expected[0] >= b'5' {
+        try_fixed!(f(&decoded) => &mut buf, expectedk, b"1", expectedk + 1;
+                   "zero-width rounding-up mismatch for v={v}: \
+                    actual {actual:?}, expected {expected:?}",
+                   v = vstr);
+        start = 1;
+    } else {
+        start = 0;
+    }
+    for i in start..-10 {
+        try_fixed!(f(&decoded) => &mut buf, expectedk - i, b"", expectedk;
+                   "rounding-down mismatch for v={v}, i={i}: \
+                    actual {actual:?}, expected {expected:?}",
+                   v = vstr, i = -i);
+    }
+
+    // check infinite zero digits
+    if let Some(cut) = cut {
+        for i in cut..expected.len()-1 {
+            expected_[..cut].copy_from_slice(&expected[..cut]);
+            for c in &mut expected_[cut..i] { *c = b'0'; }
+
+            try_exact!(f(&decoded) => &mut buf, &expected_[..i], expectedk;
+                       "exact infzero mismatch for v={v}, i={i}: \
+                        actual {actual:?}, expected {expected:?}",
+                       v = vstr, i = i);
+            try_fixed!(f(&decoded) => &mut buf, expectedk - i as i16, &expected_[..i], expectedk;
+                       "fixed infzero mismatch for v={v}, i={i}: \
+                        actual {actual:?}, expected {expected:?}",
+                       v = vstr, i = i);
+        }
+    }
+}
+
+trait TestableFloat : DecodableFloat + fmt::Display {
+    /// Returns `x * 2^exp`. Almost same to `std::{f32,f64}::ldexp`.
+    /// This is used for testing.
+    fn ldexpi(f: i64, exp: isize) -> Self;
+}
+
+impl TestableFloat for f32 {
+    fn ldexpi(f: i64, exp: isize) -> Self { f as Self * (exp as Self).exp2() }
+}
+
+impl TestableFloat for f64 {
+    fn ldexpi(f: i64, exp: isize) -> Self { f as Self * (exp as Self).exp2() }
+}
+
+fn check_exact_one<F, T>(mut f: F, x: i64, e: isize, tstr: &str, expected: &[u8], expectedk: i16)
+        where T: TestableFloat,
+              F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
+    // use a large enough buffer
+    let mut buf = [b'_'; 1024];
+    let v: T = TestableFloat::ldexpi(x, e);
+    let decoded = decode_finite(v);
+
+    try_exact!(f(&decoded) => &mut buf, &expected, expectedk;
+               "exact mismatch for v={x}p{e}{t}: actual {actual:?}, expected {expected:?}",
+               x = x, e = e, t = tstr);
+    try_fixed!(f(&decoded) => &mut buf, expectedk - expected.len() as i16, &expected, expectedk;
+               "fixed mismatch for v={x}p{e}{t}: actual {actual:?}, expected {expected:?}",
+               x = x, e = e, t = tstr);
+}
+
+macro_rules! check_exact {
+    ($f:ident($v:expr) => $buf:expr, $exp:expr) => (
+        check_exact(|d,b,k| $f(d,b,k), $v, stringify!($v), $buf, $exp)
+    )
+}
+
+macro_rules! check_exact_one {
+    ($f:ident($x:expr, $e:expr; $t:ty) => $buf:expr, $exp:expr) => (
+        check_exact_one::<_, $t>(|d,b,k| $f(d,b,k), $x, $e, stringify!($t), $buf, $exp)
+    )
+}
+
+// in the following comments, three numbers are spaced by 1 ulp apart,
+// and the second one is being formatted.
+//
+// some tests are derived from [1].
+//
+// [1] Vern Paxson, A Program for Testing IEEE Decimal-Binary Conversion
+//     ftp://ftp.ee.lbl.gov/testbase-report.ps.Z
+
+pub fn f32_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
+    // 0.0999999940395355224609375
+    // 0.100000001490116119384765625
+    // 0.10000000894069671630859375
+    check_shortest!(f(0.1f32) => b"1", 0);
+
+    // 0.333333313465118408203125
+    // 0.3333333432674407958984375 (1/3 in the default rounding)
+    // 0.33333337306976318359375
+    check_shortest!(f(1.0f32/3.0) => b"33333334", 0);
+
+    // 10^1 * 0.31415917873382568359375
+    // 10^1 * 0.31415920257568359375
+    // 10^1 * 0.31415922641754150390625
+    check_shortest!(f(3.141592f32) => b"3141592", 1);
+
+    // 10^18 * 0.31415916243714048
+    // 10^18 * 0.314159196796878848
+    // 10^18 * 0.314159231156617216
+    check_shortest!(f(3.141592e17f32) => b"3141592", 18);
+
+    // regression test for decoders
+    // 10^8 * 0.3355443
+    // 10^8 * 0.33554432
+    // 10^8 * 0.33554436
+    check_shortest!(f(ldexp_f32(1.0, 25)) => b"33554432", 8);
+
+    // 10^39 * 0.340282326356119256160033759537265639424
+    // 10^39 * 0.34028234663852885981170418348451692544
+    // 10^39 * 0.340282366920938463463374607431768211456
+    check_shortest!(f(f32::MAX) => b"34028235", 39);
+
+    // 10^-37 * 0.1175494210692441075487029444849287348827...
+    // 10^-37 * 0.1175494350822287507968736537222245677818...
+    // 10^-37 * 0.1175494490952133940450443629595204006810...
+    check_shortest!(f(f32::MIN_POSITIVE) => b"11754944", -37);
+
+    // 10^-44 * 0
+    // 10^-44 * 0.1401298464324817070923729583289916131280...
+    // 10^-44 * 0.2802596928649634141847459166579832262560...
+    let minf32 = ldexp_f32(1.0, -149);
+    check_shortest!(f(minf32) => b"1", -44);
+}
+
+pub fn f32_exact_sanity_test<F>(mut f: F)
+        where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
+    let minf32 = ldexp_f32(1.0, -149);
+
+    check_exact!(f(0.1f32)            => b"100000001490116119384765625             ", 0);
+    check_exact!(f(0.5f32)            => b"5                                       ", 0);
+    check_exact!(f(1.0f32/3.0)        => b"3333333432674407958984375               ", 0);
+    check_exact!(f(3.141592f32)       => b"31415920257568359375                    ", 1);
+    check_exact!(f(3.141592e17f32)    => b"314159196796878848                      ", 18);
+    check_exact!(f(f32::MAX)          => b"34028234663852885981170418348451692544  ", 39);
+    check_exact!(f(f32::MIN_POSITIVE) => b"1175494350822287507968736537222245677818", -37);
+    check_exact!(f(minf32)            => b"1401298464324817070923729583289916131280", -44);
+
+    // [1], Table 16: Stress Inputs for Converting 24-bit Binary to Decimal, < 1/2 ULP
+    check_exact_one!(f(12676506, -102; f32) => b"2",            -23);
+    check_exact_one!(f(12676506, -103; f32) => b"12",           -23);
+    check_exact_one!(f(15445013,   86; f32) => b"119",           34);
+    check_exact_one!(f(13734123, -138; f32) => b"3941",         -34);
+    check_exact_one!(f(12428269, -130; f32) => b"91308",        -32);
+    check_exact_one!(f(15334037, -146; f32) => b"171900",       -36);
+    check_exact_one!(f(11518287,  -41; f32) => b"5237910",       -5);
+    check_exact_one!(f(12584953, -145; f32) => b"28216440",     -36);
+    check_exact_one!(f(15961084, -125; f32) => b"375243281",    -30);
+    check_exact_one!(f(14915817, -146; f32) => b"1672120916",   -36);
+    check_exact_one!(f(10845484, -102; f32) => b"21388945814",  -23);
+    check_exact_one!(f(16431059,  -61; f32) => b"712583594561", -11);
+
+    // [1], Table 17: Stress Inputs for Converting 24-bit Binary to Decimal, > 1/2 ULP
+    check_exact_one!(f(16093626,   69; f32) => b"1",             29);
+    check_exact_one!(f( 9983778,   25; f32) => b"34",            15);
+    check_exact_one!(f(12745034,  104; f32) => b"259",           39);
+    check_exact_one!(f(12706553,   72; f32) => b"6001",          29);
+    check_exact_one!(f(11005028,   45; f32) => b"38721",         21);
+    check_exact_one!(f(15059547,   71; f32) => b"355584",        29);
+    check_exact_one!(f(16015691,  -99; f32) => b"2526831",      -22);
+    check_exact_one!(f( 8667859,   56; f32) => b"62458507",      24);
+    check_exact_one!(f(14855922,  -82; f32) => b"307213267",    -17);
+    check_exact_one!(f(14855922,  -83; f32) => b"1536066333",   -17);
+    check_exact_one!(f(10144164, -110; f32) => b"78147796834",  -26);
+    check_exact_one!(f(13248074,   95; f32) => b"524810279937",  36);
+}
+
+pub fn f64_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
+    // 0.0999999999999999777955395074968691915273...
+    // 0.1000000000000000055511151231257827021181...
+    // 0.1000000000000000333066907387546962127089...
+    check_shortest!(f(0.1f64) => b"1", 0);
+
+    // this example is explicitly mentioned in the paper.
+    // 10^3 * 0.0999999999999999857891452847979962825775...
+    // 10^3 * 0.1 (exact)
+    // 10^3 * 0.1000000000000000142108547152020037174224...
+    check_shortest!(f(100.0f64) => b"1", 3);
+
+    // 0.3333333333333332593184650249895639717578...
+    // 0.3333333333333333148296162562473909929394... (1/3 in the default rounding)
+    // 0.3333333333333333703407674875052180141210...
+    check_shortest!(f(1.0f64/3.0) => b"3333333333333333", 0);
+
+    // explicit test case for equally closest representations.
+    // Dragon has its own tie-breaking rule; Grisu should fall back.
+    // 10^1 * 0.1000007629394531027955395074968691915273...
+    // 10^1 * 0.100000762939453125 (exact)
+    // 10^1 * 0.1000007629394531472044604925031308084726...
+    check_shortest!(f(1.00000762939453125f64) => b"10000076293945313", 1);
+
+    // 10^1 * 0.3141591999999999718085064159822650253772...
+    // 10^1 * 0.3141592000000000162174274009885266423225...
+    // 10^1 * 0.3141592000000000606263483859947882592678...
+    check_shortest!(f(3.141592f64) => b"3141592", 1);
+
+    // 10^18 * 0.314159199999999936
+    // 10^18 * 0.3141592 (exact)
+    // 10^18 * 0.314159200000000064
+    check_shortest!(f(3.141592e17f64) => b"3141592", 18);
+
+    // regression test for decoders
+    // 10^20 * 0.18446744073709549568
+    // 10^20 * 0.18446744073709551616
+    // 10^20 * 0.18446744073709555712
+    check_shortest!(f(ldexp_f64(1.0, 64)) => b"18446744073709552", 20);
+
+    // pathological case: high = 10^23 (exact). tie breaking should always prefer that.
+    // 10^24 * 0.099999999999999974834176
+    // 10^24 * 0.099999999999999991611392
+    // 10^24 * 0.100000000000000008388608
+    check_shortest!(f(1.0e23f64) => b"1", 24);
+
+    // 10^309 * 0.1797693134862315508561243283845062402343...
+    // 10^309 * 0.1797693134862315708145274237317043567980...
+    // 10^309 * 0.1797693134862315907729305190789024733617...
+    check_shortest!(f(f64::MAX) => b"17976931348623157", 309);
+
+    // 10^-307 * 0.2225073858507200889024586876085859887650...
+    // 10^-307 * 0.2225073858507201383090232717332404064219...
+    // 10^-307 * 0.2225073858507201877155878558578948240788...
+    check_shortest!(f(f64::MIN_POSITIVE) => b"22250738585072014", -307);
+
+    // 10^-323 * 0
+    // 10^-323 * 0.4940656458412465441765687928682213723650...
+    // 10^-323 * 0.9881312916824930883531375857364427447301...
+    let minf64 = ldexp_f64(1.0, -1074);
+    check_shortest!(f(minf64) => b"5", -323);
+}
+
+pub fn f64_exact_sanity_test<F>(mut f: F)
+        where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
+    let minf64 = ldexp_f64(1.0, -1074);
+
+    check_exact!(f(0.1f64)            => b"1000000000000000055511151231257827021181", 0);
+    check_exact!(f(0.45f64)           => b"4500000000000000111022302462515654042363", 0);
+    check_exact!(f(0.5f64)            => b"5                                       ", 0);
+    check_exact!(f(0.95f64)           => b"9499999999999999555910790149937383830547", 0);
+    check_exact!(f(100.0f64)          => b"1                                       ", 3);
+    check_exact!(f(999.5f64)          => b"9995000000000000000000000000000000000000", 3);
+    check_exact!(f(1.0f64/3.0)        => b"3333333333333333148296162562473909929394", 0);
+    check_exact!(f(3.141592f64)       => b"3141592000000000162174274009885266423225", 1);
+    check_exact!(f(3.141592e17f64)    => b"3141592                                 ", 18);
+    check_exact!(f(1.0e23f64)         => b"99999999999999991611392                 ", 23);
+    check_exact!(f(f64::MAX)          => b"1797693134862315708145274237317043567980", 309);
+    check_exact!(f(f64::MIN_POSITIVE) => b"2225073858507201383090232717332404064219", -307);
+    check_exact!(f(minf64)            => b"4940656458412465441765687928682213723650\
+                                           5980261432476442558568250067550727020875\
+                                           1865299836361635992379796564695445717730\
+                                           9266567103559397963987747960107818781263\
+                                           0071319031140452784581716784898210368871\
+                                           8636056998730723050006387409153564984387\
+                                           3124733972731696151400317153853980741262\
+                                           3856559117102665855668676818703956031062\
+                                           4931945271591492455329305456544401127480\
+                                           1297099995419319894090804165633245247571\
+                                           4786901472678015935523861155013480352649\
+                                           3472019379026810710749170333222684475333\
+                                           5720832431936092382893458368060106011506\
+                                           1698097530783422773183292479049825247307\
+                                           7637592724787465608477820373446969953364\
+                                           7017972677717585125660551199131504891101\
+                                           4510378627381672509558373897335989936648\
+                                           0994116420570263709027924276754456522908\
+                                           7538682506419718265533447265625         ", -323);
+
+    // [1], Table 3: Stress Inputs for Converting 53-bit Binary to Decimal, < 1/2 ULP
+    check_exact_one!(f(8511030020275656,  -342; f64) => b"9",                       -87);
+    check_exact_one!(f(5201988407066741,  -824; f64) => b"46",                     -232);
+    check_exact_one!(f(6406892948269899,   237; f64) => b"141",                      88);
+    check_exact_one!(f(8431154198732492,    72; f64) => b"3981",                     38);
+    check_exact_one!(f(6475049196144587,    99; f64) => b"41040",                    46);
+    check_exact_one!(f(8274307542972842,   726; f64) => b"292084",                  235);
+    check_exact_one!(f(5381065484265332,  -456; f64) => b"2891946",                -121);
+    check_exact_one!(f(6761728585499734, -1057; f64) => b"43787718",               -302);
+    check_exact_one!(f(7976538478610756,   376; f64) => b"122770163",               130);
+    check_exact_one!(f(5982403858958067,   377; f64) => b"1841552452",              130);
+    check_exact_one!(f(5536995190630837,    93; f64) => b"54835744350",              44);
+    check_exact_one!(f(7225450889282194,   710; f64) => b"389190181146",            230);
+    check_exact_one!(f(7225450889282194,   709; f64) => b"1945950905732",           230);
+    check_exact_one!(f(8703372741147379,   117; f64) => b"14460958381605",           52);
+    check_exact_one!(f(8944262675275217, -1001; f64) => b"417367747458531",        -285);
+    check_exact_one!(f(7459803696087692,  -707; f64) => b"1107950772878888",       -196);
+    check_exact_one!(f(6080469016670379,  -381; f64) => b"12345501366327440",       -98);
+    check_exact_one!(f(8385515147034757,   721; f64) => b"925031711960365024",      233);
+    check_exact_one!(f(7514216811389786,  -828; f64) => b"4198047150284889840",    -233);
+    check_exact_one!(f(8397297803260511,  -345; f64) => b"11716315319786511046",    -87);
+    check_exact_one!(f(6733459239310543,   202; f64) => b"432810072844612493629",    77);
+    check_exact_one!(f(8091450587292794,  -473; f64) => b"3317710118160031081518", -126);
+
+    // [1], Table 4: Stress Inputs for Converting 53-bit Binary to Decimal, > 1/2 ULP
+    check_exact_one!(f(6567258882077402,   952; f64) => b"3",                       303);
+    check_exact_one!(f(6712731423444934,   535; f64) => b"76",                      177);
+    check_exact_one!(f(6712731423444934,   534; f64) => b"378",                     177);
+    check_exact_one!(f(5298405411573037,  -957; f64) => b"4350",                   -272);
+    check_exact_one!(f(5137311167659507,  -144; f64) => b"23037",                   -27);
+    check_exact_one!(f(6722280709661868,   363; f64) => b"126301",                  126);
+    check_exact_one!(f(5344436398034927,  -169; f64) => b"7142211",                 -35);
+    check_exact_one!(f(8369123604277281,  -853; f64) => b"13934574",               -240);
+    check_exact_one!(f(8995822108487663,  -780; f64) => b"141463449",              -218);
+    check_exact_one!(f(8942832835564782,  -383; f64) => b"4539277920",              -99);
+    check_exact_one!(f(8942832835564782,  -384; f64) => b"22696389598",             -99);
+    check_exact_one!(f(8942832835564782,  -385; f64) => b"113481947988",            -99);
+    check_exact_one!(f(6965949469487146,  -249; f64) => b"7700366561890",           -59);
+    check_exact_one!(f(6965949469487146,  -250; f64) => b"38501832809448",          -59);
+    check_exact_one!(f(6965949469487146,  -251; f64) => b"192509164047238",         -59);
+    check_exact_one!(f(7487252720986826,   548; f64) => b"6898586531774201",        181);
+    check_exact_one!(f(5592117679628511,   164; f64) => b"13076622631878654",        66);
+    check_exact_one!(f(8887055249355788,   665; f64) => b"136052020756121240",      217);
+    check_exact_one!(f(6994187472632449,   690; f64) => b"3592810217475959676",     224);
+    check_exact_one!(f(8797576579012143,   588; f64) => b"89125197712484551899",    193);
+    check_exact_one!(f(7363326733505337,   272; f64) => b"558769757362301140950",    98);
+    check_exact_one!(f(8549497411294502,  -448; f64) => b"1176257830728540379990", -118);
+}
+
+pub fn more_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
+    check_shortest!(f{mant: 99_999_999_999_999_999, minus: 1, plus: 1,
+                      exp: 0, inclusive: true} => b"1", 18);
+    check_shortest!(f{mant: 99_999_999_999_999_999, minus: 1, plus: 1,
+                      exp: 0, inclusive: false} => b"99999999999999999", 17);
+}
+
+fn iterate<F, G, V>(func: &str, k: usize, n: usize, mut f: F, mut g: G, mut v: V) -> (usize, usize)
+        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
+              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
+              V: FnMut(usize) -> Decoded {
+    assert!(k <= 1024);
+
+    let mut npassed = 0; // f(x) = Some(g(x))
+    let mut nignored = 0; // f(x) = None
+
+    for i in 0..n {
+        if (i & 0xfffff) == 0 {
+            println!("in progress, {:x}/{:x} (ignored={} passed={} failed={})",
+                     i, n, nignored, npassed, i - nignored - npassed);
+        }
+
+        let decoded = v(i);
+        let mut buf1 = [0; 1024];
+        if let Some((len1, e1)) = f(&decoded, &mut buf1[..k]) {
+            let mut buf2 = [0; 1024];
+            let (len2, e2) = g(&decoded, &mut buf2[..k]);
+            if e1 == e2 && &buf1[..len1] == &buf2[..len2] {
+                npassed += 1;
+            } else {
+                println!("equivalence test failed, {:x}/{:x}: {:?} f(i)={}e{} g(i)={}e{}",
+                         i, n, decoded, str::from_utf8(&buf1[..len1]).unwrap(), e1,
+                                        str::from_utf8(&buf2[..len2]).unwrap(), e2);
+            }
+        } else {
+            nignored += 1;
+        }
+    }
+    println!("{}({}): done, ignored={} passed={} failed={}",
+             func, k, nignored, npassed, n - nignored - npassed);
+    assert!(nignored + npassed == n,
+            "{}({}): {} out of {} values returns an incorrect value!",
+            func, k, n - nignored - npassed, n);
+    (npassed, nignored)
+}
+
+pub fn f32_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
+        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
+              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
+    let mut rng: XorShiftRng = Rand::rand(&mut rand::thread_rng());
+    let f32_range = Range::new(0x0000_0001u32, 0x7f80_0000);
+    iterate("f32_random_equivalence_test", k, n, f, g, |_| {
+        let i: u32 = f32_range.ind_sample(&mut rng);
+        let x: f32 = unsafe {mem::transmute(i)};
+        decode_finite(x)
+    });
+}
+
+pub fn f64_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
+        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
+              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
+    let mut rng: XorShiftRng = Rand::rand(&mut rand::thread_rng());
+    let f64_range = Range::new(0x0000_0000_0000_0001u64, 0x7ff0_0000_0000_0000);
+    iterate("f64_random_equivalence_test", k, n, f, g, |_| {
+        let i: u64 = f64_range.ind_sample(&mut rng);
+        let x: f64 = unsafe {mem::transmute(i)};
+        decode_finite(x)
+    });
+}
+
+pub fn f32_exhaustive_equivalence_test<F, G>(f: F, g: G, k: usize)
+        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
+              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
+    // we have only 2^23 * (2^8 - 1) - 1 = 2,139,095,039 positive finite f32 values,
+    // so why not simply testing all of them?
+    //
+    // this is of course very stressful (and thus should be behind an `#[ignore]` attribute),
+    // but with `-C opt-level=3 -C lto` this only takes about an hour or so.
+
+    // iterate from 0x0000_0001 to 0x7f7f_ffff, i.e. all finite ranges
+    let (npassed, nignored) = iterate("f32_exhaustive_equivalence_test",
+                                      k, 0x7f7f_ffff, f, g, |i: usize| {
+        let x: f32 = unsafe {mem::transmute(i as u32 + 1)};
+        decode_finite(x)
+    });
+    assert_eq!((npassed, nignored), (2121451881, 17643158));
+}
+
+fn to_string_with_parts<F>(mut f: F) -> String
+        where F: for<'a> FnMut(&'a mut [u8], &'a mut [Part<'a>]) -> Formatted<'a> {
+    let mut buf = [0; 1024];
+    let mut parts = [Part::Zero(0); 16];
+    let formatted = f(&mut buf, &mut parts);
+    let mut ret = vec![0; formatted.len()];
+    assert_eq!(formatted.write(&mut ret), Some(ret.len()));
+    String::from_utf8(ret).unwrap()
+}
+
+pub fn to_shortest_str_test<F>(mut f_: F)
+        where F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
+    use core::num::flt2dec::Sign::*;
+
+    fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize, upper: bool) -> String
+            where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
+        to_string_with_parts(|buf, parts| to_shortest_str(|d,b| f(d,b), v, sign,
+                                                          frac_digits, upper, buf, parts))
+    }
+
+    let f = &mut f_;
+
+    assert_eq!(to_string(f,  0.0, Minus,        0, false), "0");
+    assert_eq!(to_string(f,  0.0, MinusRaw,     0, false), "0");
+    assert_eq!(to_string(f,  0.0, MinusPlus,    0, false), "+0");
+    assert_eq!(to_string(f,  0.0, MinusPlusRaw, 0, false), "+0");
+    assert_eq!(to_string(f, -0.0, Minus,        0, false), "0");
+    assert_eq!(to_string(f, -0.0, MinusRaw,     0, false), "-0");
+    assert_eq!(to_string(f, -0.0, MinusPlus,    0, false), "+0");
+    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 0, false), "-0");
+    assert_eq!(to_string(f,  0.0, Minus,        1,  true), "0.0");
+    assert_eq!(to_string(f,  0.0, MinusRaw,     1,  true), "0.0");
+    assert_eq!(to_string(f,  0.0, MinusPlus,    1,  true), "+0.0");
+    assert_eq!(to_string(f,  0.0, MinusPlusRaw, 1,  true), "+0.0");
+    assert_eq!(to_string(f, -0.0, Minus,        8,  true), "0.00000000");
+    assert_eq!(to_string(f, -0.0, MinusRaw,     8,  true), "-0.00000000");
+    assert_eq!(to_string(f, -0.0, MinusPlus,    8,  true), "+0.00000000");
+    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8,  true), "-0.00000000");
+
+    assert_eq!(to_string(f,  1.0/0.0, Minus,         0, false), "inf");
+    assert_eq!(to_string(f,  1.0/0.0, MinusRaw,      0,  true), "inf");
+    assert_eq!(to_string(f,  1.0/0.0, MinusPlus,     0, false), "+inf");
+    assert_eq!(to_string(f,  1.0/0.0, MinusPlusRaw,  0,  true), "+inf");
+    assert_eq!(to_string(f,  0.0/0.0, Minus,         0, false), "NaN");
+    assert_eq!(to_string(f,  0.0/0.0, MinusRaw,      1,  true), "NaN");
+    assert_eq!(to_string(f,  0.0/0.0, MinusPlus,     8, false), "NaN");
+    assert_eq!(to_string(f,  0.0/0.0, MinusPlusRaw, 64,  true), "NaN");
+    assert_eq!(to_string(f, -1.0/0.0, Minus,         0, false), "-inf");
+    assert_eq!(to_string(f, -1.0/0.0, MinusRaw,      1,  true), "-inf");
+    assert_eq!(to_string(f, -1.0/0.0, MinusPlus,     8, false), "-inf");
+    assert_eq!(to_string(f, -1.0/0.0, MinusPlusRaw, 64,  true), "-inf");
+
+    assert_eq!(to_string(f,  3.14, Minus,        0, false), "3.14");
+    assert_eq!(to_string(f,  3.14, MinusRaw,     0, false), "3.14");
+    assert_eq!(to_string(f,  3.14, MinusPlus,    0, false), "+3.14");
+    assert_eq!(to_string(f,  3.14, MinusPlusRaw, 0, false), "+3.14");
+    assert_eq!(to_string(f, -3.14, Minus,        0, false), "-3.14");
+    assert_eq!(to_string(f, -3.14, MinusRaw,     0, false), "-3.14");
+    assert_eq!(to_string(f, -3.14, MinusPlus,    0, false), "-3.14");
+    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 0, false), "-3.14");
+    assert_eq!(to_string(f,  3.14, Minus,        1,  true), "3.14");
+    assert_eq!(to_string(f,  3.14, MinusRaw,     2,  true), "3.14");
+    assert_eq!(to_string(f,  3.14, MinusPlus,    3,  true), "+3.140");
+    assert_eq!(to_string(f,  3.14, MinusPlusRaw, 4,  true), "+3.1400");
+    assert_eq!(to_string(f, -3.14, Minus,        8,  true), "-3.14000000");
+    assert_eq!(to_string(f, -3.14, MinusRaw,     8,  true), "-3.14000000");
+    assert_eq!(to_string(f, -3.14, MinusPlus,    8,  true), "-3.14000000");
+    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 8,  true), "-3.14000000");
+
+    assert_eq!(to_string(f, 7.5e-11, Minus,  0, false), "0.000000000075");
+    assert_eq!(to_string(f, 7.5e-11, Minus,  3, false), "0.000000000075");
+    assert_eq!(to_string(f, 7.5e-11, Minus, 12, false), "0.000000000075");
+    assert_eq!(to_string(f, 7.5e-11, Minus, 13, false), "0.0000000000750");
+
+    assert_eq!(to_string(f, 1.9971e20, Minus, 0, false), "199710000000000000000");
+    assert_eq!(to_string(f, 1.9971e20, Minus, 1, false), "199710000000000000000.0");
+    assert_eq!(to_string(f, 1.9971e20, Minus, 8, false), "199710000000000000000.00000000");
+
+    assert_eq!(to_string(f, f32::MAX, Minus, 0, false), format!("34028235{:0>31}", ""));
+    assert_eq!(to_string(f, f32::MAX, Minus, 1, false), format!("34028235{:0>31}.0", ""));
+    assert_eq!(to_string(f, f32::MAX, Minus, 8, false), format!("34028235{:0>31}.00000000", ""));
+
+    let minf32 = ldexp_f32(1.0, -149);
+    assert_eq!(to_string(f, minf32, Minus,  0, false), format!("0.{:0>44}1", ""));
+    assert_eq!(to_string(f, minf32, Minus, 45, false), format!("0.{:0>44}1", ""));
+    assert_eq!(to_string(f, minf32, Minus, 46, false), format!("0.{:0>44}10", ""));
+
+    assert_eq!(to_string(f, f64::MAX, Minus, 0, false),
+               format!("17976931348623157{:0>292}", ""));
+    assert_eq!(to_string(f, f64::MAX, Minus, 1, false),
+               format!("17976931348623157{:0>292}.0", ""));
+    assert_eq!(to_string(f, f64::MAX, Minus, 8, false),
+               format!("17976931348623157{:0>292}.00000000", ""));
+
+    let minf64 = ldexp_f64(1.0, -1074);
+    assert_eq!(to_string(f, minf64, Minus,   0, false), format!("0.{:0>323}5", ""));
+    assert_eq!(to_string(f, minf64, Minus, 324, false), format!("0.{:0>323}5", ""));
+    assert_eq!(to_string(f, minf64, Minus, 325, false), format!("0.{:0>323}50", ""));
+
+    // very large output
+    assert_eq!(to_string(f, 1.1, Minus, 80000, false), format!("1.1{:0>79999}", ""));
+}
+
+pub fn to_shortest_exp_str_test<F>(mut f_: F)
+        where F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
+    use core::num::flt2dec::Sign::*;
+
+    fn to_string<T, F>(f: &mut F, v: T, sign: Sign, exp_bounds: (i16, i16), upper: bool) -> String
+            where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
+        to_string_with_parts(|buf, parts| to_shortest_exp_str(|d,b| f(d,b), v, sign,
+                                                              exp_bounds, upper, buf, parts))
+    }
+
+    let f = &mut f_;
+
+    assert_eq!(to_string(f,  0.0, Minus,        (-4, 16), false), "0");
+    assert_eq!(to_string(f,  0.0, MinusRaw,     (-4, 16), false), "0");
+    assert_eq!(to_string(f,  0.0, MinusPlus,    (-4, 16), false), "+0");
+    assert_eq!(to_string(f,  0.0, MinusPlusRaw, (-4, 16), false), "+0");
+    assert_eq!(to_string(f, -0.0, Minus,        (-4, 16), false), "0");
+    assert_eq!(to_string(f, -0.0, MinusRaw,     (-4, 16), false), "-0");
+    assert_eq!(to_string(f, -0.0, MinusPlus,    (-4, 16), false), "+0");
+    assert_eq!(to_string(f, -0.0, MinusPlusRaw, (-4, 16), false), "-0");
+    assert_eq!(to_string(f,  0.0, Minus,        ( 0,  0),  true), "0E0");
+    assert_eq!(to_string(f,  0.0, MinusRaw,     ( 0,  0), false), "0e0");
+    assert_eq!(to_string(f,  0.0, MinusPlus,    (-9, -5),  true), "+0E0");
+    assert_eq!(to_string(f,  0.0, MinusPlusRaw, ( 5,  9), false), "+0e0");
+    assert_eq!(to_string(f, -0.0, Minus,        ( 0,  0),  true), "0E0");
+    assert_eq!(to_string(f, -0.0, MinusRaw,     ( 0,  0), false), "-0e0");
+    assert_eq!(to_string(f, -0.0, MinusPlus,    (-9, -5),  true), "+0E0");
+    assert_eq!(to_string(f, -0.0, MinusPlusRaw, ( 5,  9), false), "-0e0");
+
+    assert_eq!(to_string(f,  1.0/0.0, Minus,        (-4, 16), false), "inf");
+    assert_eq!(to_string(f,  1.0/0.0, MinusRaw,     (-4, 16),  true), "inf");
+    assert_eq!(to_string(f,  1.0/0.0, MinusPlus,    (-4, 16), false), "+inf");
+    assert_eq!(to_string(f,  1.0/0.0, MinusPlusRaw, (-4, 16),  true), "+inf");
+    assert_eq!(to_string(f,  0.0/0.0, Minus,        ( 0,  0), false), "NaN");
+    assert_eq!(to_string(f,  0.0/0.0, MinusRaw,     ( 0,  0),  true), "NaN");
+    assert_eq!(to_string(f,  0.0/0.0, MinusPlus,    (-9, -5), false), "NaN");
+    assert_eq!(to_string(f,  0.0/0.0, MinusPlusRaw, ( 5,  9),  true), "NaN");
+    assert_eq!(to_string(f, -1.0/0.0, Minus,        ( 0,  0), false), "-inf");
+    assert_eq!(to_string(f, -1.0/0.0, MinusRaw,     ( 0,  0),  true), "-inf");
+    assert_eq!(to_string(f, -1.0/0.0, MinusPlus,    (-9, -5), false), "-inf");
+    assert_eq!(to_string(f, -1.0/0.0, MinusPlusRaw, ( 5,  9),  true), "-inf");
+
+    assert_eq!(to_string(f,  3.14, Minus,        (-4, 16), false), "3.14");
+    assert_eq!(to_string(f,  3.14, MinusRaw,     (-4, 16), false), "3.14");
+    assert_eq!(to_string(f,  3.14, MinusPlus,    (-4, 16), false), "+3.14");
+    assert_eq!(to_string(f,  3.14, MinusPlusRaw, (-4, 16), false), "+3.14");
+    assert_eq!(to_string(f, -3.14, Minus,        (-4, 16), false), "-3.14");
+    assert_eq!(to_string(f, -3.14, MinusRaw,     (-4, 16), false), "-3.14");
+    assert_eq!(to_string(f, -3.14, MinusPlus,    (-4, 16), false), "-3.14");
+    assert_eq!(to_string(f, -3.14, MinusPlusRaw, (-4, 16), false), "-3.14");
+    assert_eq!(to_string(f,  3.14, Minus,        ( 0,  0),  true), "3.14E0");
+    assert_eq!(to_string(f,  3.14, MinusRaw,     ( 0,  0), false), "3.14e0");
+    assert_eq!(to_string(f,  3.14, MinusPlus,    (-9, -5),  true), "+3.14E0");
+    assert_eq!(to_string(f,  3.14, MinusPlusRaw, ( 5,  9), false), "+3.14e0");
+    assert_eq!(to_string(f, -3.14, Minus,        ( 0,  0),  true), "-3.14E0");
+    assert_eq!(to_string(f, -3.14, MinusRaw,     ( 0,  0), false), "-3.14e0");
+    assert_eq!(to_string(f, -3.14, MinusPlus,    (-9, -5),  true), "-3.14E0");
+    assert_eq!(to_string(f, -3.14, MinusPlusRaw, ( 5,  9), false), "-3.14e0");
+
+    assert_eq!(to_string(f,  0.1, Minus,        (-4, 16), false), "0.1");
+    assert_eq!(to_string(f,  0.1, MinusRaw,     (-4, 16), false), "0.1");
+    assert_eq!(to_string(f,  0.1, MinusPlus,    (-4, 16), false), "+0.1");
+    assert_eq!(to_string(f,  0.1, MinusPlusRaw, (-4, 16), false), "+0.1");
+    assert_eq!(to_string(f, -0.1, Minus,        (-4, 16), false), "-0.1");
+    assert_eq!(to_string(f, -0.1, MinusRaw,     (-4, 16), false), "-0.1");
+    assert_eq!(to_string(f, -0.1, MinusPlus,    (-4, 16), false), "-0.1");
+    assert_eq!(to_string(f, -0.1, MinusPlusRaw, (-4, 16), false), "-0.1");
+    assert_eq!(to_string(f,  0.1, Minus,        ( 0,  0),  true), "1E-1");
+    assert_eq!(to_string(f,  0.1, MinusRaw,     ( 0,  0), false), "1e-1");
+    assert_eq!(to_string(f,  0.1, MinusPlus,    (-9, -5),  true), "+1E-1");
+    assert_eq!(to_string(f,  0.1, MinusPlusRaw, ( 5,  9), false), "+1e-1");
+    assert_eq!(to_string(f, -0.1, Minus,        ( 0,  0),  true), "-1E-1");
+    assert_eq!(to_string(f, -0.1, MinusRaw,     ( 0,  0), false), "-1e-1");
+    assert_eq!(to_string(f, -0.1, MinusPlus,    (-9, -5),  true), "-1E-1");
+    assert_eq!(to_string(f, -0.1, MinusPlusRaw, ( 5,  9), false), "-1e-1");
+
+    assert_eq!(to_string(f, 7.5e-11, Minus, ( -4, 16), false), "7.5e-11");
+    assert_eq!(to_string(f, 7.5e-11, Minus, (-11, 10), false), "0.000000000075");
+    assert_eq!(to_string(f, 7.5e-11, Minus, (-10, 11), false), "7.5e-11");
+
+    assert_eq!(to_string(f, 1.9971e20, Minus, ( -4, 16), false), "1.9971e20");
+    assert_eq!(to_string(f, 1.9971e20, Minus, (-20, 21), false), "199710000000000000000");
+    assert_eq!(to_string(f, 1.9971e20, Minus, (-21, 20), false), "1.9971e20");
+
+    // the true value of 1.0e23f64 is less than 10^23, but that shouldn't matter here
+    assert_eq!(to_string(f, 1.0e23, Minus, (22, 23), false), "1e23");
+    assert_eq!(to_string(f, 1.0e23, Minus, (23, 24), false), "100000000000000000000000");
+    assert_eq!(to_string(f, 1.0e23, Minus, (24, 25), false), "1e23");
+
+    assert_eq!(to_string(f, f32::MAX, Minus, ( -4, 16), false), "3.4028235e38");
+    assert_eq!(to_string(f, f32::MAX, Minus, (-39, 38), false), "3.4028235e38");
+    assert_eq!(to_string(f, f32::MAX, Minus, (-38, 39), false), format!("34028235{:0>31}", ""));
+
+    let minf32 = ldexp_f32(1.0, -149);
+    assert_eq!(to_string(f, minf32, Minus, ( -4, 16), false), "1e-45");
+    assert_eq!(to_string(f, minf32, Minus, (-44, 45), false), "1e-45");
+    assert_eq!(to_string(f, minf32, Minus, (-45, 44), false), format!("0.{:0>44}1", ""));
+
+    assert_eq!(to_string(f, f64::MAX, Minus, (  -4,  16), false),
+               "1.7976931348623157e308");
+    assert_eq!(to_string(f, f64::MAX, Minus, (-308, 309), false),
+               format!("17976931348623157{:0>292}", ""));
+    assert_eq!(to_string(f, f64::MAX, Minus, (-309, 308), false),
+               "1.7976931348623157e308");
+
+    let minf64 = ldexp_f64(1.0, -1074);
+    assert_eq!(to_string(f, minf64, Minus, (  -4,  16), false), "5e-324");
+    assert_eq!(to_string(f, minf64, Minus, (-324, 323), false), format!("0.{:0>323}5", ""));
+    assert_eq!(to_string(f, minf64, Minus, (-323, 324), false), "5e-324");
+
+    assert_eq!(to_string(f, 1.1, Minus, (i16::MIN, i16::MAX), false), "1.1");
+}
+
+pub fn to_exact_exp_str_test<F>(mut f_: F)
+        where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
+    use core::num::flt2dec::Sign::*;
+
+    fn to_string<T, F>(f: &mut F, v: T, sign: Sign, ndigits: usize, upper: bool) -> String
+            where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
+        to_string_with_parts(|buf, parts| to_exact_exp_str(|d,b,l| f(d,b,l), v, sign,
+                                                           ndigits, upper, buf, parts))
+    }
+
+    let f = &mut f_;
+
+    assert_eq!(to_string(f,  0.0, Minus,        1,  true), "0E0");
+    assert_eq!(to_string(f,  0.0, MinusRaw,     1, false), "0e0");
+    assert_eq!(to_string(f,  0.0, MinusPlus,    1,  true), "+0E0");
+    assert_eq!(to_string(f,  0.0, MinusPlusRaw, 1, false), "+0e0");
+    assert_eq!(to_string(f, -0.0, Minus,        1,  true), "0E0");
+    assert_eq!(to_string(f, -0.0, MinusRaw,     1, false), "-0e0");
+    assert_eq!(to_string(f, -0.0, MinusPlus,    1,  true), "+0E0");
+    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 1, false), "-0e0");
+    assert_eq!(to_string(f,  0.0, Minus,        2,  true), "0.0E0");
+    assert_eq!(to_string(f,  0.0, MinusRaw,     2, false), "0.0e0");
+    assert_eq!(to_string(f,  0.0, MinusPlus,    2,  true), "+0.0E0");
+    assert_eq!(to_string(f,  0.0, MinusPlusRaw, 2, false), "+0.0e0");
+    assert_eq!(to_string(f, -0.0, Minus,        8,  true), "0.0000000E0");
+    assert_eq!(to_string(f, -0.0, MinusRaw,     8, false), "-0.0000000e0");
+    assert_eq!(to_string(f, -0.0, MinusPlus,    8,  true), "+0.0000000E0");
+    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8, false), "-0.0000000e0");
+
+    assert_eq!(to_string(f,  1.0/0.0, Minus,         1, false), "inf");
+    assert_eq!(to_string(f,  1.0/0.0, MinusRaw,      1,  true), "inf");
+    assert_eq!(to_string(f,  1.0/0.0, MinusPlus,     1, false), "+inf");
+    assert_eq!(to_string(f,  1.0/0.0, MinusPlusRaw,  1,  true), "+inf");
+    assert_eq!(to_string(f,  0.0/0.0, Minus,         8, false), "NaN");
+    assert_eq!(to_string(f,  0.0/0.0, MinusRaw,      8,  true), "NaN");
+    assert_eq!(to_string(f,  0.0/0.0, MinusPlus,     8, false), "NaN");
+    assert_eq!(to_string(f,  0.0/0.0, MinusPlusRaw,  8,  true), "NaN");
+    assert_eq!(to_string(f, -1.0/0.0, Minus,        64, false), "-inf");
+    assert_eq!(to_string(f, -1.0/0.0, MinusRaw,     64,  true), "-inf");
+    assert_eq!(to_string(f, -1.0/0.0, MinusPlus,    64, false), "-inf");
+    assert_eq!(to_string(f, -1.0/0.0, MinusPlusRaw, 64,  true), "-inf");
+
+    assert_eq!(to_string(f,  3.14, Minus,        1,  true), "3E0");
+    assert_eq!(to_string(f,  3.14, MinusRaw,     1, false), "3e0");
+    assert_eq!(to_string(f,  3.14, MinusPlus,    1,  true), "+3E0");
+    assert_eq!(to_string(f,  3.14, MinusPlusRaw, 1, false), "+3e0");
+    assert_eq!(to_string(f, -3.14, Minus,        2,  true), "-3.1E0");
+    assert_eq!(to_string(f, -3.14, MinusRaw,     2, false), "-3.1e0");
+    assert_eq!(to_string(f, -3.14, MinusPlus,    2,  true), "-3.1E0");
+    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 2, false), "-3.1e0");
+    assert_eq!(to_string(f,  3.14, Minus,        3,  true), "3.14E0");
+    assert_eq!(to_string(f,  3.14, MinusRaw,     3, false), "3.14e0");
+    assert_eq!(to_string(f,  3.14, MinusPlus,    3,  true), "+3.14E0");
+    assert_eq!(to_string(f,  3.14, MinusPlusRaw, 3, false), "+3.14e0");
+    assert_eq!(to_string(f, -3.14, Minus,        4,  true), "-3.140E0");
+    assert_eq!(to_string(f, -3.14, MinusRaw,     4, false), "-3.140e0");
+    assert_eq!(to_string(f, -3.14, MinusPlus,    4,  true), "-3.140E0");
+    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 4, false), "-3.140e0");
+
+    assert_eq!(to_string(f,  0.195, Minus,        1, false), "2e-1");
+    assert_eq!(to_string(f,  0.195, MinusRaw,     1,  true), "2E-1");
+    assert_eq!(to_string(f,  0.195, MinusPlus,    1, false), "+2e-1");
+    assert_eq!(to_string(f,  0.195, MinusPlusRaw, 1,  true), "+2E-1");
+    assert_eq!(to_string(f, -0.195, Minus,        2, false), "-2.0e-1");
+    assert_eq!(to_string(f, -0.195, MinusRaw,     2,  true), "-2.0E-1");
+    assert_eq!(to_string(f, -0.195, MinusPlus,    2, false), "-2.0e-1");
+    assert_eq!(to_string(f, -0.195, MinusPlusRaw, 2,  true), "-2.0E-1");
+    assert_eq!(to_string(f,  0.195, Minus,        3, false), "1.95e-1");
+    assert_eq!(to_string(f,  0.195, MinusRaw,     3,  true), "1.95E-1");
+    assert_eq!(to_string(f,  0.195, MinusPlus,    3, false), "+1.95e-1");
+    assert_eq!(to_string(f,  0.195, MinusPlusRaw, 3,  true), "+1.95E-1");
+    assert_eq!(to_string(f, -0.195, Minus,        4, false), "-1.950e-1");
+    assert_eq!(to_string(f, -0.195, MinusRaw,     4,  true), "-1.950E-1");
+    assert_eq!(to_string(f, -0.195, MinusPlus,    4, false), "-1.950e-1");
+    assert_eq!(to_string(f, -0.195, MinusPlusRaw, 4,  true), "-1.950E-1");
+
+    assert_eq!(to_string(f, 9.5, Minus,  1, false), "1e1");
+    assert_eq!(to_string(f, 9.5, Minus,  2, false), "9.5e0");
+    assert_eq!(to_string(f, 9.5, Minus,  3, false), "9.50e0");
+    assert_eq!(to_string(f, 9.5, Minus, 30, false), "9.50000000000000000000000000000e0");
+
+    assert_eq!(to_string(f, 1.0e25, Minus,  1, false), "1e25");
+    assert_eq!(to_string(f, 1.0e25, Minus,  2, false), "1.0e25");
+    assert_eq!(to_string(f, 1.0e25, Minus, 15, false), "1.00000000000000e25");
+    assert_eq!(to_string(f, 1.0e25, Minus, 16, false), "1.000000000000000e25");
+    assert_eq!(to_string(f, 1.0e25, Minus, 17, false), "1.0000000000000001e25");
+    assert_eq!(to_string(f, 1.0e25, Minus, 18, false), "1.00000000000000009e25");
+    assert_eq!(to_string(f, 1.0e25, Minus, 19, false), "1.000000000000000091e25");
+    assert_eq!(to_string(f, 1.0e25, Minus, 20, false), "1.0000000000000000906e25");
+    assert_eq!(to_string(f, 1.0e25, Minus, 21, false), "1.00000000000000009060e25");
+    assert_eq!(to_string(f, 1.0e25, Minus, 22, false), "1.000000000000000090597e25");
+    assert_eq!(to_string(f, 1.0e25, Minus, 23, false), "1.0000000000000000905970e25");
+    assert_eq!(to_string(f, 1.0e25, Minus, 24, false), "1.00000000000000009059697e25");
+    assert_eq!(to_string(f, 1.0e25, Minus, 25, false), "1.000000000000000090596966e25");
+    assert_eq!(to_string(f, 1.0e25, Minus, 26, false), "1.0000000000000000905969664e25");
+    assert_eq!(to_string(f, 1.0e25, Minus, 27, false), "1.00000000000000009059696640e25");
+    assert_eq!(to_string(f, 1.0e25, Minus, 30, false), "1.00000000000000009059696640000e25");
+
+    assert_eq!(to_string(f, 1.0e-6, Minus,  1, false), "1e-6");
+    assert_eq!(to_string(f, 1.0e-6, Minus,  2, false), "1.0e-6");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 16, false), "1.000000000000000e-6");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 17, false), "9.9999999999999995e-7");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 18, false), "9.99999999999999955e-7");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 19, false), "9.999999999999999547e-7");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 20, false), "9.9999999999999995475e-7");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 30, false), "9.99999999999999954748111825886e-7");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 40, false),
+               "9.999999999999999547481118258862586856139e-7");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 50, false),
+               "9.9999999999999995474811182588625868561393872369081e-7");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 60, false),
+               "9.99999999999999954748111825886258685613938723690807819366455e-7");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 70, false),
+               "9.999999999999999547481118258862586856139387236908078193664550781250000e-7");
+
+    assert_eq!(to_string(f, f32::MAX, Minus,  1, false), "3e38");
+    assert_eq!(to_string(f, f32::MAX, Minus,  2, false), "3.4e38");
+    assert_eq!(to_string(f, f32::MAX, Minus,  4, false), "3.403e38");
+    assert_eq!(to_string(f, f32::MAX, Minus,  8, false), "3.4028235e38");
+    assert_eq!(to_string(f, f32::MAX, Minus, 16, false), "3.402823466385289e38");
+    assert_eq!(to_string(f, f32::MAX, Minus, 32, false), "3.4028234663852885981170418348452e38");
+    assert_eq!(to_string(f, f32::MAX, Minus, 64, false),
+               "3.402823466385288598117041834845169254400000000000000000000000000e38");
+
+    let minf32 = ldexp_f32(1.0, -149);
+    assert_eq!(to_string(f, minf32, Minus,   1, false), "1e-45");
+    assert_eq!(to_string(f, minf32, Minus,   2, false), "1.4e-45");
+    assert_eq!(to_string(f, minf32, Minus,   4, false), "1.401e-45");
+    assert_eq!(to_string(f, minf32, Minus,   8, false), "1.4012985e-45");
+    assert_eq!(to_string(f, minf32, Minus,  16, false), "1.401298464324817e-45");
+    assert_eq!(to_string(f, minf32, Minus,  32, false), "1.4012984643248170709237295832899e-45");
+    assert_eq!(to_string(f, minf32, Minus,  64, false),
+               "1.401298464324817070923729583289916131280261941876515771757068284e-45");
+    assert_eq!(to_string(f, minf32, Minus, 128, false),
+               "1.401298464324817070923729583289916131280261941876515771757068283\
+                 8897910826858606014866381883621215820312500000000000000000000000e-45");
+
+    assert_eq!(to_string(f, f64::MAX, Minus,   1, false), "2e308");
+    assert_eq!(to_string(f, f64::MAX, Minus,   2, false), "1.8e308");
+    assert_eq!(to_string(f, f64::MAX, Minus,   4, false), "1.798e308");
+    assert_eq!(to_string(f, f64::MAX, Minus,   8, false), "1.7976931e308");
+    assert_eq!(to_string(f, f64::MAX, Minus,  16, false), "1.797693134862316e308");
+    assert_eq!(to_string(f, f64::MAX, Minus,  32, false), "1.7976931348623157081452742373170e308");
+    assert_eq!(to_string(f, f64::MAX, Minus,  64, false),
+               "1.797693134862315708145274237317043567980705675258449965989174768e308");
+    assert_eq!(to_string(f, f64::MAX, Minus, 128, false),
+               "1.797693134862315708145274237317043567980705675258449965989174768\
+                 0315726078002853876058955863276687817154045895351438246423432133e308");
+    assert_eq!(to_string(f, f64::MAX, Minus, 256, false),
+               "1.797693134862315708145274237317043567980705675258449965989174768\
+                 0315726078002853876058955863276687817154045895351438246423432132\
+                 6889464182768467546703537516986049910576551282076245490090389328\
+                 9440758685084551339423045832369032229481658085593321233482747978e308");
+    assert_eq!(to_string(f, f64::MAX, Minus, 512, false),
+               "1.797693134862315708145274237317043567980705675258449965989174768\
+                 0315726078002853876058955863276687817154045895351438246423432132\
+                 6889464182768467546703537516986049910576551282076245490090389328\
+                 9440758685084551339423045832369032229481658085593321233482747978\
+                 2620414472316873817718091929988125040402618412485836800000000000\
+                 0000000000000000000000000000000000000000000000000000000000000000\
+                 0000000000000000000000000000000000000000000000000000000000000000\
+                 0000000000000000000000000000000000000000000000000000000000000000e308");
+
+    // okay, this is becoming tough. fortunately for us, this is almost the worst case.
+    let minf64 = ldexp_f64(1.0, -1074);
+    assert_eq!(to_string(f, minf64, Minus,    1, false), "5e-324");
+    assert_eq!(to_string(f, minf64, Minus,    2, false), "4.9e-324");
+    assert_eq!(to_string(f, minf64, Minus,    4, false), "4.941e-324");
+    assert_eq!(to_string(f, minf64, Minus,    8, false), "4.9406565e-324");
+    assert_eq!(to_string(f, minf64, Minus,   16, false), "4.940656458412465e-324");
+    assert_eq!(to_string(f, minf64, Minus,   32, false), "4.9406564584124654417656879286822e-324");
+    assert_eq!(to_string(f, minf64, Minus,   64, false),
+               "4.940656458412465441765687928682213723650598026143247644255856825e-324");
+    assert_eq!(to_string(f, minf64, Minus,  128, false),
+               "4.940656458412465441765687928682213723650598026143247644255856825\
+                 0067550727020875186529983636163599237979656469544571773092665671e-324");
+    assert_eq!(to_string(f, minf64, Minus,  256, false),
+               "4.940656458412465441765687928682213723650598026143247644255856825\
+                 0067550727020875186529983636163599237979656469544571773092665671\
+                 0355939796398774796010781878126300713190311404527845817167848982\
+                 1036887186360569987307230500063874091535649843873124733972731696e-324");
+    assert_eq!(to_string(f, minf64, Minus,  512, false),
+               "4.940656458412465441765687928682213723650598026143247644255856825\
+                 0067550727020875186529983636163599237979656469544571773092665671\
+                 0355939796398774796010781878126300713190311404527845817167848982\
+                 1036887186360569987307230500063874091535649843873124733972731696\
+                 1514003171538539807412623856559117102665855668676818703956031062\
+                 4931945271591492455329305456544401127480129709999541931989409080\
+                 4165633245247571478690147267801593552386115501348035264934720193\
+                 7902681071074917033322268447533357208324319360923828934583680601e-324");
+    assert_eq!(to_string(f, minf64, Minus, 1024, false),
+               "4.940656458412465441765687928682213723650598026143247644255856825\
+                 0067550727020875186529983636163599237979656469544571773092665671\
+                 0355939796398774796010781878126300713190311404527845817167848982\
+                 1036887186360569987307230500063874091535649843873124733972731696\
+                 1514003171538539807412623856559117102665855668676818703956031062\
+                 4931945271591492455329305456544401127480129709999541931989409080\
+                 4165633245247571478690147267801593552386115501348035264934720193\
+                 7902681071074917033322268447533357208324319360923828934583680601\
+                 0601150616980975307834227731832924790498252473077637592724787465\
+                 6084778203734469699533647017972677717585125660551199131504891101\
+                 4510378627381672509558373897335989936648099411642057026370902792\
+                 4276754456522908753868250641971826553344726562500000000000000000\
+                 0000000000000000000000000000000000000000000000000000000000000000\
+                 0000000000000000000000000000000000000000000000000000000000000000\
+                 0000000000000000000000000000000000000000000000000000000000000000\
+                 0000000000000000000000000000000000000000000000000000000000000000e-324");
+
+    // very large output
+    assert_eq!(to_string(f, 0.0,     Minus, 80000, false), format!("0.{:0>79999}e0", ""));
+    assert_eq!(to_string(f, 1.0e1,   Minus, 80000, false), format!("1.{:0>79999}e1", ""));
+    assert_eq!(to_string(f, 1.0e0,   Minus, 80000, false), format!("1.{:0>79999}e0", ""));
+    assert_eq!(to_string(f, 1.0e-1,  Minus, 80000, false),
+               format!("1.000000000000000055511151231257827021181583404541015625{:0>79945}\
+                        e-1", ""));
+    assert_eq!(to_string(f, 1.0e-20, Minus, 80000, false),
+               format!("9.999999999999999451532714542095716517295037027873924471077157760\
+                         66783064379706047475337982177734375{:0>79901}e-21", ""));
+}
+
+pub fn to_exact_fixed_str_test<F>(mut f_: F)
+        where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
+    use core::num::flt2dec::Sign::*;
+
+    fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize, upper: bool) -> String
+            where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
+        to_string_with_parts(|buf, parts| to_exact_fixed_str(|d,b,l| f(d,b,l), v, sign,
+                                                             frac_digits, upper, buf, parts))
+    }
+
+    let f = &mut f_;
+
+    assert_eq!(to_string(f,  0.0, Minus,        0, false), "0");
+    assert_eq!(to_string(f,  0.0, MinusRaw,     0, false), "0");
+    assert_eq!(to_string(f,  0.0, MinusPlus,    0, false), "+0");
+    assert_eq!(to_string(f,  0.0, MinusPlusRaw, 0, false), "+0");
+    assert_eq!(to_string(f, -0.0, Minus,        0, false), "0");
+    assert_eq!(to_string(f, -0.0, MinusRaw,     0, false), "-0");
+    assert_eq!(to_string(f, -0.0, MinusPlus,    0, false), "+0");
+    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 0, false), "-0");
+    assert_eq!(to_string(f,  0.0, Minus,        1,  true), "0.0");
+    assert_eq!(to_string(f,  0.0, MinusRaw,     1,  true), "0.0");
+    assert_eq!(to_string(f,  0.0, MinusPlus,    1,  true), "+0.0");
+    assert_eq!(to_string(f,  0.0, MinusPlusRaw, 1,  true), "+0.0");
+    assert_eq!(to_string(f, -0.0, Minus,        8,  true), "0.00000000");
+    assert_eq!(to_string(f, -0.0, MinusRaw,     8,  true), "-0.00000000");
+    assert_eq!(to_string(f, -0.0, MinusPlus,    8,  true), "+0.00000000");
+    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8,  true), "-0.00000000");
+
+    assert_eq!(to_string(f,  1.0/0.0, Minus,         0, false), "inf");
+    assert_eq!(to_string(f,  1.0/0.0, MinusRaw,      1,  true), "inf");
+    assert_eq!(to_string(f,  1.0/0.0, MinusPlus,     8, false), "+inf");
+    assert_eq!(to_string(f,  1.0/0.0, MinusPlusRaw, 64,  true), "+inf");
+    assert_eq!(to_string(f,  0.0/0.0, Minus,         0, false), "NaN");
+    assert_eq!(to_string(f,  0.0/0.0, MinusRaw,      1,  true), "NaN");
+    assert_eq!(to_string(f,  0.0/0.0, MinusPlus,     8, false), "NaN");
+    assert_eq!(to_string(f,  0.0/0.0, MinusPlusRaw, 64,  true), "NaN");
+    assert_eq!(to_string(f, -1.0/0.0, Minus,         0, false), "-inf");
+    assert_eq!(to_string(f, -1.0/0.0, MinusRaw,      1,  true), "-inf");
+    assert_eq!(to_string(f, -1.0/0.0, MinusPlus,     8, false), "-inf");
+    assert_eq!(to_string(f, -1.0/0.0, MinusPlusRaw, 64,  true), "-inf");
+
+    assert_eq!(to_string(f,  3.14, Minus,        0, false), "3");
+    assert_eq!(to_string(f,  3.14, MinusRaw,     0, false), "3");
+    assert_eq!(to_string(f,  3.14, MinusPlus,    0, false), "+3");
+    assert_eq!(to_string(f,  3.14, MinusPlusRaw, 0, false), "+3");
+    assert_eq!(to_string(f, -3.14, Minus,        0, false), "-3");
+    assert_eq!(to_string(f, -3.14, MinusRaw,     0, false), "-3");
+    assert_eq!(to_string(f, -3.14, MinusPlus,    0, false), "-3");
+    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 0, false), "-3");
+    assert_eq!(to_string(f,  3.14, Minus,        1,  true), "3.1");
+    assert_eq!(to_string(f,  3.14, MinusRaw,     2,  true), "3.14");
+    assert_eq!(to_string(f,  3.14, MinusPlus,    3,  true), "+3.140");
+    assert_eq!(to_string(f,  3.14, MinusPlusRaw, 4,  true), "+3.1400");
+    assert_eq!(to_string(f, -3.14, Minus,        8,  true), "-3.14000000");
+    assert_eq!(to_string(f, -3.14, MinusRaw,     8,  true), "-3.14000000");
+    assert_eq!(to_string(f, -3.14, MinusPlus,    8,  true), "-3.14000000");
+    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 8,  true), "-3.14000000");
+
+    assert_eq!(to_string(f,  0.195, Minus,        0, false), "0");
+    assert_eq!(to_string(f,  0.195, MinusRaw,     0, false), "0");
+    assert_eq!(to_string(f,  0.195, MinusPlus,    0, false), "+0");
+    assert_eq!(to_string(f,  0.195, MinusPlusRaw, 0, false), "+0");
+    assert_eq!(to_string(f, -0.195, Minus,        0, false), "-0");
+    assert_eq!(to_string(f, -0.195, MinusRaw,     0, false), "-0");
+    assert_eq!(to_string(f, -0.195, MinusPlus,    0, false), "-0");
+    assert_eq!(to_string(f, -0.195, MinusPlusRaw, 0, false), "-0");
+    assert_eq!(to_string(f,  0.195, Minus,        1,  true), "0.2");
+    assert_eq!(to_string(f,  0.195, MinusRaw,     2,  true), "0.20");
+    assert_eq!(to_string(f,  0.195, MinusPlus,    3,  true), "+0.195");
+    assert_eq!(to_string(f,  0.195, MinusPlusRaw, 4,  true), "+0.1950");
+    assert_eq!(to_string(f, -0.195, Minus,        5,  true), "-0.19500");
+    assert_eq!(to_string(f, -0.195, MinusRaw,     6,  true), "-0.195000");
+    assert_eq!(to_string(f, -0.195, MinusPlus,    7,  true), "-0.1950000");
+    assert_eq!(to_string(f, -0.195, MinusPlusRaw, 8,  true), "-0.19500000");
+
+    assert_eq!(to_string(f, 999.5, Minus,  0, false), "1000");
+    assert_eq!(to_string(f, 999.5, Minus,  1, false), "999.5");
+    assert_eq!(to_string(f, 999.5, Minus,  2, false), "999.50");
+    assert_eq!(to_string(f, 999.5, Minus,  3, false), "999.500");
+    assert_eq!(to_string(f, 999.5, Minus, 30, false), "999.500000000000000000000000000000");
+
+    assert_eq!(to_string(f, 0.5, Minus, 0, false), "1");
+    assert_eq!(to_string(f, 0.5, Minus, 1, false), "0.5");
+    assert_eq!(to_string(f, 0.5, Minus, 2, false), "0.50");
+    assert_eq!(to_string(f, 0.5, Minus, 3, false), "0.500");
+
+    assert_eq!(to_string(f, 0.95, Minus,  0, false), "1");
+    assert_eq!(to_string(f, 0.95, Minus,  1, false), "0.9"); // because it really is less than 0.95
+    assert_eq!(to_string(f, 0.95, Minus,  2, false), "0.95");
+    assert_eq!(to_string(f, 0.95, Minus,  3, false), "0.950");
+    assert_eq!(to_string(f, 0.95, Minus, 10, false), "0.9500000000");
+    assert_eq!(to_string(f, 0.95, Minus, 30, false), "0.949999999999999955591079014994");
+
+    assert_eq!(to_string(f, 0.095, Minus,  0, false), "0");
+    assert_eq!(to_string(f, 0.095, Minus,  1, false), "0.1");
+    assert_eq!(to_string(f, 0.095, Minus,  2, false), "0.10");
+    assert_eq!(to_string(f, 0.095, Minus,  3, false), "0.095");
+    assert_eq!(to_string(f, 0.095, Minus,  4, false), "0.0950");
+    assert_eq!(to_string(f, 0.095, Minus, 10, false), "0.0950000000");
+    assert_eq!(to_string(f, 0.095, Minus, 30, false), "0.095000000000000001110223024625");
+
+    assert_eq!(to_string(f, 0.0095, Minus,  0, false), "0");
+    assert_eq!(to_string(f, 0.0095, Minus,  1, false), "0.0");
+    assert_eq!(to_string(f, 0.0095, Minus,  2, false), "0.01");
+    assert_eq!(to_string(f, 0.0095, Minus,  3, false), "0.009"); // really is less than 0.0095
+    assert_eq!(to_string(f, 0.0095, Minus,  4, false), "0.0095");
+    assert_eq!(to_string(f, 0.0095, Minus,  5, false), "0.00950");
+    assert_eq!(to_string(f, 0.0095, Minus, 10, false), "0.0095000000");
+    assert_eq!(to_string(f, 0.0095, Minus, 30, false), "0.009499999999999999764077607267");
+
+    assert_eq!(to_string(f, 7.5e-11, Minus,  0, false), "0");
+    assert_eq!(to_string(f, 7.5e-11, Minus,  3, false), "0.000");
+    assert_eq!(to_string(f, 7.5e-11, Minus, 10, false), "0.0000000001");
+    assert_eq!(to_string(f, 7.5e-11, Minus, 11, false), "0.00000000007"); // ditto
+    assert_eq!(to_string(f, 7.5e-11, Minus, 12, false), "0.000000000075");
+    assert_eq!(to_string(f, 7.5e-11, Minus, 13, false), "0.0000000000750");
+    assert_eq!(to_string(f, 7.5e-11, Minus, 20, false), "0.00000000007500000000");
+    assert_eq!(to_string(f, 7.5e-11, Minus, 30, false), "0.000000000074999999999999999501");
+
+    assert_eq!(to_string(f, 1.0e25, Minus, 0, false), "10000000000000000905969664");
+    assert_eq!(to_string(f, 1.0e25, Minus, 1, false), "10000000000000000905969664.0");
+    assert_eq!(to_string(f, 1.0e25, Minus, 3, false), "10000000000000000905969664.000");
+
+    assert_eq!(to_string(f, 1.0e-6, Minus,  0, false), "0");
+    assert_eq!(to_string(f, 1.0e-6, Minus,  3, false), "0.000");
+    assert_eq!(to_string(f, 1.0e-6, Minus,  6, false), "0.000001");
+    assert_eq!(to_string(f, 1.0e-6, Minus,  9, false), "0.000001000");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 12, false), "0.000001000000");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 22, false), "0.0000010000000000000000");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 23, false), "0.00000099999999999999995");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 24, false), "0.000000999999999999999955");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 25, false), "0.0000009999999999999999547");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 35, false), "0.00000099999999999999995474811182589");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 45, false),
+               "0.000000999999999999999954748111825886258685614");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 55, false),
+               "0.0000009999999999999999547481118258862586856139387236908");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 65, false),
+               "0.00000099999999999999995474811182588625868561393872369080781936646");
+    assert_eq!(to_string(f, 1.0e-6, Minus, 75, false),
+               "0.000000999999999999999954748111825886258685613938723690807819366455078125000");
+
+    assert_eq!(to_string(f, f32::MAX, Minus, 0, false),
+               "340282346638528859811704183484516925440");
+    assert_eq!(to_string(f, f32::MAX, Minus, 1, false),
+               "340282346638528859811704183484516925440.0");
+    assert_eq!(to_string(f, f32::MAX, Minus, 2, false),
+               "340282346638528859811704183484516925440.00");
+
+    let minf32 = ldexp_f32(1.0, -149);
+    assert_eq!(to_string(f, minf32, Minus,   0, false), "0");
+    assert_eq!(to_string(f, minf32, Minus,   1, false), "0.0");
+    assert_eq!(to_string(f, minf32, Minus,   2, false), "0.00");
+    assert_eq!(to_string(f, minf32, Minus,   4, false), "0.0000");
+    assert_eq!(to_string(f, minf32, Minus,   8, false), "0.00000000");
+    assert_eq!(to_string(f, minf32, Minus,  16, false), "0.0000000000000000");
+    assert_eq!(to_string(f, minf32, Minus,  32, false), "0.00000000000000000000000000000000");
+    assert_eq!(to_string(f, minf32, Minus,  64, false),
+               "0.0000000000000000000000000000000000000000000014012984643248170709");
+    assert_eq!(to_string(f, minf32, Minus, 128, false),
+               "0.0000000000000000000000000000000000000000000014012984643248170709\
+                  2372958328991613128026194187651577175706828388979108268586060149");
+    assert_eq!(to_string(f, minf32, Minus, 256, false),
+               "0.0000000000000000000000000000000000000000000014012984643248170709\
+                  2372958328991613128026194187651577175706828388979108268586060148\
+                  6638188362121582031250000000000000000000000000000000000000000000\
+                  0000000000000000000000000000000000000000000000000000000000000000");
+
+    assert_eq!(to_string(f, f64::MAX, Minus, 0, false),
+               "1797693134862315708145274237317043567980705675258449965989174768\
+                0315726078002853876058955863276687817154045895351438246423432132\
+                6889464182768467546703537516986049910576551282076245490090389328\
+                9440758685084551339423045832369032229481658085593321233482747978\
+                26204144723168738177180919299881250404026184124858368");
+    assert_eq!(to_string(f, f64::MAX, Minus, 10, false),
+               "1797693134862315708145274237317043567980705675258449965989174768\
+                0315726078002853876058955863276687817154045895351438246423432132\
+                6889464182768467546703537516986049910576551282076245490090389328\
+                9440758685084551339423045832369032229481658085593321233482747978\
+                26204144723168738177180919299881250404026184124858368.0000000000");
+
+    let minf64 = ldexp_f64(1.0, -1074);
+    assert_eq!(to_string(f, minf64, Minus, 0, false), "0");
+    assert_eq!(to_string(f, minf64, Minus, 1, false), "0.0");
+    assert_eq!(to_string(f, minf64, Minus, 10, false), "0.0000000000");
+    assert_eq!(to_string(f, minf64, Minus, 100, false),
+               "0.0000000000000000000000000000000000000000000000000000000000000000\
+                  000000000000000000000000000000000000");
+    assert_eq!(to_string(f, minf64, Minus, 1000, false),
+               "0.0000000000000000000000000000000000000000000000000000000000000000\
+                  0000000000000000000000000000000000000000000000000000000000000000\
+                  0000000000000000000000000000000000000000000000000000000000000000\
+                  0000000000000000000000000000000000000000000000000000000000000000\
+                  0000000000000000000000000000000000000000000000000000000000000000\
+                  0004940656458412465441765687928682213723650598026143247644255856\
+                  8250067550727020875186529983636163599237979656469544571773092665\
+                  6710355939796398774796010781878126300713190311404527845817167848\
+                  9821036887186360569987307230500063874091535649843873124733972731\
+                  6961514003171538539807412623856559117102665855668676818703956031\
+                  0624931945271591492455329305456544401127480129709999541931989409\
+                  0804165633245247571478690147267801593552386115501348035264934720\
+                  1937902681071074917033322268447533357208324319360923828934583680\
+                  6010601150616980975307834227731832924790498252473077637592724787\
+                  4656084778203734469699533647017972677717585125660551199131504891\
+                  1014510378627381672509558373897335989937");
+
+    // very large output
+    assert_eq!(to_string(f, 0.0,     Minus, 80000, false), format!("0.{:0>80000}", ""));
+    assert_eq!(to_string(f, 1.0e1,   Minus, 80000, false), format!("10.{:0>80000}", ""));
+    assert_eq!(to_string(f, 1.0e0,   Minus, 80000, false), format!("1.{:0>80000}", ""));
+    assert_eq!(to_string(f, 1.0e-1,  Minus, 80000, false),
+               format!("0.1000000000000000055511151231257827021181583404541015625{:0>79945}", ""));
+    assert_eq!(to_string(f, 1.0e-20, Minus, 80000, false),
+               format!("0.0000000000000000000099999999999999994515327145420957165172950370\
+                          2787392447107715776066783064379706047475337982177734375{:0>79881}", ""));
+}
+
diff --git a/src/libcore/tests/num/flt2dec/strategy/dragon.rs b/src/libcore/tests/num/flt2dec/strategy/dragon.rs
new file mode 100644 (file)
index 0000000..4edb0f3
--- /dev/null
@@ -0,0 +1,74 @@
+// 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::prelude::v1::*;
+use super::super::*;
+use core::num::bignum::Big32x40 as Big;
+use core::num::flt2dec::strategy::dragon::*;
+
+#[test]
+fn test_mul_pow10() {
+    let mut prevpow10 = Big::from_small(1);
+    for i in 1..340 {
+        let mut curpow10 = Big::from_small(1);
+        mul_pow10(&mut curpow10, i);
+        assert_eq!(curpow10, *prevpow10.clone().mul_small(10));
+        prevpow10 = curpow10;
+    }
+}
+
+#[test]
+fn shortest_sanity_test() {
+    f64_shortest_sanity_test(format_shortest);
+    f32_shortest_sanity_test(format_shortest);
+    more_shortest_sanity_test(format_shortest);
+}
+
+#[test]
+fn exact_sanity_test() {
+    // This test ends up running what I can only assume is some corner-ish case
+    // of the `exp2` library function, defined in whatever C runtime we're
+    // using. In VS 2013 this function apparently had a bug as this test fails
+    // when linked, but with VS 2015 the bug appears fixed as the test runs just
+    // fine.
+    //
+    // The bug seems to be a difference in return value of `exp2(-1057)`, where
+    // in VS 2013 it returns a double with the bit pattern 0x2 and in VS 2015 it
+    // returns 0x20000.
+    //
+    // For now just ignore this test entirely on MSVC as it's tested elsewhere
+    // anyway and we're not super interested in testing each platform's exp2
+    // implementation.
+    if !cfg!(target_env = "msvc") {
+        f64_exact_sanity_test(format_exact);
+    }
+    f32_exact_sanity_test(format_exact);
+}
+
+#[test]
+fn test_to_shortest_str() {
+    to_shortest_str_test(format_shortest);
+}
+
+#[test]
+fn test_to_shortest_exp_str() {
+    to_shortest_exp_str_test(format_shortest);
+}
+
+#[test]
+fn test_to_exact_exp_str() {
+    to_exact_exp_str_test(format_exact);
+}
+
+#[test]
+fn test_to_exact_fixed_str() {
+    to_exact_fixed_str_test(format_exact);
+}
+
diff --git a/src/libcore/tests/num/flt2dec/strategy/grisu.rs b/src/libcore/tests/num/flt2dec/strategy/grisu.rs
new file mode 100644 (file)
index 0000000..79e66ee
--- /dev/null
@@ -0,0 +1,124 @@
+// 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::i16;
+use super::super::*;
+use core::num::flt2dec::strategy::grisu::*;
+
+#[test]
+fn test_cached_power() {
+    assert_eq!(CACHED_POW10.first().unwrap().1, CACHED_POW10_FIRST_E);
+    assert_eq!(CACHED_POW10.last().unwrap().1, CACHED_POW10_LAST_E);
+
+    for e in -1137..961 { // full range for f64
+        let low = ALPHA - e - 64;
+        let high = GAMMA - e - 64;
+        let (_k, cached) = cached_power(low, high);
+        assert!(low <= cached.e && cached.e <= high,
+                "cached_power({}, {}) = {:?} is incorrect", low, high, cached);
+    }
+}
+
+#[test]
+fn test_max_pow10_no_more_than() {
+    let mut prevtenk = 1;
+    for k in 1..10 {
+        let tenk = prevtenk * 10;
+        assert_eq!(max_pow10_no_more_than(tenk - 1), (k - 1, prevtenk));
+        assert_eq!(max_pow10_no_more_than(tenk), (k, tenk));
+        prevtenk = tenk;
+    }
+}
+
+
+#[test]
+fn shortest_sanity_test() {
+    f64_shortest_sanity_test(format_shortest);
+    f32_shortest_sanity_test(format_shortest);
+    more_shortest_sanity_test(format_shortest);
+}
+
+#[test]
+fn shortest_random_equivalence_test() {
+    use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
+    f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
+    f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
+}
+
+#[test] #[ignore] // it is too expensive
+fn shortest_f32_exhaustive_equivalence_test() {
+    // it is hard to directly test the optimality of the output, but we can at least test if
+    // two different algorithms agree to each other.
+    //
+    // this reports the progress and the number of f32 values returned `None`.
+    // with `--nocapture` (and plenty of time and appropriate rustc flags), this should print:
+    // `done, ignored=17643158 passed=2121451881 failed=0`.
+
+    use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
+    f32_exhaustive_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS);
+}
+
+#[test] #[ignore] // it is too expensive
+fn shortest_f64_hard_random_equivalence_test() {
+    // this again probably has to use appropriate rustc flags.
+
+    use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
+    f64_random_equivalence_test(format_shortest_opt, fallback,
+                                         MAX_SIG_DIGITS, 100_000_000);
+}
+
+#[test]
+fn exact_sanity_test() {
+    // See comments in dragon.rs's exact_sanity_test for why this test is
+    // ignored on MSVC
+    if !cfg!(target_env = "msvc") {
+        f64_exact_sanity_test(format_exact);
+    }
+    f32_exact_sanity_test(format_exact);
+}
+
+#[test]
+fn exact_f32_random_equivalence_test() {
+    use core::num::flt2dec::strategy::dragon::format_exact as fallback;
+    for k in 1..21 {
+        f32_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
+                                             |d, buf| fallback(d, buf, i16::MIN), k, 1_000);
+    }
+}
+
+#[test]
+fn exact_f64_random_equivalence_test() {
+    use core::num::flt2dec::strategy::dragon::format_exact as fallback;
+    for k in 1..21 {
+        f64_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
+                                             |d, buf| fallback(d, buf, i16::MIN), k, 1_000);
+    }
+}
+
+#[test]
+fn test_to_shortest_str() {
+    to_shortest_str_test(format_shortest);
+}
+
+#[test]
+fn test_to_shortest_exp_str() {
+    to_shortest_exp_str_test(format_shortest);
+}
+
+#[test]
+fn test_to_exact_exp_str() {
+    to_exact_exp_str_test(format_exact);
+}
+
+#[test]
+fn test_to_exact_fixed_str() {
+    to_exact_fixed_str_test(format_exact);
+}
+
diff --git a/src/libcore/tests/num/i16.rs b/src/libcore/tests/num/i16.rs
new file mode 100644 (file)
index 0000000..7435831
--- /dev/null
@@ -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.
+
+int_module!(i16, i16);
diff --git a/src/libcore/tests/num/i32.rs b/src/libcore/tests/num/i32.rs
new file mode 100644 (file)
index 0000000..3b3407e
--- /dev/null
@@ -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.
+
+int_module!(i32, i32);
diff --git a/src/libcore/tests/num/i64.rs b/src/libcore/tests/num/i64.rs
new file mode 100644 (file)
index 0000000..9e1aec2
--- /dev/null
@@ -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.
+
+int_module!(i64, i64);
diff --git a/src/libcore/tests/num/i8.rs b/src/libcore/tests/num/i8.rs
new file mode 100644 (file)
index 0000000..f722442
--- /dev/null
@@ -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.
+
+int_module!(i8, i8);
diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs
new file mode 100644 (file)
index 0000000..8d79128
--- /dev/null
@@ -0,0 +1,219 @@
+// 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.
+
+macro_rules! int_module { ($T:ident, $T_i:ident) => (
+#[cfg(test)]
+mod tests {
+    use core::$T_i::*;
+    use core::isize;
+    use core::ops::{Shl, Shr, Not, BitXor, BitAnd, BitOr};
+    use core::mem;
+
+    use num;
+
+    #[test]
+    fn test_overflows() {
+        assert!(MAX > 0);
+        assert!(MIN <= 0);
+        assert!(MIN + MAX + 1 == 0);
+    }
+
+    #[test]
+    fn test_num() {
+        num::test_num(10 as $T, 2 as $T);
+    }
+
+    #[test]
+    pub fn test_abs() {
+        assert!((1 as $T).abs() == 1 as $T);
+        assert!((0 as $T).abs() == 0 as $T);
+        assert!((-1 as $T).abs() == 1 as $T);
+    }
+
+    #[test]
+    fn test_signum() {
+        assert!((1 as $T).signum() == 1 as $T);
+        assert!((0 as $T).signum() == 0 as $T);
+        assert!((-0 as $T).signum() == 0 as $T);
+        assert!((-1 as $T).signum() == -1 as $T);
+    }
+
+    #[test]
+    fn test_is_positive() {
+        assert!((1 as $T).is_positive());
+        assert!(!(0 as $T).is_positive());
+        assert!(!(-0 as $T).is_positive());
+        assert!(!(-1 as $T).is_positive());
+    }
+
+    #[test]
+    fn test_is_negative() {
+        assert!(!(1 as $T).is_negative());
+        assert!(!(0 as $T).is_negative());
+        assert!(!(-0 as $T).is_negative());
+        assert!((-1 as $T).is_negative());
+    }
+
+    #[test]
+    fn test_bitwise_operators() {
+        assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T));
+        assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T));
+        assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T));
+        assert!(0b1110 as $T == (0b0111 as $T).shl(1));
+        assert!(0b0111 as $T == (0b1110 as $T).shr(1));
+        assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not());
+    }
+
+    const A: $T = 0b0101100;
+    const B: $T = 0b0100001;
+    const C: $T = 0b1111001;
+
+    const _0: $T = 0;
+    const _1: $T = !0;
+
+    #[test]
+    fn test_count_ones() {
+        assert!(A.count_ones() == 3);
+        assert!(B.count_ones() == 2);
+        assert!(C.count_ones() == 5);
+    }
+
+    #[test]
+    fn test_count_zeros() {
+        let bits = mem::size_of::<$T>() * 8;
+        assert!(A.count_zeros() == bits as u32 - 3);
+        assert!(B.count_zeros() == bits as u32 - 2);
+        assert!(C.count_zeros() == bits as u32 - 5);
+    }
+
+    #[test]
+    fn test_rotate() {
+        assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
+        assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
+        assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
+
+        // Rotating these should make no difference
+        //
+        // We test using 124 bits because to ensure that overlong bit shifts do
+        // not cause undefined behaviour. See #10183.
+        assert_eq!(_0.rotate_left(124), _0);
+        assert_eq!(_1.rotate_left(124), _1);
+        assert_eq!(_0.rotate_right(124), _0);
+        assert_eq!(_1.rotate_right(124), _1);
+
+        // Rotating by 0 should have no effect
+        assert_eq!(A.rotate_left(0), A);
+        assert_eq!(B.rotate_left(0), B);
+        assert_eq!(C.rotate_left(0), C);
+        // Rotating by a multiple of word size should also have no effect
+        assert_eq!(A.rotate_left(64), A);
+        assert_eq!(B.rotate_left(64), B);
+        assert_eq!(C.rotate_left(64), C);
+    }
+
+    #[test]
+    fn test_swap_bytes() {
+        assert_eq!(A.swap_bytes().swap_bytes(), A);
+        assert_eq!(B.swap_bytes().swap_bytes(), B);
+        assert_eq!(C.swap_bytes().swap_bytes(), C);
+
+        // Swapping these should make no difference
+        assert_eq!(_0.swap_bytes(), _0);
+        assert_eq!(_1.swap_bytes(), _1);
+    }
+
+    #[test]
+    fn test_le() {
+        assert_eq!($T::from_le(A.to_le()), A);
+        assert_eq!($T::from_le(B.to_le()), B);
+        assert_eq!($T::from_le(C.to_le()), C);
+        assert_eq!($T::from_le(_0), _0);
+        assert_eq!($T::from_le(_1), _1);
+        assert_eq!(_0.to_le(), _0);
+        assert_eq!(_1.to_le(), _1);
+    }
+
+    #[test]
+    fn test_be() {
+        assert_eq!($T::from_be(A.to_be()), A);
+        assert_eq!($T::from_be(B.to_be()), B);
+        assert_eq!($T::from_be(C.to_be()), C);
+        assert_eq!($T::from_be(_0), _0);
+        assert_eq!($T::from_be(_1), _1);
+        assert_eq!(_0.to_be(), _0);
+        assert_eq!(_1.to_be(), _1);
+    }
+
+    #[test]
+    fn test_signed_checked_div() {
+        assert!((10 as $T).checked_div(2) == Some(5));
+        assert!((5 as $T).checked_div(0) == None);
+        assert!(isize::MIN.checked_div(-1) == None);
+    }
+
+    #[test]
+    fn test_from_str() {
+        fn from_str<T: ::std::str::FromStr>(t: &str) -> Option<T> {
+            ::std::str::FromStr::from_str(t).ok()
+        }
+        assert_eq!(from_str::<$T>("0"), Some(0 as $T));
+        assert_eq!(from_str::<$T>("3"), Some(3 as $T));
+        assert_eq!(from_str::<$T>("10"), Some(10 as $T));
+        assert_eq!(from_str::<i32>("123456789"), Some(123456789 as i32));
+        assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
+
+        assert_eq!(from_str::<$T>("-1"), Some(-1 as $T));
+        assert_eq!(from_str::<$T>("-3"), Some(-3 as $T));
+        assert_eq!(from_str::<$T>("-10"), Some(-10 as $T));
+        assert_eq!(from_str::<i32>("-123456789"), Some(-123456789 as i32));
+        assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T));
+
+        assert_eq!(from_str::<$T>(""), None);
+        assert_eq!(from_str::<$T>(" "), None);
+        assert_eq!(from_str::<$T>("x"), None);
+    }
+
+    #[test]
+    fn test_from_str_radix() {
+        assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
+        assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
+        assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
+        assert_eq!(i32::from_str_radix("123", 16), Ok(291 as i32));
+        assert_eq!(i32::from_str_radix("ffff", 16), Ok(65535 as i32));
+        assert_eq!(i32::from_str_radix("FFFF", 16), Ok(65535 as i32));
+        assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
+        assert_eq!($T::from_str_radix("Z", 36), Ok(35 as $T));
+
+        assert_eq!($T::from_str_radix("-123", 10), Ok(-123 as $T));
+        assert_eq!($T::from_str_radix("-1001", 2), Ok(-9 as $T));
+        assert_eq!($T::from_str_radix("-123", 8), Ok(-83 as $T));
+        assert_eq!(i32::from_str_radix("-123", 16), Ok(-291 as i32));
+        assert_eq!(i32::from_str_radix("-ffff", 16), Ok(-65535 as i32));
+        assert_eq!(i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
+        assert_eq!($T::from_str_radix("-z", 36), Ok(-35 as $T));
+        assert_eq!($T::from_str_radix("-Z", 36), Ok(-35 as $T));
+
+        assert_eq!($T::from_str_radix("Z", 35).ok(), None::<$T>);
+        assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>);
+    }
+
+    #[test]
+    fn test_pow() {
+        let mut r = 2 as $T;
+
+        assert_eq!(r.pow(2), 4 as $T);
+        assert_eq!(r.pow(0), 1 as $T);
+        r = -2 as $T;
+        assert_eq!(r.pow(2), 4 as $T);
+        assert_eq!(r.pow(3), -8 as $T);
+    }
+}
+
+)}
diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs
new file mode 100644 (file)
index 0000000..51737c9
--- /dev/null
@@ -0,0 +1,400 @@
+// 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 core::convert::TryFrom;
+use core::cmp::PartialEq;
+use core::fmt::Debug;
+use core::marker::Copy;
+use core::ops::{Add, Sub, Mul, Div, Rem};
+use core::option::Option;
+use core::option::Option::{Some, None};
+
+#[macro_use]
+mod int_macros;
+
+mod i8;
+mod i16;
+mod i32;
+mod i64;
+
+#[macro_use]
+mod uint_macros;
+
+mod u8;
+mod u16;
+mod u32;
+mod u64;
+
+mod flt2dec;
+mod dec2flt;
+mod bignum;
+
+/// Helper function for testing numeric operations
+pub fn test_num<T>(ten: T, two: T) where
+    T: PartialEq
+     + Add<Output=T> + Sub<Output=T>
+     + Mul<Output=T> + Div<Output=T>
+     + Rem<Output=T> + Debug
+     + Copy
+{
+    assert_eq!(ten.add(two),  ten + two);
+    assert_eq!(ten.sub(two),  ten - two);
+    assert_eq!(ten.mul(two),  ten * two);
+    assert_eq!(ten.div(two),  ten / two);
+    assert_eq!(ten.rem(two),  ten % two);
+}
+
+#[test]
+fn from_str_issue7588() {
+    let u : Option<u8> = u8::from_str_radix("1000", 10).ok();
+    assert_eq!(u, None);
+    let s : Option<i16> = i16::from_str_radix("80000", 10).ok();
+    assert_eq!(s, None);
+}
+
+#[test]
+fn test_int_from_str_overflow() {
+    let mut i8_val: i8 = 127;
+    assert_eq!("127".parse::<i8>().ok(), Some(i8_val));
+    assert_eq!("128".parse::<i8>().ok(), None);
+
+    i8_val = i8_val.wrapping_add(1);
+    assert_eq!("-128".parse::<i8>().ok(), Some(i8_val));
+    assert_eq!("-129".parse::<i8>().ok(), None);
+
+    let mut i16_val: i16 = 32_767;
+    assert_eq!("32767".parse::<i16>().ok(), Some(i16_val));
+    assert_eq!("32768".parse::<i16>().ok(), None);
+
+    i16_val = i16_val.wrapping_add(1);
+    assert_eq!("-32768".parse::<i16>().ok(), Some(i16_val));
+    assert_eq!("-32769".parse::<i16>().ok(), None);
+
+    let mut i32_val: i32 = 2_147_483_647;
+    assert_eq!("2147483647".parse::<i32>().ok(), Some(i32_val));
+    assert_eq!("2147483648".parse::<i32>().ok(), None);
+
+    i32_val = i32_val.wrapping_add(1);
+    assert_eq!("-2147483648".parse::<i32>().ok(), Some(i32_val));
+    assert_eq!("-2147483649".parse::<i32>().ok(), None);
+
+    let mut i64_val: i64 = 9_223_372_036_854_775_807;
+    assert_eq!("9223372036854775807".parse::<i64>().ok(), Some(i64_val));
+    assert_eq!("9223372036854775808".parse::<i64>().ok(), None);
+
+    i64_val = i64_val.wrapping_add(1);
+    assert_eq!("-9223372036854775808".parse::<i64>().ok(), Some(i64_val));
+    assert_eq!("-9223372036854775809".parse::<i64>().ok(), None);
+}
+
+#[test]
+fn test_leading_plus() {
+    assert_eq!("+127".parse::<u8>().ok(), Some(127));
+    assert_eq!("+9223372036854775807".parse::<i64>().ok(), Some(9223372036854775807));
+}
+
+#[test]
+fn test_invalid() {
+    assert_eq!("--129".parse::<i8>().ok(), None);
+    assert_eq!("++129".parse::<i8>().ok(), None);
+    assert_eq!("Съешь".parse::<u8>().ok(), None);
+}
+
+#[test]
+fn test_empty() {
+    assert_eq!("-".parse::<i8>().ok(), None);
+    assert_eq!("+".parse::<i8>().ok(), None);
+    assert_eq!("".parse::<u8>().ok(), None);
+}
+
+macro_rules! test_impl_from {
+    ($fn_name: ident, $Small: ty, $Large: ty) => {
+        #[test]
+        fn $fn_name() {
+            let small_max = <$Small>::max_value();
+            let small_min = <$Small>::min_value();
+            let large_max: $Large = small_max.into();
+            let large_min: $Large = small_min.into();
+            assert_eq!(large_max as $Small, small_max);
+            assert_eq!(large_min as $Small, small_min);
+        }
+    }
+}
+
+// Unsigned -> Unsigned
+test_impl_from! { test_u8u16, u8, u16 }
+test_impl_from! { test_u8u32, u8, u32 }
+test_impl_from! { test_u8u64, u8, u64 }
+test_impl_from! { test_u8usize, u8, usize }
+test_impl_from! { test_u16u32, u16, u32 }
+test_impl_from! { test_u16u64, u16, u64 }
+test_impl_from! { test_u32u64, u32, u64 }
+
+// Signed -> Signed
+test_impl_from! { test_i8i16, i8, i16 }
+test_impl_from! { test_i8i32, i8, i32 }
+test_impl_from! { test_i8i64, i8, i64 }
+test_impl_from! { test_i8isize, i8, isize }
+test_impl_from! { test_i16i32, i16, i32 }
+test_impl_from! { test_i16i64, i16, i64 }
+test_impl_from! { test_i32i64, i32, i64 }
+
+// Unsigned -> Signed
+test_impl_from! { test_u8i16, u8, i16 }
+test_impl_from! { test_u8i32, u8, i32 }
+test_impl_from! { test_u8i64, u8, i64 }
+test_impl_from! { test_u16i32, u16, i32 }
+test_impl_from! { test_u16i64, u16, i64 }
+test_impl_from! { test_u32i64, u32, i64 }
+
+// Signed -> Float
+test_impl_from! { test_i8f32, i8, f32 }
+test_impl_from! { test_i8f64, i8, f64 }
+test_impl_from! { test_i16f32, i16, f32 }
+test_impl_from! { test_i16f64, i16, f64 }
+test_impl_from! { test_i32f64, i32, f64 }
+
+// Unsigned -> Float
+test_impl_from! { test_u8f32, u8, f32 }
+test_impl_from! { test_u8f64, u8, f64 }
+test_impl_from! { test_u16f32, u16, f32 }
+test_impl_from! { test_u16f64, u16, f64 }
+test_impl_from! { test_u32f64, u32, f64 }
+
+// Float -> Float
+#[test]
+fn test_f32f64() {
+    use core::f32;
+
+    let max: f64 = f32::MAX.into();
+    assert_eq!(max as f32, f32::MAX);
+    assert!(max.is_normal());
+
+    let min: f64 = f32::MIN.into();
+    assert_eq!(min as f32, f32::MIN);
+    assert!(min.is_normal());
+
+    let min_positive: f64 = f32::MIN_POSITIVE.into();
+    assert_eq!(min_positive as f32, f32::MIN_POSITIVE);
+    assert!(min_positive.is_normal());
+
+    let epsilon: f64 = f32::EPSILON.into();
+    assert_eq!(epsilon as f32, f32::EPSILON);
+    assert!(epsilon.is_normal());
+
+    let zero: f64 = (0.0f32).into();
+    assert_eq!(zero as f32, 0.0f32);
+    assert!(zero.is_sign_positive());
+
+    let neg_zero: f64 = (-0.0f32).into();
+    assert_eq!(neg_zero as f32, -0.0f32);
+    assert!(neg_zero.is_sign_negative());
+
+    let infinity: f64 = f32::INFINITY.into();
+    assert_eq!(infinity as f32, f32::INFINITY);
+    assert!(infinity.is_infinite());
+    assert!(infinity.is_sign_positive());
+
+    let neg_infinity: f64 = f32::NEG_INFINITY.into();
+    assert_eq!(neg_infinity as f32, f32::NEG_INFINITY);
+    assert!(neg_infinity.is_infinite());
+    assert!(neg_infinity.is_sign_negative());
+
+    let nan: f64 = f32::NAN.into();
+    assert!(nan.is_nan());
+}
+
+macro_rules! test_impl_try_from_always_ok {
+    ($fn_name:ident, $source:ty, $target: ty) => {
+        #[test]
+        fn $fn_name() {
+            let max = <$source>::max_value();
+            let min = <$source>::min_value();
+            let zero: $source = 0;
+            assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(),
+                       max as $target);
+            assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(),
+                       min as $target);
+            assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
+                       zero as $target);
+        }
+    }
+}
+
+test_impl_try_from_always_ok! { test_try_u8u8, u8, u8 }
+test_impl_try_from_always_ok! { test_try_u8u16, u8, u16 }
+test_impl_try_from_always_ok! { test_try_u8u32, u8, u32 }
+test_impl_try_from_always_ok! { test_try_u8u64, u8, u64 }
+test_impl_try_from_always_ok! { test_try_u8i16, u8, i16 }
+test_impl_try_from_always_ok! { test_try_u8i32, u8, i32 }
+test_impl_try_from_always_ok! { test_try_u8i64, u8, i64 }
+
+test_impl_try_from_always_ok! { test_try_u16u16, u16, u16 }
+test_impl_try_from_always_ok! { test_try_u16u32, u16, u32 }
+test_impl_try_from_always_ok! { test_try_u16u64, u16, u64 }
+test_impl_try_from_always_ok! { test_try_u16i32, u16, i32 }
+test_impl_try_from_always_ok! { test_try_u16i64, u16, i64 }
+
+test_impl_try_from_always_ok! { test_try_u32u32, u32, u32 }
+test_impl_try_from_always_ok! { test_try_u32u64, u32, u64 }
+test_impl_try_from_always_ok! { test_try_u32i64, u32, i64 }
+
+test_impl_try_from_always_ok! { test_try_u64u64, u64, u64 }
+
+test_impl_try_from_always_ok! { test_try_i8i8, i8, i8 }
+test_impl_try_from_always_ok! { test_try_i8i16, i8, i16 }
+test_impl_try_from_always_ok! { test_try_i8i32, i8, i32 }
+test_impl_try_from_always_ok! { test_try_i8i64, i8, i64 }
+
+test_impl_try_from_always_ok! { test_try_i16i16, i16, i16 }
+test_impl_try_from_always_ok! { test_try_i16i32, i16, i32 }
+test_impl_try_from_always_ok! { test_try_i16i64, i16, i64 }
+
+test_impl_try_from_always_ok! { test_try_i32i32, i32, i32 }
+test_impl_try_from_always_ok! { test_try_i32i64, i32, i64 }
+
+test_impl_try_from_always_ok! { test_try_i64i64, i64, i64 }
+
+macro_rules! test_impl_try_from_signed_to_unsigned_upper_ok {
+    ($fn_name:ident, $source:ty, $target:ty) => {
+        #[test]
+        fn $fn_name() {
+            let max = <$source>::max_value();
+            let min = <$source>::min_value();
+            let zero: $source = 0;
+            let neg_one: $source = -1;
+            assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(),
+                       max as $target);
+            assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
+            assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
+                       zero as $target);
+            assert!(<$target as TryFrom<$source>>::try_from(neg_one).is_err());
+        }
+    }
+}
+
+test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u8, i8, u8 }
+test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u16, i8, u16 }
+test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u32, i8, u32 }
+test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u64, i8, u64 }
+
+test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u16, i16, u16 }
+test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u32, i16, u32 }
+test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u64, i16, u64 }
+
+test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u32, i32, u32 }
+test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u64, i32, u64 }
+
+test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64u64, i64, u64 }
+
+macro_rules! test_impl_try_from_unsigned_to_signed_upper_err {
+    ($fn_name:ident, $source:ty, $target:ty) => {
+        #[test]
+        fn $fn_name() {
+            let max = <$source>::max_value();
+            let min = <$source>::min_value();
+            let zero: $source = 0;
+            assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
+            assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(),
+                       min as $target);
+            assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
+                       zero as $target);
+        }
+    }
+}
+
+test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u8i8, u8, i8 }
+
+test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16i8, u16, i8 }
+test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16i16, u16, i16 }
+
+test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i8, u32, i8 }
+test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i16, u32, i16 }
+test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i32, u32, i32 }
+
+test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i8, u64, i8 }
+test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i16, u64, i16 }
+test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i32, u64, i32 }
+test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i64, u64, i64 }
+
+macro_rules! test_impl_try_from_same_sign_err {
+    ($fn_name:ident, $source:ty, $target:ty) => {
+        #[test]
+        fn $fn_name() {
+            let max = <$source>::max_value();
+            let min = <$source>::min_value();
+            let zero: $source = 0;
+            let t_max = <$target>::max_value();
+            let t_min = <$target>::min_value();
+            assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
+            if min != 0 {
+                assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
+            }
+            assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
+                       zero as $target);
+            assert_eq!(<$target as TryFrom<$source>>::try_from(t_max as $source)
+                            .unwrap(),
+                       t_max as $target);
+            assert_eq!(<$target as TryFrom<$source>>::try_from(t_min as $source)
+                            .unwrap(),
+                       t_min as $target);
+        }
+    }
+}
+
+test_impl_try_from_same_sign_err! { test_try_u16u8, u16, u8 }
+
+test_impl_try_from_same_sign_err! { test_try_u32u8, u32, u8 }
+test_impl_try_from_same_sign_err! { test_try_u32u16, u32, u16 }
+
+test_impl_try_from_same_sign_err! { test_try_u64u8, u64, u8 }
+test_impl_try_from_same_sign_err! { test_try_u64u16, u64, u16 }
+test_impl_try_from_same_sign_err! { test_try_u64u32, u64, u32 }
+
+test_impl_try_from_same_sign_err! { test_try_i16i8, i16, i8 }
+
+test_impl_try_from_same_sign_err! { test_try_i32i8, i32, i8 }
+test_impl_try_from_same_sign_err! { test_try_i32i16, i32, i16 }
+
+test_impl_try_from_same_sign_err! { test_try_i64i8, i64, i8 }
+test_impl_try_from_same_sign_err! { test_try_i64i16, i64, i16 }
+test_impl_try_from_same_sign_err! { test_try_i64i32, i64, i32 }
+
+macro_rules! test_impl_try_from_signed_to_unsigned_err {
+    ($fn_name:ident, $source:ty, $target:ty) => {
+        #[test]
+        fn $fn_name() {
+            let max = <$source>::max_value();
+            let min = <$source>::min_value();
+            let zero: $source = 0;
+            let t_max = <$target>::max_value();
+            let t_min = <$target>::min_value();
+            assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
+            assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
+            assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
+                       zero as $target);
+            assert_eq!(<$target as TryFrom<$source>>::try_from(t_max as $source)
+                            .unwrap(),
+                       t_max as $target);
+            assert_eq!(<$target as TryFrom<$source>>::try_from(t_min as $source)
+                            .unwrap(),
+                       t_min as $target);
+        }
+    }
+}
+
+test_impl_try_from_signed_to_unsigned_err! { test_try_i16u8, i16, u8 }
+
+test_impl_try_from_signed_to_unsigned_err! { test_try_i32u8, i32, u8 }
+test_impl_try_from_signed_to_unsigned_err! { test_try_i32u16, i32, u16 }
+
+test_impl_try_from_signed_to_unsigned_err! { test_try_i64u8, i64, u8 }
+test_impl_try_from_signed_to_unsigned_err! { test_try_i64u16, i64, u16 }
+test_impl_try_from_signed_to_unsigned_err! { test_try_i64u32, i64, u32 }
diff --git a/src/libcore/tests/num/u16.rs b/src/libcore/tests/num/u16.rs
new file mode 100644 (file)
index 0000000..8455207
--- /dev/null
@@ -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.
+
+uint_module!(u16, u16);
diff --git a/src/libcore/tests/num/u32.rs b/src/libcore/tests/num/u32.rs
new file mode 100644 (file)
index 0000000..b44e60f
--- /dev/null
@@ -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.
+
+uint_module!(u32, u32);
diff --git a/src/libcore/tests/num/u64.rs b/src/libcore/tests/num/u64.rs
new file mode 100644 (file)
index 0000000..ffcd101
--- /dev/null
@@ -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.
+
+uint_module!(u64, u64);
diff --git a/src/libcore/tests/num/u8.rs b/src/libcore/tests/num/u8.rs
new file mode 100644 (file)
index 0000000..4ee14e2
--- /dev/null
@@ -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.
+
+uint_module!(u8, u8);
diff --git a/src/libcore/tests/num/uint_macros.rs b/src/libcore/tests/num/uint_macros.rs
new file mode 100644 (file)
index 0000000..daa1cc3
--- /dev/null
@@ -0,0 +1,158 @@
+// 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.
+
+macro_rules! uint_module { ($T:ident, $T_i:ident) => (
+#[cfg(test)]
+mod tests {
+    use core::$T_i::*;
+    use num;
+    use core::ops::{BitOr, BitAnd, BitXor, Shl, Shr, Not};
+    use std::str::FromStr;
+    use std::mem;
+
+    #[test]
+    fn test_overflows() {
+        assert!(MAX > 0);
+        assert!(MIN <= 0);
+        assert!((MIN + MAX).wrapping_add(1) == 0);
+    }
+
+    #[test]
+    fn test_num() {
+        num::test_num(10 as $T, 2 as $T);
+    }
+
+    #[test]
+    fn test_bitwise_operators() {
+        assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T));
+        assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T));
+        assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T));
+        assert!(0b1110 as $T == (0b0111 as $T).shl(1));
+        assert!(0b0111 as $T == (0b1110 as $T).shr(1));
+        assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
+    }
+
+    const A: $T = 0b0101100;
+    const B: $T = 0b0100001;
+    const C: $T = 0b1111001;
+
+    const _0: $T = 0;
+    const _1: $T = !0;
+
+    #[test]
+    fn test_count_ones() {
+        assert!(A.count_ones() == 3);
+        assert!(B.count_ones() == 2);
+        assert!(C.count_ones() == 5);
+    }
+
+    #[test]
+    fn test_count_zeros() {
+        let bits = mem::size_of::<$T>() * 8;
+        assert!(A.count_zeros() == bits as u32 - 3);
+        assert!(B.count_zeros() == bits as u32 - 2);
+        assert!(C.count_zeros() == bits as u32 - 5);
+    }
+
+    #[test]
+    fn test_rotate() {
+        assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
+        assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
+        assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
+
+        // Rotating these should make no difference
+        //
+        // We test using 124 bits because to ensure that overlong bit shifts do
+        // not cause undefined behaviour. See #10183.
+        assert_eq!(_0.rotate_left(124), _0);
+        assert_eq!(_1.rotate_left(124), _1);
+        assert_eq!(_0.rotate_right(124), _0);
+        assert_eq!(_1.rotate_right(124), _1);
+
+        // Rotating by 0 should have no effect
+        assert_eq!(A.rotate_left(0), A);
+        assert_eq!(B.rotate_left(0), B);
+        assert_eq!(C.rotate_left(0), C);
+        // Rotating by a multiple of word size should also have no effect
+        assert_eq!(A.rotate_left(64), A);
+        assert_eq!(B.rotate_left(64), B);
+        assert_eq!(C.rotate_left(64), C);
+    }
+
+    #[test]
+    fn test_swap_bytes() {
+        assert_eq!(A.swap_bytes().swap_bytes(), A);
+        assert_eq!(B.swap_bytes().swap_bytes(), B);
+        assert_eq!(C.swap_bytes().swap_bytes(), C);
+
+        // Swapping these should make no difference
+        assert_eq!(_0.swap_bytes(), _0);
+        assert_eq!(_1.swap_bytes(), _1);
+    }
+
+    #[test]
+    fn test_le() {
+        assert_eq!($T::from_le(A.to_le()), A);
+        assert_eq!($T::from_le(B.to_le()), B);
+        assert_eq!($T::from_le(C.to_le()), C);
+        assert_eq!($T::from_le(_0), _0);
+        assert_eq!($T::from_le(_1), _1);
+        assert_eq!(_0.to_le(), _0);
+        assert_eq!(_1.to_le(), _1);
+    }
+
+    #[test]
+    fn test_be() {
+        assert_eq!($T::from_be(A.to_be()), A);
+        assert_eq!($T::from_be(B.to_be()), B);
+        assert_eq!($T::from_be(C.to_be()), C);
+        assert_eq!($T::from_be(_0), _0);
+        assert_eq!($T::from_be(_1), _1);
+        assert_eq!(_0.to_be(), _0);
+        assert_eq!(_1.to_be(), _1);
+    }
+
+    #[test]
+    fn test_unsigned_checked_div() {
+        assert!((10 as $T).checked_div(2) == Some(5));
+        assert!((5 as $T).checked_div(0) == None);
+    }
+
+    fn from_str<T: FromStr>(t: &str) -> Option<T> {
+        FromStr::from_str(t).ok()
+    }
+
+    #[test]
+    pub fn test_from_str() {
+        assert_eq!(from_str::<$T>("0"), Some(0 as $T));
+        assert_eq!(from_str::<$T>("3"), Some(3 as $T));
+        assert_eq!(from_str::<$T>("10"), Some(10 as $T));
+        assert_eq!(from_str::<u32>("123456789"), Some(123456789 as u32));
+        assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
+
+        assert_eq!(from_str::<$T>(""), None);
+        assert_eq!(from_str::<$T>(" "), None);
+        assert_eq!(from_str::<$T>("x"), None);
+    }
+
+    #[test]
+    pub fn test_parse_bytes() {
+        assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
+        assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
+        assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
+        assert_eq!(u16::from_str_radix("123", 16), Ok(291 as u16));
+        assert_eq!(u16::from_str_radix("ffff", 16), Ok(65535 as u16));
+        assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
+
+        assert_eq!($T::from_str_radix("Z", 10).ok(), None::<$T>);
+        assert_eq!($T::from_str_radix("_", 2).ok(), None::<$T>);
+    }
+}
+)}
diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs
new file mode 100644 (file)
index 0000000..1c6c13b
--- /dev/null
@@ -0,0 +1,49 @@
+// 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 core::ops::{Range, RangeFull, RangeFrom, RangeTo};
+
+// Test the Range structs without the syntactic sugar.
+
+#[test]
+fn test_range() {
+    let r = Range { start: 2, end: 10 };
+    let mut count = 0;
+    for (i, ri) in r.enumerate() {
+        assert!(ri == i + 2);
+        assert!(ri >= 2 && ri < 10);
+        count += 1;
+    }
+    assert!(count == 8);
+}
+
+#[test]
+fn test_range_from() {
+    let r = RangeFrom { start: 2 };
+    let mut count = 0;
+    for (i, ri) in r.take(10).enumerate() {
+        assert!(ri == i + 2);
+        assert!(ri >= 2 && ri < 12);
+        count += 1;
+    }
+    assert!(count == 10);
+}
+
+#[test]
+fn test_range_to() {
+    // Not much to test.
+    let _ = RangeTo { end: 42 };
+}
+
+#[test]
+fn test_full_range() {
+    // Not much to test.
+    let _ = RangeFull;
+}
diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs
new file mode 100644 (file)
index 0000000..51b0655
--- /dev/null
@@ -0,0 +1,272 @@
+// 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 core::option::*;
+use core::mem;
+use core::clone::Clone;
+
+#[test]
+fn test_get_ptr() {
+    unsafe {
+        let x: Box<_> = box 0;
+        let addr_x: *const isize = mem::transmute(&*x);
+        let opt = Some(x);
+        let y = opt.unwrap();
+        let addr_y: *const isize = mem::transmute(&*y);
+        assert_eq!(addr_x, addr_y);
+    }
+}
+
+#[test]
+fn test_get_str() {
+    let x = "test".to_string();
+    let addr_x = x.as_ptr();
+    let opt = Some(x);
+    let y = opt.unwrap();
+    let addr_y = y.as_ptr();
+    assert_eq!(addr_x, addr_y);
+}
+
+#[test]
+fn test_get_resource() {
+    use std::rc::Rc;
+    use core::cell::RefCell;
+
+    struct R {
+       i: Rc<RefCell<isize>>,
+    }
+
+        impl Drop for R {
+       fn drop(&mut self) {
+            let ii = &*self.i;
+            let i = *ii.borrow();
+            *ii.borrow_mut() = i + 1;
+        }
+    }
+
+    fn r(i: Rc<RefCell<isize>>) -> R {
+        R {
+            i: i
+        }
+    }
+
+    let i = Rc::new(RefCell::new(0));
+    {
+        let x = r(i.clone());
+        let opt = Some(x);
+        let _y = opt.unwrap();
+    }
+    assert_eq!(*i.borrow(), 1);
+}
+
+#[test]
+fn test_option_dance() {
+    let x = Some(());
+    let mut y = Some(5);
+    let mut y2 = 0;
+    for _x in x {
+        y2 = y.take().unwrap();
+    }
+    assert_eq!(y2, 5);
+    assert!(y.is_none());
+}
+
+#[test] #[should_panic]
+fn test_option_too_much_dance() {
+    struct A;
+    let mut y = Some(A);
+    let _y2 = y.take().unwrap();
+    let _y3 = y.take().unwrap();
+}
+
+#[test]
+fn test_and() {
+    let x: Option<isize> = Some(1);
+    assert_eq!(x.and(Some(2)), Some(2));
+    assert_eq!(x.and(None::<isize>), None);
+
+    let x: Option<isize> = None;
+    assert_eq!(x.and(Some(2)), None);
+    assert_eq!(x.and(None::<isize>), None);
+}
+
+#[test]
+fn test_and_then() {
+    let x: Option<isize> = Some(1);
+    assert_eq!(x.and_then(|x| Some(x + 1)), Some(2));
+    assert_eq!(x.and_then(|_| None::<isize>), None);
+
+    let x: Option<isize> = None;
+    assert_eq!(x.and_then(|x| Some(x + 1)), None);
+    assert_eq!(x.and_then(|_| None::<isize>), None);
+}
+
+#[test]
+fn test_or() {
+    let x: Option<isize> = Some(1);
+    assert_eq!(x.or(Some(2)), Some(1));
+    assert_eq!(x.or(None), Some(1));
+
+    let x: Option<isize> = None;
+    assert_eq!(x.or(Some(2)), Some(2));
+    assert_eq!(x.or(None), None);
+}
+
+#[test]
+fn test_or_else() {
+    let x: Option<isize> = Some(1);
+    assert_eq!(x.or_else(|| Some(2)), Some(1));
+    assert_eq!(x.or_else(|| None), Some(1));
+
+    let x: Option<isize> = None;
+    assert_eq!(x.or_else(|| Some(2)), Some(2));
+    assert_eq!(x.or_else(|| None), None);
+}
+
+#[test]
+fn test_unwrap() {
+    assert_eq!(Some(1).unwrap(), 1);
+    let s = Some("hello".to_string()).unwrap();
+    assert_eq!(s, "hello");
+}
+
+#[test]
+#[should_panic]
+fn test_unwrap_panic1() {
+    let x: Option<isize> = None;
+    x.unwrap();
+}
+
+#[test]
+#[should_panic]
+fn test_unwrap_panic2() {
+    let x: Option<String> = None;
+    x.unwrap();
+}
+
+#[test]
+fn test_unwrap_or() {
+    let x: Option<isize> = Some(1);
+    assert_eq!(x.unwrap_or(2), 1);
+
+    let x: Option<isize> = None;
+    assert_eq!(x.unwrap_or(2), 2);
+}
+
+#[test]
+fn test_unwrap_or_else() {
+    let x: Option<isize> = Some(1);
+    assert_eq!(x.unwrap_or_else(|| 2), 1);
+
+    let x: Option<isize> = None;
+    assert_eq!(x.unwrap_or_else(|| 2), 2);
+}
+
+#[test]
+fn test_iter() {
+    let val = 5;
+
+    let x = Some(val);
+    let mut it = x.iter();
+
+    assert_eq!(it.size_hint(), (1, Some(1)));
+    assert_eq!(it.next(), Some(&val));
+    assert_eq!(it.size_hint(), (0, Some(0)));
+    assert!(it.next().is_none());
+
+    let mut it = (&x).into_iter();
+    assert_eq!(it.next(), Some(&val));
+}
+
+#[test]
+fn test_mut_iter() {
+    let mut val = 5;
+    let new_val = 11;
+
+    let mut x = Some(val);
+    {
+        let mut it = x.iter_mut();
+
+        assert_eq!(it.size_hint(), (1, Some(1)));
+
+        match it.next() {
+            Some(interior) => {
+                assert_eq!(*interior, val);
+                *interior = new_val;
+            }
+            None => assert!(false),
+        }
+
+        assert_eq!(it.size_hint(), (0, Some(0)));
+        assert!(it.next().is_none());
+    }
+    assert_eq!(x, Some(new_val));
+
+    let mut y = Some(val);
+    let mut it = (&mut y).into_iter();
+    assert_eq!(it.next(), Some(&mut val));
+}
+
+#[test]
+fn test_ord() {
+    let small = Some(1.0f64);
+    let big = Some(5.0f64);
+    let nan = Some(0.0f64/0.0);
+    assert!(!(nan < big));
+    assert!(!(nan > big));
+    assert!(small < big);
+    assert!(None < big);
+    assert!(big > None);
+}
+
+#[test]
+fn test_collect() {
+    let v: Option<Vec<isize>> = (0..0).map(|_| Some(0)).collect();
+    assert!(v == Some(vec![]));
+
+    let v: Option<Vec<isize>> = (0..3).map(|x| Some(x)).collect();
+    assert!(v == Some(vec![0, 1, 2]));
+
+    let v: Option<Vec<isize>> = (0..3).map(|x| {
+        if x > 1 { None } else { Some(x) }
+    }).collect();
+    assert!(v == None);
+
+    // test that it does not take more elements than it needs
+    let mut functions: [Box<Fn() -> Option<()>>; 3] =
+        [box || Some(()), box || None, box || panic!()];
+
+    let v: Option<Vec<()>> = functions.iter_mut().map(|f| (*f)()).collect();
+
+    assert!(v == None);
+}
+
+
+#[test]
+fn test_cloned() {
+    let val = 1;
+    let val_ref = &val;
+    let opt_none: Option<&'static u32> = None;
+    let opt_ref = Some(&val);
+    let opt_ref_ref = Some(&val_ref);
+
+    // None works
+    assert_eq!(opt_none.clone(), None);
+    assert_eq!(opt_none.cloned(), None);
+
+    // Immutable ref works
+    assert_eq!(opt_ref.clone(), Some(&val));
+    assert_eq!(opt_ref.cloned(), Some(1));
+
+    // Double Immutable ref works
+    assert_eq!(opt_ref_ref.clone(), Some(&val_ref));
+    assert_eq!(opt_ref_ref.clone().cloned(), Some(&val));
+    assert_eq!(opt_ref_ref.cloned().cloned(), Some(1));
+}
diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs
new file mode 100644 (file)
index 0000000..7f6f472
--- /dev/null
@@ -0,0 +1,214 @@
+// 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 core::ptr::*;
+use core::cell::RefCell;
+
+#[test]
+fn test() {
+    unsafe {
+        struct Pair {
+            fst: isize,
+            snd: isize
+        };
+        let mut p = Pair {fst: 10, snd: 20};
+        let pptr: *mut Pair = &mut p;
+        let iptr: *mut isize = pptr as *mut isize;
+        assert_eq!(*iptr, 10);
+        *iptr = 30;
+        assert_eq!(*iptr, 30);
+        assert_eq!(p.fst, 30);
+
+        *pptr = Pair {fst: 50, snd: 60};
+        assert_eq!(*iptr, 50);
+        assert_eq!(p.fst, 50);
+        assert_eq!(p.snd, 60);
+
+        let v0 = vec![32000u16, 32001u16, 32002u16];
+        let mut v1 = vec![0u16, 0u16, 0u16];
+
+        copy(v0.as_ptr().offset(1), v1.as_mut_ptr().offset(1), 1);
+        assert!((v1[0] == 0u16 &&
+                 v1[1] == 32001u16 &&
+                 v1[2] == 0u16));
+        copy(v0.as_ptr().offset(2), v1.as_mut_ptr(), 1);
+        assert!((v1[0] == 32002u16 &&
+                 v1[1] == 32001u16 &&
+                 v1[2] == 0u16));
+        copy(v0.as_ptr(), v1.as_mut_ptr().offset(2), 1);
+        assert!((v1[0] == 32002u16 &&
+                 v1[1] == 32001u16 &&
+                 v1[2] == 32000u16));
+    }
+}
+
+#[test]
+fn test_is_null() {
+    let p: *const isize = null();
+    assert!(p.is_null());
+
+    let q = unsafe { p.offset(1) };
+    assert!(!q.is_null());
+
+    let mp: *mut isize = null_mut();
+    assert!(mp.is_null());
+
+    let mq = unsafe { mp.offset(1) };
+    assert!(!mq.is_null());
+}
+
+#[test]
+fn test_as_ref() {
+    unsafe {
+        let p: *const isize = null();
+        assert_eq!(p.as_ref(), None);
+
+        let q: *const isize = &2;
+        assert_eq!(q.as_ref().unwrap(), &2);
+
+        let p: *mut isize = null_mut();
+        assert_eq!(p.as_ref(), None);
+
+        let q: *mut isize = &mut 2;
+        assert_eq!(q.as_ref().unwrap(), &2);
+
+        // Lifetime inference
+        let u = 2isize;
+        {
+            let p = &u as *const isize;
+            assert_eq!(p.as_ref().unwrap(), &2);
+        }
+    }
+}
+
+#[test]
+fn test_as_mut() {
+    unsafe {
+        let p: *mut isize = null_mut();
+        assert!(p.as_mut() == None);
+
+        let q: *mut isize = &mut 2;
+        assert!(q.as_mut().unwrap() == &mut 2);
+
+        // Lifetime inference
+        let mut u = 2isize;
+        {
+            let p = &mut u as *mut isize;
+            assert!(p.as_mut().unwrap() == &mut 2);
+        }
+    }
+}
+
+#[test]
+fn test_ptr_addition() {
+    unsafe {
+        let xs = vec![5; 16];
+        let mut ptr = xs.as_ptr();
+        let end = ptr.offset(16);
+
+        while ptr < end {
+            assert_eq!(*ptr, 5);
+            ptr = ptr.offset(1);
+        }
+
+        let mut xs_mut = xs;
+        let mut m_ptr = xs_mut.as_mut_ptr();
+        let m_end = m_ptr.offset(16);
+
+        while m_ptr < m_end {
+            *m_ptr += 5;
+            m_ptr = m_ptr.offset(1);
+        }
+
+        assert!(xs_mut == vec![10; 16]);
+    }
+}
+
+#[test]
+fn test_ptr_subtraction() {
+    unsafe {
+        let xs = vec![0,1,2,3,4,5,6,7,8,9];
+        let mut idx = 9;
+        let ptr = xs.as_ptr();
+
+        while idx >= 0 {
+            assert_eq!(*(ptr.offset(idx as isize)), idx as isize);
+            idx = idx - 1;
+        }
+
+        let mut xs_mut = xs;
+        let m_start = xs_mut.as_mut_ptr();
+        let mut m_ptr = m_start.offset(9);
+
+        while m_ptr >= m_start {
+            *m_ptr += *m_ptr;
+            m_ptr = m_ptr.offset(-1);
+        }
+
+        assert_eq!(xs_mut, [0,2,4,6,8,10,12,14,16,18]);
+    }
+}
+
+#[test]
+fn test_set_memory() {
+    let mut xs = [0u8; 20];
+    let ptr = xs.as_mut_ptr();
+    unsafe { write_bytes(ptr, 5u8, xs.len()); }
+    assert!(xs == [5u8; 20]);
+}
+
+#[test]
+fn test_unsized_unique() {
+    let xs: &mut [i32] = &mut [1, 2, 3];
+    let ptr = unsafe { Unique::new(xs as *mut [i32]) };
+    let ys = unsafe { &mut **ptr };
+    let zs: &mut [i32] = &mut [1, 2, 3];
+    assert!(ys == zs);
+}
+
+#[test]
+#[allow(warnings)]
+// Have a symbol for the test below. It doesn’t need to be an actual variadic function, match the
+// ABI, or even point to an actual executable code, because the function itself is never invoked.
+#[no_mangle]
+pub fn test_variadic_fnptr() {
+    use core::hash::{Hash, SipHasher};
+    extern {
+        fn test_variadic_fnptr(_: u64, ...) -> f64;
+    }
+    let p: unsafe extern fn(u64, ...) -> f64 = test_variadic_fnptr;
+    let q = p.clone();
+    assert_eq!(p, q);
+    assert!(!(p < q));
+    let mut s = SipHasher::new();
+    assert_eq!(p.hash(&mut s), q.hash(&mut s));
+}
+
+#[test]
+fn write_unaligned_drop() {
+    thread_local! {
+        static DROPS: RefCell<Vec<u32>> = RefCell::new(Vec::new());
+    }
+
+    struct Dropper(u32);
+
+    impl Drop for Dropper {
+        fn drop(&mut self) {
+            DROPS.with(|d| d.borrow_mut().push(self.0));
+        }
+    }
+
+    {
+        let c = Dropper(0);
+        let mut t = Dropper(1);
+        unsafe { write_unaligned(&mut t, c); }
+    }
+    DROPS.with(|d| assert_eq!(*d.borrow(), [0]));
+}
diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs
new file mode 100644 (file)
index 0000000..4c5f19d
--- /dev/null
@@ -0,0 +1,204 @@
+// 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.
+
+fn op1() -> Result<isize, &'static str> { Ok(666) }
+fn op2() -> Result<isize, &'static str> { Err("sadface") }
+
+#[test]
+fn test_and() {
+    assert_eq!(op1().and(Ok(667)).unwrap(), 667);
+    assert_eq!(op1().and(Err::<i32, &'static str>("bad")).unwrap_err(),
+               "bad");
+
+    assert_eq!(op2().and(Ok(667)).unwrap_err(), "sadface");
+    assert_eq!(op2().and(Err::<i32,&'static str>("bad")).unwrap_err(),
+               "sadface");
+}
+
+#[test]
+fn test_and_then() {
+    assert_eq!(op1().and_then(|i| Ok::<isize, &'static str>(i + 1)).unwrap(), 667);
+    assert_eq!(op1().and_then(|_| Err::<isize, &'static str>("bad")).unwrap_err(),
+               "bad");
+
+    assert_eq!(op2().and_then(|i| Ok::<isize, &'static str>(i + 1)).unwrap_err(),
+               "sadface");
+    assert_eq!(op2().and_then(|_| Err::<isize, &'static str>("bad")).unwrap_err(),
+               "sadface");
+}
+
+#[test]
+fn test_or() {
+    assert_eq!(op1().or(Ok::<_, &'static str>(667)).unwrap(), 666);
+    assert_eq!(op1().or(Err("bad")).unwrap(), 666);
+
+    assert_eq!(op2().or(Ok::<_, &'static str>(667)).unwrap(), 667);
+    assert_eq!(op2().or(Err("bad")).unwrap_err(), "bad");
+}
+
+#[test]
+fn test_or_else() {
+    assert_eq!(op1().or_else(|_| Ok::<isize, &'static str>(667)).unwrap(), 666);
+    assert_eq!(op1().or_else(|e| Err::<isize, &'static str>(e)).unwrap(), 666);
+
+    assert_eq!(op2().or_else(|_| Ok::<isize, &'static str>(667)).unwrap(), 667);
+    assert_eq!(op2().or_else(|e| Err::<isize, &'static str>(e)).unwrap_err(),
+               "sadface");
+}
+
+#[test]
+fn test_impl_map() {
+    assert!(Ok::<isize, isize>(1).map(|x| x + 1) == Ok(2));
+    assert!(Err::<isize, isize>(1).map(|x| x + 1) == Err(1));
+}
+
+#[test]
+fn test_impl_map_err() {
+    assert!(Ok::<isize, isize>(1).map_err(|x| x + 1) == Ok(1));
+    assert!(Err::<isize, isize>(1).map_err(|x| x + 1) == Err(2));
+}
+
+#[test]
+fn test_collect() {
+    let v: Result<Vec<isize>, ()> = (0..0).map(|_| Ok::<isize, ()>(0)).collect();
+    assert!(v == Ok(vec![]));
+
+    let v: Result<Vec<isize>, ()> = (0..3).map(|x| Ok::<isize, ()>(x)).collect();
+    assert!(v == Ok(vec![0, 1, 2]));
+
+    let v: Result<Vec<isize>, isize> = (0..3).map(|x| {
+        if x > 1 { Err(x) } else { Ok(x) }
+    }).collect();
+    assert!(v == Err(2));
+
+    // test that it does not take more elements than it needs
+    let mut functions: [Box<Fn() -> Result<(), isize>>; 3] =
+        [box || Ok(()), box || Err(1), box || panic!()];
+
+    let v: Result<Vec<()>, isize> = functions.iter_mut().map(|f| (*f)()).collect();
+    assert!(v == Err(1));
+}
+
+#[test]
+fn test_fmt_default() {
+    let ok: Result<isize, &'static str> = Ok(100);
+    let err: Result<isize, &'static str> = Err("Err");
+
+    let s = format!("{:?}", ok);
+    assert_eq!(s, "Ok(100)");
+    let s = format!("{:?}", err);
+    assert_eq!(s, "Err(\"Err\")");
+}
+
+#[test]
+fn test_unwrap_or() {
+    let ok: Result<isize, &'static str> = Ok(100);
+    let ok_err: Result<isize, &'static str> = Err("Err");
+
+    assert_eq!(ok.unwrap_or(50), 100);
+    assert_eq!(ok_err.unwrap_or(50), 50);
+}
+
+#[test]
+fn test_unwrap_or_else() {
+    fn handler(msg: &'static str) -> isize {
+        if msg == "I got this." {
+            50
+        } else {
+            panic!("BadBad")
+        }
+    }
+
+    let ok: Result<isize, &'static str> = Ok(100);
+    let ok_err: Result<isize, &'static str> = Err("I got this.");
+
+    assert_eq!(ok.unwrap_or_else(handler), 100);
+    assert_eq!(ok_err.unwrap_or_else(handler), 50);
+}
+
+#[test]
+#[should_panic]
+pub fn test_unwrap_or_else_panic() {
+    fn handler(msg: &'static str) -> isize {
+        if msg == "I got this." {
+            50
+        } else {
+            panic!("BadBad")
+        }
+    }
+
+    let bad_err: Result<isize, &'static str> = Err("Unrecoverable mess.");
+    let _ : isize = bad_err.unwrap_or_else(handler);
+}
+
+
+#[test]
+pub fn test_expect_ok() {
+    let ok: Result<isize, &'static str> = Ok(100);
+    assert_eq!(ok.expect("Unexpected error"), 100);
+}
+#[test]
+#[should_panic(expected="Got expected error: \"All good\"")]
+pub fn test_expect_err() {
+    let err: Result<isize, &'static str> = Err("All good");
+    err.expect("Got expected error");
+}
+
+
+#[test]
+pub fn test_expect_err_err() {
+    let ok: Result<&'static str, isize> = Err(100);
+    assert_eq!(ok.expect_err("Unexpected ok"), 100);
+}
+#[test]
+#[should_panic(expected="Got expected ok: \"All good\"")]
+pub fn test_expect_err_ok() {
+    let err: Result<&'static str, isize> = Ok("All good");
+    err.expect_err("Got expected ok");
+}
+
+#[test]
+pub fn test_iter() {
+    let ok: Result<isize, &'static str> = Ok(100);
+    let mut it = ok.iter();
+    assert_eq!(it.size_hint(), (1, Some(1)));
+    assert_eq!(it.next(), Some(&100));
+    assert_eq!(it.size_hint(), (0, Some(0)));
+    assert!(it.next().is_none());
+    assert_eq!((&ok).into_iter().next(), Some(&100));
+
+    let err: Result<isize, &'static str> = Err("error");
+    assert_eq!(err.iter().next(), None);
+}
+
+#[test]
+pub fn test_iter_mut() {
+    let mut ok: Result<isize, &'static str> = Ok(100);
+    for loc in ok.iter_mut() {
+        *loc = 200;
+    }
+    assert_eq!(ok, Ok(200));
+    for loc in &mut ok {
+        *loc = 300;
+    }
+    assert_eq!(ok, Ok(300));
+
+    let mut err: Result<isize, &'static str> = Err("error");
+    for loc in err.iter_mut() {
+        *loc = 200;
+    }
+    assert_eq!(err, Err("error"));
+}
+
+#[test]
+pub fn test_unwrap_or_default() {
+    assert_eq!(op1().unwrap_or_default(), 666);
+    assert_eq!(op2().unwrap_or_default(), 0);
+}
diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs
new file mode 100644 (file)
index 0000000..ec38345
--- /dev/null
@@ -0,0 +1,291 @@
+// 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 core::cmp::Ordering::{Equal, Greater, Less};
+use core::slice::heapsort;
+use core::result::Result::{Ok, Err};
+use rand::{Rng, XorShiftRng};
+
+#[test]
+fn test_binary_search() {
+    let b = [1, 2, 4, 6, 8, 9];
+    assert!(b.binary_search_by(|v| v.cmp(&6)) == Ok(3));
+    assert!(b.binary_search_by(|v| v.cmp(&5)) == Err(3));
+    let b = [1, 2, 4, 6, 7, 8, 9];
+    assert!(b.binary_search_by(|v| v.cmp(&6)) == Ok(3));
+    assert!(b.binary_search_by(|v| v.cmp(&5)) == Err(3));
+    let b = [1, 2, 4, 6, 8, 9];
+    assert!(b.binary_search_by(|v| v.cmp(&8)) == Ok(4));
+    assert!(b.binary_search_by(|v| v.cmp(&7)) == Err(4));
+    let b = [1, 2, 4, 6, 7, 8, 9];
+    assert!(b.binary_search_by(|v| v.cmp(&8)) == Ok(5));
+    let b = [1, 2, 4, 5, 6, 8, 9];
+    assert!(b.binary_search_by(|v| v.cmp(&7)) == Err(5));
+    assert!(b.binary_search_by(|v| v.cmp(&0)) == Err(0));
+    let b = [1, 2, 4, 5, 6, 8];
+    assert!(b.binary_search_by(|v| v.cmp(&9)) == Err(6));
+}
+
+#[test]
+fn test_iterator_nth() {
+    let v: &[_] = &[0, 1, 2, 3, 4];
+    for i in 0..v.len() {
+        assert_eq!(v.iter().nth(i).unwrap(), &v[i]);
+    }
+    assert_eq!(v.iter().nth(v.len()), None);
+
+    let mut iter = v.iter();
+    assert_eq!(iter.nth(2).unwrap(), &v[2]);
+    assert_eq!(iter.nth(1).unwrap(), &v[4]);
+}
+
+#[test]
+fn test_iterator_last() {
+    let v: &[_] = &[0, 1, 2, 3, 4];
+    assert_eq!(v.iter().last().unwrap(), &4);
+    assert_eq!(v[..1].iter().last().unwrap(), &0);
+}
+
+#[test]
+fn test_iterator_count() {
+    let v: &[_] = &[0, 1, 2, 3, 4];
+    assert_eq!(v.iter().count(), 5);
+
+    let mut iter2 = v.iter();
+    iter2.next();
+    iter2.next();
+    assert_eq!(iter2.count(), 3);
+}
+
+#[test]
+fn test_chunks_count() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+    let c = v.chunks(3);
+    assert_eq!(c.count(), 2);
+
+    let v2: &[i32] = &[0, 1, 2, 3, 4];
+    let c2 = v2.chunks(2);
+    assert_eq!(c2.count(), 3);
+
+    let v3: &[i32] = &[];
+    let c3 = v3.chunks(2);
+    assert_eq!(c3.count(), 0);
+}
+
+#[test]
+fn test_chunks_nth() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+    let mut c = v.chunks(2);
+    assert_eq!(c.nth(1).unwrap()[1], 3);
+    assert_eq!(c.next().unwrap()[0], 4);
+
+    let v2: &[i32] = &[0, 1, 2, 3, 4];
+    let mut c2 = v2.chunks(3);
+    assert_eq!(c2.nth(1).unwrap()[1], 4);
+    assert_eq!(c2.next(), None);
+}
+
+#[test]
+fn test_chunks_last() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+    let c = v.chunks(2);
+    assert_eq!(c.last().unwrap()[1], 5);
+
+    let v2: &[i32] = &[0, 1, 2, 3, 4];
+    let c2 = v2.chunks(2);
+    assert_eq!(c2.last().unwrap()[0], 4);
+}
+
+#[test]
+fn test_chunks_mut_count() {
+    let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+    let c = v.chunks_mut(3);
+    assert_eq!(c.count(), 2);
+
+    let mut v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
+    let c2 = v2.chunks_mut(2);
+    assert_eq!(c2.count(), 3);
+
+    let mut v3: &mut [i32] = &mut [];
+    let c3 = v3.chunks_mut(2);
+    assert_eq!(c3.count(), 0);
+}
+
+#[test]
+fn test_chunks_mut_nth() {
+    let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+    let mut c = v.chunks_mut(2);
+    assert_eq!(c.nth(1).unwrap()[1], 3);
+    assert_eq!(c.next().unwrap()[0], 4);
+
+    let mut v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
+    let mut c2 = v2.chunks_mut(3);
+    assert_eq!(c2.nth(1).unwrap()[1], 4);
+    assert_eq!(c2.next(), None);
+}
+
+#[test]
+fn test_chunks_mut_last() {
+    let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+    let c = v.chunks_mut(2);
+    assert_eq!(c.last().unwrap()[1], 5);
+
+    let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
+    let c2 = v2.chunks_mut(2);
+    assert_eq!(c2.last().unwrap()[0], 4);
+}
+
+#[test]
+fn test_windows_count() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+    let c = v.windows(3);
+    assert_eq!(c.count(), 4);
+
+    let v2: &[i32] = &[0, 1, 2, 3, 4];
+    let c2 = v2.windows(6);
+    assert_eq!(c2.count(), 0);
+
+    let v3: &[i32] = &[];
+    let c3 = v3.windows(2);
+    assert_eq!(c3.count(), 0);
+}
+
+#[test]
+fn test_windows_nth() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+    let mut c = v.windows(2);
+    assert_eq!(c.nth(2).unwrap()[1], 3);
+    assert_eq!(c.next().unwrap()[0], 3);
+
+    let v2: &[i32] = &[0, 1, 2, 3, 4];
+    let mut c2 = v2.windows(4);
+    assert_eq!(c2.nth(1).unwrap()[1], 2);
+    assert_eq!(c2.next(), None);
+}
+
+#[test]
+fn test_windows_last() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+    let c = v.windows(2);
+    assert_eq!(c.last().unwrap()[1], 5);
+
+    let v2: &[i32] = &[0, 1, 2, 3, 4];
+    let c2 = v2.windows(2);
+    assert_eq!(c2.last().unwrap()[0], 3);
+}
+
+#[test]
+fn get_range() {
+    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+    assert_eq!(v.get(..), Some(&[0, 1, 2, 3, 4, 5][..]));
+    assert_eq!(v.get(..2), Some(&[0, 1][..]));
+    assert_eq!(v.get(2..), Some(&[2, 3, 4, 5][..]));
+    assert_eq!(v.get(1..4), Some(&[1, 2, 3][..]));
+    assert_eq!(v.get(7..), None);
+    assert_eq!(v.get(7..10), None);
+}
+
+#[test]
+fn get_mut_range() {
+    let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+    assert_eq!(v.get_mut(..), Some(&mut [0, 1, 2, 3, 4, 5][..]));
+    assert_eq!(v.get_mut(..2), Some(&mut [0, 1][..]));
+    assert_eq!(v.get_mut(2..), Some(&mut [2, 3, 4, 5][..]));
+    assert_eq!(v.get_mut(1..4), Some(&mut [1, 2, 3][..]));
+    assert_eq!(v.get_mut(7..), None);
+    assert_eq!(v.get_mut(7..10), None);
+}
+
+#[test]
+fn get_unchecked_range() {
+    unsafe {
+        let v: &[i32] = &[0, 1, 2, 3, 4, 5];
+        assert_eq!(v.get_unchecked(..), &[0, 1, 2, 3, 4, 5][..]);
+        assert_eq!(v.get_unchecked(..2), &[0, 1][..]);
+        assert_eq!(v.get_unchecked(2..), &[2, 3, 4, 5][..]);
+        assert_eq!(v.get_unchecked(1..4), &[1, 2, 3][..]);
+    }
+}
+
+#[test]
+fn get_unchecked_mut_range() {
+    unsafe {
+        let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
+        assert_eq!(v.get_unchecked_mut(..), &mut [0, 1, 2, 3, 4, 5][..]);
+        assert_eq!(v.get_unchecked_mut(..2), &mut [0, 1][..]);
+        assert_eq!(v.get_unchecked_mut(2..), &mut[2, 3, 4, 5][..]);
+        assert_eq!(v.get_unchecked_mut(1..4), &mut [1, 2, 3][..]);
+    }
+}
+
+#[test]
+fn sort_unstable() {
+    let mut v = [0; 600];
+    let mut tmp = [0; 600];
+    let mut rng = XorShiftRng::new_unseeded();
+
+    for len in (2..25).chain(500..510) {
+        let v = &mut v[0..len];
+        let tmp = &mut tmp[0..len];
+
+        for &modulus in &[5, 10, 100, 1000] {
+            for _ in 0..100 {
+                for i in 0..len {
+                    v[i] = rng.gen::<i32>() % modulus;
+                }
+
+                // Sort in default order.
+                tmp.copy_from_slice(v);
+                tmp.sort_unstable();
+                assert!(tmp.windows(2).all(|w| w[0] <= w[1]));
+
+                // Sort in ascending order.
+                tmp.copy_from_slice(v);
+                tmp.sort_unstable_by(|a, b| a.cmp(b));
+                assert!(tmp.windows(2).all(|w| w[0] <= w[1]));
+
+                // Sort in descending order.
+                tmp.copy_from_slice(v);
+                tmp.sort_unstable_by(|a, b| b.cmp(a));
+                assert!(tmp.windows(2).all(|w| w[0] >= w[1]));
+
+                // Test heapsort using `<` operator.
+                tmp.copy_from_slice(v);
+                heapsort(tmp, |a, b| a < b);
+                assert!(tmp.windows(2).all(|w| w[0] <= w[1]));
+
+                // Test heapsort using `>` operator.
+                tmp.copy_from_slice(v);
+                heapsort(tmp, |a, b| a > b);
+                assert!(tmp.windows(2).all(|w| w[0] >= w[1]));
+            }
+        }
+    }
+
+    // Sort using a completely random comparison function.
+    // This will reorder the elements *somehow*, but won't panic.
+    for i in 0..v.len() {
+        v[i] = i as i32;
+    }
+    v.sort_unstable_by(|_, _| *rng.choose(&[Less, Equal, Greater]).unwrap());
+    v.sort_unstable();
+    for i in 0..v.len() {
+        assert_eq!(v[i], i as i32);
+    }
+
+    // Should not panic.
+    [0i32; 0].sort_unstable();
+    [(); 10].sort_unstable();
+    [(); 100].sort_unstable();
+
+    let mut v = [0xDEADBEEFu64];
+    v.sort_unstable();
+    assert!(v == [0xDEADBEEF]);
+}
diff --git a/src/libcore/tests/str.rs b/src/libcore/tests/str.rs
new file mode 100644 (file)
index 0000000..08daafc
--- /dev/null
@@ -0,0 +1,11 @@
+// Copyright 2014-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.
+
+// All `str` tests live in collectionstests::str
diff --git a/src/libcore/tests/tuple.rs b/src/libcore/tests/tuple.rs
new file mode 100644 (file)
index 0000000..4fe5e0a
--- /dev/null
@@ -0,0 +1,68 @@
+// 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::cmp::Ordering::{Equal, Less, Greater};
+
+#[test]
+fn test_clone() {
+    let a = (1, "2");
+    let b = a.clone();
+    assert_eq!(a, b);
+}
+
+#[test]
+fn test_tuple_cmp() {
+    let (small, big) = ((1, 2, 3), (3, 2, 1));
+
+    let nan = 0.0f64/0.0;
+
+    // PartialEq
+    assert_eq!(small, small);
+    assert_eq!(big, big);
+    assert!(small != big);
+    assert!(big != small);
+
+    // PartialOrd
+    assert!(small < big);
+    assert!(!(small < small));
+    assert!(!(big < small));
+    assert!(!(big < big));
+
+    assert!(small <= small);
+    assert!(big <= big);
+
+    assert!(big > small);
+    assert!(small >= small);
+    assert!(big >= small);
+    assert!(big >= big);
+
+    assert!(!((1.0f64, 2.0f64) < (nan, 3.0)));
+    assert!(!((1.0f64, 2.0f64) <= (nan, 3.0)));
+    assert!(!((1.0f64, 2.0f64) > (nan, 3.0)));
+    assert!(!((1.0f64, 2.0f64) >= (nan, 3.0)));
+    assert!(((1.0f64, 2.0f64) < (2.0, nan)));
+    assert!(!((2.0f64, 2.0f64) < (2.0, nan)));
+
+    // Ord
+    assert!(small.cmp(&small) == Equal);
+    assert!(big.cmp(&big) == Equal);
+    assert!(small.cmp(&big) == Less);
+    assert!(big.cmp(&small) == Greater);
+}
+
+#[test]
+fn test_show() {
+    let s = format!("{:?}", (1,));
+    assert_eq!(s, "(1,)");
+    let s = format!("{:?}", (1, true));
+    assert_eq!(s, "(1, true)");
+    let s = format!("{:?}", (1, "hi", true));
+    assert_eq!(s, "(1, \"hi\", true)");
+}
diff --git a/src/libcoretest/any.rs b/src/libcoretest/any.rs
deleted file mode 100644 (file)
index 2d3e81a..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use core::any::*;
-
-#[derive(PartialEq, Debug)]
-struct Test;
-
-static TEST: &'static str = "Test";
-
-#[test]
-fn any_referenced() {
-    let (a, b, c) = (&5 as &Any, &TEST as &Any, &Test as &Any);
-
-    assert!(a.is::<i32>());
-    assert!(!b.is::<i32>());
-    assert!(!c.is::<i32>());
-
-    assert!(!a.is::<&'static str>());
-    assert!(b.is::<&'static str>());
-    assert!(!c.is::<&'static str>());
-
-    assert!(!a.is::<Test>());
-    assert!(!b.is::<Test>());
-    assert!(c.is::<Test>());
-}
-
-#[test]
-fn any_owning() {
-    let (a, b, c) = (box 5_usize as Box<Any>, box TEST as Box<Any>, box Test as Box<Any>);
-
-    assert!(a.is::<usize>());
-    assert!(!b.is::<usize>());
-    assert!(!c.is::<usize>());
-
-    assert!(!a.is::<&'static str>());
-    assert!(b.is::<&'static str>());
-    assert!(!c.is::<&'static str>());
-
-    assert!(!a.is::<Test>());
-    assert!(!b.is::<Test>());
-    assert!(c.is::<Test>());
-}
-
-#[test]
-fn any_downcast_ref() {
-    let a = &5_usize as &Any;
-
-    match a.downcast_ref::<usize>() {
-        Some(&5) => {}
-        x => panic!("Unexpected value {:?}", x)
-    }
-
-    match a.downcast_ref::<Test>() {
-        None => {}
-        x => panic!("Unexpected value {:?}", x)
-    }
-}
-
-#[test]
-fn any_downcast_mut() {
-    let mut a = 5_usize;
-    let mut b: Box<_> = box 7_usize;
-
-    let a_r = &mut a as &mut Any;
-    let tmp: &mut usize = &mut *b;
-    let b_r = tmp as &mut Any;
-
-    match a_r.downcast_mut::<usize>() {
-        Some(x) => {
-            assert_eq!(*x, 5);
-            *x = 612;
-        }
-        x => panic!("Unexpected value {:?}", x)
-    }
-
-    match b_r.downcast_mut::<usize>() {
-        Some(x) => {
-            assert_eq!(*x, 7);
-            *x = 413;
-        }
-        x => panic!("Unexpected value {:?}", x)
-    }
-
-    match a_r.downcast_mut::<Test>() {
-        None => (),
-        x => panic!("Unexpected value {:?}", x)
-    }
-
-    match b_r.downcast_mut::<Test>() {
-        None => (),
-        x => panic!("Unexpected value {:?}", x)
-    }
-
-    match a_r.downcast_mut::<usize>() {
-        Some(&mut 612) => {}
-        x => panic!("Unexpected value {:?}", x)
-    }
-
-    match b_r.downcast_mut::<usize>() {
-        Some(&mut 413) => {}
-        x => panic!("Unexpected value {:?}", x)
-    }
-}
-
-#[test]
-fn any_fixed_vec() {
-    let test = [0_usize; 8];
-    let test = &test as &Any;
-    assert!(test.is::<[usize; 8]>());
-    assert!(!test.is::<[usize; 10]>());
-}
-
-#[test]
-fn any_unsized() {
-    fn is_any<T: Any + ?Sized>() {}
-    is_any::<[i32]>();
-}
diff --git a/src/libcoretest/array.rs b/src/libcoretest/array.rs
deleted file mode 100644 (file)
index 6af031d..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-use core::array::FixedSizeArray;
-
-#[test]
-fn fixed_size_array() {
-    let mut array = [0; 64];
-    let mut zero_sized = [(); 64];
-    let mut empty_array = [0; 0];
-    let mut empty_zero_sized = [(); 0];
-
-    assert_eq!(FixedSizeArray::as_slice(&array).len(), 64);
-    assert_eq!(FixedSizeArray::as_slice(&zero_sized).len(), 64);
-    assert_eq!(FixedSizeArray::as_slice(&empty_array).len(), 0);
-    assert_eq!(FixedSizeArray::as_slice(&empty_zero_sized).len(), 0);
-
-    assert_eq!(FixedSizeArray::as_mut_slice(&mut array).len(), 64);
-    assert_eq!(FixedSizeArray::as_mut_slice(&mut zero_sized).len(), 64);
-    assert_eq!(FixedSizeArray::as_mut_slice(&mut empty_array).len(), 0);
-    assert_eq!(FixedSizeArray::as_mut_slice(&mut empty_zero_sized).len(), 0);
-}
diff --git a/src/libcoretest/atomic.rs b/src/libcoretest/atomic.rs
deleted file mode 100644 (file)
index b6bb5fd..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use core::sync::atomic::*;
-use core::sync::atomic::Ordering::SeqCst;
-
-#[test]
-fn bool_() {
-    let a = AtomicBool::new(false);
-    assert_eq!(a.compare_and_swap(false, true, SeqCst), false);
-    assert_eq!(a.compare_and_swap(false, true, SeqCst), true);
-
-    a.store(false, SeqCst);
-    assert_eq!(a.compare_and_swap(false, true, SeqCst), false);
-}
-
-#[test]
-fn bool_and() {
-    let a = AtomicBool::new(true);
-    assert_eq!(a.fetch_and(false, SeqCst),true);
-    assert_eq!(a.load(SeqCst),false);
-}
-
-#[test]
-fn uint_and() {
-    let x = AtomicUsize::new(0xf731);
-    assert_eq!(x.fetch_and(0x137f, SeqCst), 0xf731);
-    assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
-}
-
-#[test]
-fn uint_or() {
-    let x = AtomicUsize::new(0xf731);
-    assert_eq!(x.fetch_or(0x137f, SeqCst), 0xf731);
-    assert_eq!(x.load(SeqCst), 0xf731 | 0x137f);
-}
-
-#[test]
-fn uint_xor() {
-    let x = AtomicUsize::new(0xf731);
-    assert_eq!(x.fetch_xor(0x137f, SeqCst), 0xf731);
-    assert_eq!(x.load(SeqCst), 0xf731 ^ 0x137f);
-}
-
-#[test]
-fn int_and() {
-    let x = AtomicIsize::new(0xf731);
-    assert_eq!(x.fetch_and(0x137f, SeqCst), 0xf731);
-    assert_eq!(x.load(SeqCst), 0xf731 & 0x137f);
-}
-
-#[test]
-fn int_or() {
-    let x = AtomicIsize::new(0xf731);
-    assert_eq!(x.fetch_or(0x137f, SeqCst), 0xf731);
-    assert_eq!(x.load(SeqCst), 0xf731 | 0x137f);
-}
-
-#[test]
-fn int_xor() {
-    let x = AtomicIsize::new(0xf731);
-    assert_eq!(x.fetch_xor(0x137f, SeqCst), 0xf731);
-    assert_eq!(x.load(SeqCst), 0xf731 ^ 0x137f);
-}
-
-static S_FALSE: AtomicBool = AtomicBool::new(false);
-static S_TRUE: AtomicBool = AtomicBool::new(true);
-static S_INT: AtomicIsize  = AtomicIsize::new(0);
-static S_UINT: AtomicUsize = AtomicUsize::new(0);
-
-#[test]
-fn static_init() {
-    assert!(!S_FALSE.load(SeqCst));
-    assert!(S_TRUE.load(SeqCst));
-    assert!(S_INT.load(SeqCst) == 0);
-    assert!(S_UINT.load(SeqCst) == 0);
-}
diff --git a/src/libcoretest/cell.rs b/src/libcoretest/cell.rs
deleted file mode 100644 (file)
index 8585f2f..0000000
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use core::cell::*;
-use core::default::Default;
-use std::mem::drop;
-
-#[test]
-fn smoketest_cell() {
-    let x = Cell::new(10);
-    assert!(x == Cell::new(10));
-    assert!(x.get() == 10);
-    x.set(20);
-    assert!(x == Cell::new(20));
-    assert!(x.get() == 20);
-
-    let y = Cell::new((30, 40));
-    assert!(y == Cell::new((30, 40)));
-    assert!(y.get() == (30, 40));
-}
-
-#[test]
-fn cell_has_sensible_show() {
-    let x = Cell::new("foo bar");
-    assert!(format!("{:?}", x).contains(x.get()));
-
-    x.set("baz qux");
-    assert!(format!("{:?}", x).contains(x.get()));
-}
-
-#[test]
-fn ref_and_refmut_have_sensible_show() {
-    let refcell = RefCell::new("foo");
-
-    let refcell_refmut = refcell.borrow_mut();
-    assert!(format!("{:?}", refcell_refmut).contains("foo"));
-    drop(refcell_refmut);
-
-    let refcell_ref = refcell.borrow();
-    assert!(format!("{:?}", refcell_ref).contains("foo"));
-    drop(refcell_ref);
-}
-
-#[test]
-fn double_imm_borrow() {
-    let x = RefCell::new(0);
-    let _b1 = x.borrow();
-    x.borrow();
-}
-
-#[test]
-fn no_mut_then_imm_borrow() {
-    let x = RefCell::new(0);
-    let _b1 = x.borrow_mut();
-    assert!(x.try_borrow().is_err());
-}
-
-#[test]
-fn no_imm_then_borrow_mut() {
-    let x = RefCell::new(0);
-    let _b1 = x.borrow();
-    assert!(x.try_borrow_mut().is_err());
-}
-
-#[test]
-fn no_double_borrow_mut() {
-    let x = RefCell::new(0);
-    assert!(x.try_borrow().is_ok());
-    let _b1 = x.borrow_mut();
-    assert!(x.try_borrow().is_err());
-}
-
-#[test]
-fn imm_release_borrow_mut() {
-    let x = RefCell::new(0);
-    {
-        let _b1 = x.borrow();
-    }
-    x.borrow_mut();
-}
-
-#[test]
-fn mut_release_borrow_mut() {
-    let x = RefCell::new(0);
-    {
-        let _b1 = x.borrow_mut();
-    }
-    x.borrow();
-}
-
-#[test]
-fn double_borrow_single_release_no_borrow_mut() {
-    let x = RefCell::new(0);
-    let _b1 = x.borrow();
-    {
-        let _b2 = x.borrow();
-    }
-    assert!(x.try_borrow().is_ok());
-    assert!(x.try_borrow_mut().is_err());
-}
-
-#[test]
-#[should_panic]
-fn discard_doesnt_unborrow() {
-    let x = RefCell::new(0);
-    let _b = x.borrow();
-    let _ = _b;
-    let _b = x.borrow_mut();
-}
-
-#[test]
-fn ref_clone_updates_flag() {
-    let x = RefCell::new(0);
-    {
-        let b1 = x.borrow();
-        assert!(x.try_borrow().is_ok());
-        assert!(x.try_borrow_mut().is_err());
-        {
-            let _b2 = Ref::clone(&b1);
-            assert!(x.try_borrow().is_ok());
-            assert!(x.try_borrow_mut().is_err());
-        }
-        assert!(x.try_borrow().is_ok());
-        assert!(x.try_borrow_mut().is_err());
-    }
-    assert!(x.try_borrow().is_ok());
-    assert!(x.try_borrow_mut().is_ok());
-}
-
-#[test]
-fn ref_map_does_not_update_flag() {
-    let x = RefCell::new(Some(5));
-    {
-        let b1: Ref<Option<u32>> = x.borrow();
-        assert!(x.try_borrow().is_ok());
-        assert!(x.try_borrow_mut().is_err());
-        {
-            let b2: Ref<u32> = Ref::map(b1, |o| o.as_ref().unwrap());
-            assert_eq!(*b2, 5);
-            assert!(x.try_borrow().is_ok());
-            assert!(x.try_borrow_mut().is_err());
-        }
-        assert!(x.try_borrow().is_ok());
-        assert!(x.try_borrow_mut().is_ok());
-    }
-    assert!(x.try_borrow().is_ok());
-    assert!(x.try_borrow_mut().is_ok());
-}
-
-#[test]
-fn ref_map_accessor() {
-    struct X(RefCell<(u32, char)>);
-    impl X {
-        fn accessor(&self) -> Ref<u32> {
-            Ref::map(self.0.borrow(), |tuple| &tuple.0)
-        }
-    }
-    let x = X(RefCell::new((7, 'z')));
-    let d: Ref<u32> = x.accessor();
-    assert_eq!(*d, 7);
-}
-
-#[test]
-fn ref_mut_map_accessor() {
-    struct X(RefCell<(u32, char)>);
-    impl X {
-        fn accessor(&self) -> RefMut<u32> {
-            RefMut::map(self.0.borrow_mut(), |tuple| &mut tuple.0)
-        }
-    }
-    let x = X(RefCell::new((7, 'z')));
-    {
-        let mut d: RefMut<u32> = x.accessor();
-        assert_eq!(*d, 7);
-        *d += 1;
-    }
-    assert_eq!(*x.0.borrow(), (8, 'z'));
-}
-
-#[test]
-fn as_ptr() {
-    let c1: Cell<usize> = Cell::new(0);
-    c1.set(1);
-    assert_eq!(1, unsafe { *c1.as_ptr() });
-
-    let c2: Cell<usize> = Cell::new(0);
-    unsafe { *c2.as_ptr() = 1; }
-    assert_eq!(1, c2.get());
-
-    let r1: RefCell<usize> = RefCell::new(0);
-    *r1.borrow_mut() = 1;
-    assert_eq!(1, unsafe { *r1.as_ptr() });
-
-    let r2: RefCell<usize> = RefCell::new(0);
-    unsafe { *r2.as_ptr() = 1; }
-    assert_eq!(1, *r2.borrow());
-}
-
-#[test]
-fn cell_default() {
-    let cell: Cell<u32> = Default::default();
-    assert_eq!(0, cell.get());
-}
-
-#[test]
-fn cell_set() {
-    let cell = Cell::new(10);
-    cell.set(20);
-    assert_eq!(20, cell.get());
-
-    let cell = Cell::new("Hello".to_owned());
-    cell.set("World".to_owned());
-    assert_eq!("World".to_owned(), cell.into_inner());
-}
-
-#[test]
-fn cell_replace() {
-    let cell = Cell::new(10);
-    assert_eq!(10, cell.replace(20));
-    assert_eq!(20, cell.get());
-
-    let cell = Cell::new("Hello".to_owned());
-    assert_eq!("Hello".to_owned(), cell.replace("World".to_owned()));
-    assert_eq!("World".to_owned(), cell.into_inner());
-}
-
-#[test]
-fn cell_into_inner() {
-    let cell = Cell::new(10);
-    assert_eq!(10, cell.into_inner());
-
-    let cell = Cell::new("Hello world".to_owned());
-    assert_eq!("Hello world".to_owned(), cell.into_inner());
-}
-
-#[test]
-fn refcell_default() {
-    let cell: RefCell<u64> = Default::default();
-    assert_eq!(0, *cell.borrow());
-}
-
-#[test]
-fn unsafe_cell_unsized() {
-    let cell: &UnsafeCell<[i32]> = &UnsafeCell::new([1, 2, 3]);
-    {
-        let val: &mut [i32] = unsafe { &mut *cell.get() };
-        val[0] = 4;
-        val[2] = 5;
-    }
-    let comp: &mut [i32] = &mut [4, 2, 5];
-    assert_eq!(unsafe { &mut *cell.get() }, comp);
-}
-
-#[test]
-fn refcell_unsized() {
-    let cell: &RefCell<[i32]> = &RefCell::new([1, 2, 3]);
-    {
-        let b = &mut *cell.borrow_mut();
-        b[0] = 4;
-        b[2] = 5;
-    }
-    let comp: &mut [i32] = &mut [4, 2, 5];
-    assert_eq!(&*cell.borrow(), comp);
-}
-
-#[test]
-fn refcell_ref_coercion() {
-    let cell: RefCell<[i32; 3]> = RefCell::new([1, 2, 3]);
-    {
-        let mut cellref: RefMut<[i32; 3]> = cell.borrow_mut();
-        cellref[0] = 4;
-        let mut coerced: RefMut<[i32]> = cellref;
-        coerced[2] = 5;
-    }
-    {
-        let comp: &mut [i32] = &mut [4, 2, 5];
-        let cellref: Ref<[i32; 3]> = cell.borrow();
-        assert_eq!(&*cellref, comp);
-        let coerced: Ref<[i32]> = cellref;
-        assert_eq!(&*coerced, comp);
-    }
-}
diff --git a/src/libcoretest/char.rs b/src/libcoretest/char.rs
deleted file mode 100644 (file)
index e4012ec..0000000
+++ /dev/null
@@ -1,404 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::{char,str};
-use std::convert::TryFrom;
-
-#[test]
-fn test_convert() {
-    assert_eq!(u32::from('a'), 0x61);
-    assert_eq!(char::from(b'\0'), '\0');
-    assert_eq!(char::from(b'a'), 'a');
-    assert_eq!(char::from(b'\xFF'), '\u{FF}');
-    assert_eq!(char::try_from(0_u32), Ok('\0'));
-    assert_eq!(char::try_from(0x61_u32), Ok('a'));
-    assert_eq!(char::try_from(0xD7FF_u32), Ok('\u{D7FF}'));
-    assert!(char::try_from(0xD800_u32).is_err());
-    assert!(char::try_from(0xDFFF_u32).is_err());
-    assert_eq!(char::try_from(0xE000_u32), Ok('\u{E000}'));
-    assert_eq!(char::try_from(0x10FFFF_u32), Ok('\u{10FFFF}'));
-    assert!(char::try_from(0x110000_u32).is_err());
-    assert!(char::try_from(0xFFFF_FFFF_u32).is_err());
-}
-
-#[test]
-fn test_is_lowercase() {
-    assert!('a'.is_lowercase());
-    assert!('ö'.is_lowercase());
-    assert!('ß'.is_lowercase());
-    assert!(!'Ü'.is_lowercase());
-    assert!(!'P'.is_lowercase());
-}
-
-#[test]
-fn test_is_uppercase() {
-    assert!(!'h'.is_uppercase());
-    assert!(!'ä'.is_uppercase());
-    assert!(!'ß'.is_uppercase());
-    assert!('Ö'.is_uppercase());
-    assert!('T'.is_uppercase());
-}
-
-#[test]
-fn test_is_whitespace() {
-    assert!(' '.is_whitespace());
-    assert!('\u{2007}'.is_whitespace());
-    assert!('\t'.is_whitespace());
-    assert!('\n'.is_whitespace());
-    assert!(!'a'.is_whitespace());
-    assert!(!'_'.is_whitespace());
-    assert!(!'\u{0}'.is_whitespace());
-}
-
-#[test]
-fn test_to_digit() {
-    assert_eq!('0'.to_digit(10), Some(0));
-    assert_eq!('1'.to_digit(2), Some(1));
-    assert_eq!('2'.to_digit(3), Some(2));
-    assert_eq!('9'.to_digit(10), Some(9));
-    assert_eq!('a'.to_digit(16), Some(10));
-    assert_eq!('A'.to_digit(16), Some(10));
-    assert_eq!('b'.to_digit(16), Some(11));
-    assert_eq!('B'.to_digit(16), Some(11));
-    assert_eq!('z'.to_digit(36), Some(35));
-    assert_eq!('Z'.to_digit(36), Some(35));
-    assert_eq!(' '.to_digit(10), None);
-    assert_eq!('$'.to_digit(36), None);
-}
-
-#[test]
-fn test_to_lowercase() {
-    fn lower(c: char) -> String {
-        let iter: String = c.to_lowercase().collect();
-        let disp: String = c.to_lowercase().to_string();
-        assert_eq!(iter, disp);
-        iter
-    }
-    assert_eq!(lower('A'), "a");
-    assert_eq!(lower('Ö'), "ö");
-    assert_eq!(lower('ß'), "ß");
-    assert_eq!(lower('Ü'), "ü");
-    assert_eq!(lower('💩'), "💩");
-    assert_eq!(lower('Σ'), "σ");
-    assert_eq!(lower('Τ'), "τ");
-    assert_eq!(lower('Ι'), "ι");
-    assert_eq!(lower('Γ'), "γ");
-    assert_eq!(lower('Μ'), "μ");
-    assert_eq!(lower('Α'), "α");
-    assert_eq!(lower('Σ'), "σ");
-    assert_eq!(lower('Dž'), "dž");
-    assert_eq!(lower('fi'), "fi");
-    assert_eq!(lower('İ'), "i\u{307}");
-}
-
-#[test]
-fn test_to_uppercase() {
-    fn upper(c: char) -> String {
-        let iter: String = c.to_uppercase().collect();
-        let disp: String = c.to_uppercase().to_string();
-        assert_eq!(iter, disp);
-        iter
-    }
-    assert_eq!(upper('a'), "A");
-    assert_eq!(upper('ö'), "Ö");
-    assert_eq!(upper('ß'), "SS"); // not ẞ: Latin capital letter sharp s
-    assert_eq!(upper('ü'), "Ü");
-    assert_eq!(upper('💩'), "💩");
-
-    assert_eq!(upper('σ'), "Σ");
-    assert_eq!(upper('τ'), "Τ");
-    assert_eq!(upper('ι'), "Ι");
-    assert_eq!(upper('γ'), "Γ");
-    assert_eq!(upper('μ'), "Μ");
-    assert_eq!(upper('α'), "Α");
-    assert_eq!(upper('ς'), "Σ");
-    assert_eq!(upper('Dž'), "DŽ");
-    assert_eq!(upper('fi'), "FI");
-    assert_eq!(upper('ᾀ'), "ἈΙ");
-}
-
-#[test]
-fn test_is_control() {
-    assert!('\u{0}'.is_control());
-    assert!('\u{3}'.is_control());
-    assert!('\u{6}'.is_control());
-    assert!('\u{9}'.is_control());
-    assert!('\u{7f}'.is_control());
-    assert!('\u{92}'.is_control());
-    assert!(!'\u{20}'.is_control());
-    assert!(!'\u{55}'.is_control());
-    assert!(!'\u{68}'.is_control());
-}
-
-#[test]
-fn test_is_digit() {
-   assert!('2'.is_numeric());
-   assert!('7'.is_numeric());
-   assert!(!'c'.is_numeric());
-   assert!(!'i'.is_numeric());
-   assert!(!'z'.is_numeric());
-   assert!(!'Q'.is_numeric());
-}
-
-#[test]
-fn test_escape_debug() {
-    fn string(c: char) -> String {
-        let iter: String = c.escape_debug().collect();
-        let disp: String = c.escape_debug().to_string();
-        assert_eq!(iter, disp);
-        iter
-    }
-    assert_eq!(string('\n'), "\\n");
-    assert_eq!(string('\r'), "\\r");
-    assert_eq!(string('\''), "\\'");
-    assert_eq!(string('"'), "\\\"");
-    assert_eq!(string(' '), " ");
-    assert_eq!(string('a'), "a");
-    assert_eq!(string('~'), "~");
-    assert_eq!(string('é'), "é");
-    assert_eq!(string('文'), "文");
-    assert_eq!(string('\x00'), "\\u{0}");
-    assert_eq!(string('\x1f'), "\\u{1f}");
-    assert_eq!(string('\x7f'), "\\u{7f}");
-    assert_eq!(string('\u{80}'), "\\u{80}");
-    assert_eq!(string('\u{ff}'), "\u{ff}");
-    assert_eq!(string('\u{11b}'), "\u{11b}");
-    assert_eq!(string('\u{1d4b6}'), "\u{1d4b6}");
-    assert_eq!(string('\u{200b}'),"\\u{200b}");      // zero width space
-    assert_eq!(string('\u{e000}'), "\\u{e000}");     // private use 1
-    assert_eq!(string('\u{100000}'), "\\u{100000}"); // private use 2
-}
-
-#[test]
-fn test_escape_default() {
-    fn string(c: char) -> String {
-        let iter: String = c.escape_default().collect();
-        let disp: String = c.escape_default().to_string();
-        assert_eq!(iter, disp);
-        iter
-    }
-    assert_eq!(string('\n'), "\\n");
-    assert_eq!(string('\r'), "\\r");
-    assert_eq!(string('\''), "\\'");
-    assert_eq!(string('"'), "\\\"");
-    assert_eq!(string(' '), " ");
-    assert_eq!(string('a'), "a");
-    assert_eq!(string('~'), "~");
-    assert_eq!(string('é'), "\\u{e9}");
-    assert_eq!(string('\x00'), "\\u{0}");
-    assert_eq!(string('\x1f'), "\\u{1f}");
-    assert_eq!(string('\x7f'), "\\u{7f}");
-    assert_eq!(string('\u{80}'), "\\u{80}");
-    assert_eq!(string('\u{ff}'), "\\u{ff}");
-    assert_eq!(string('\u{11b}'), "\\u{11b}");
-    assert_eq!(string('\u{1d4b6}'), "\\u{1d4b6}");
-    assert_eq!(string('\u{200b}'), "\\u{200b}"); // zero width space
-    assert_eq!(string('\u{e000}'), "\\u{e000}"); // private use 1
-    assert_eq!(string('\u{100000}'), "\\u{100000}"); // private use 2
-}
-
-#[test]
-fn test_escape_unicode() {
-    fn string(c: char) -> String {
-        let iter: String = c.escape_unicode().collect();
-        let disp: String = c.escape_unicode().to_string();
-        assert_eq!(iter, disp);
-        iter
-    }
-
-    assert_eq!(string('\x00'), "\\u{0}");
-    assert_eq!(string('\n'), "\\u{a}");
-    assert_eq!(string(' '), "\\u{20}");
-    assert_eq!(string('a'), "\\u{61}");
-    assert_eq!(string('\u{11b}'), "\\u{11b}");
-    assert_eq!(string('\u{1d4b6}'), "\\u{1d4b6}");
-}
-
-#[test]
-fn test_encode_utf8() {
-    fn check(input: char, expect: &[u8]) {
-        let mut buf = [0; 4];
-        let ptr = buf.as_ptr();
-        let s = input.encode_utf8(&mut buf);
-        assert_eq!(s.as_ptr() as usize, ptr as usize);
-        assert!(str::from_utf8(s.as_bytes()).is_ok());
-        assert_eq!(s.as_bytes(), expect);
-    }
-
-    check('x', &[0x78]);
-    check('\u{e9}', &[0xc3, 0xa9]);
-    check('\u{a66e}', &[0xea, 0x99, 0xae]);
-    check('\u{1f4a9}', &[0xf0, 0x9f, 0x92, 0xa9]);
-}
-
-#[test]
-fn test_encode_utf16() {
-    fn check(input: char, expect: &[u16]) {
-        let mut buf = [0; 2];
-        let ptr = buf.as_mut_ptr();
-        let b = input.encode_utf16(&mut buf);
-        assert_eq!(b.as_mut_ptr() as usize, ptr as usize);
-        assert_eq!(b, expect);
-    }
-
-    check('x', &[0x0078]);
-    check('\u{e9}', &[0x00e9]);
-    check('\u{a66e}', &[0xa66e]);
-    check('\u{1f4a9}', &[0xd83d, 0xdca9]);
-}
-
-#[test]
-fn test_len_utf16() {
-    assert!('x'.len_utf16() == 1);
-    assert!('\u{e9}'.len_utf16() == 1);
-    assert!('\u{a66e}'.len_utf16() == 1);
-    assert!('\u{1f4a9}'.len_utf16() == 2);
-}
-
-#[test]
-fn test_decode_utf16() {
-    fn check(s: &[u16], expected: &[Result<char, u16>]) {
-        let v = char::decode_utf16(s.iter().cloned())
-                     .map(|r| r.map_err(|e| e.unpaired_surrogate()))
-                     .collect::<Vec<_>>();
-        assert_eq!(v, expected);
-    }
-    check(&[0xD800, 0x41, 0x42], &[Err(0xD800), Ok('A'), Ok('B')]);
-    check(&[0xD800, 0], &[Err(0xD800), Ok('\0')]);
-}
-
-#[test]
-fn ed_iterator_specializations() {
-    // Check counting
-    assert_eq!('\n'.escape_default().count(), 2);
-    assert_eq!('c'.escape_default().count(), 1);
-    assert_eq!(' '.escape_default().count(), 1);
-    assert_eq!('\\'.escape_default().count(), 2);
-    assert_eq!('\''.escape_default().count(), 2);
-
-    // Check nth
-
-    // Check that OoB is handled correctly
-    assert_eq!('\n'.escape_default().nth(2), None);
-    assert_eq!('c'.escape_default().nth(1), None);
-    assert_eq!(' '.escape_default().nth(1), None);
-    assert_eq!('\\'.escape_default().nth(2), None);
-    assert_eq!('\''.escape_default().nth(2), None);
-
-    // Check the first char
-    assert_eq!('\n'.escape_default().nth(0), Some('\\'));
-    assert_eq!('c'.escape_default().nth(0), Some('c'));
-    assert_eq!(' '.escape_default().nth(0), Some(' '));
-    assert_eq!('\\'.escape_default().nth(0), Some('\\'));
-    assert_eq!('\''.escape_default().nth(0), Some('\\'));
-
-    // Check the second char
-    assert_eq!('\n'.escape_default().nth(1), Some('n'));
-    assert_eq!('\\'.escape_default().nth(1), Some('\\'));
-    assert_eq!('\''.escape_default().nth(1), Some('\''));
-
-    // Check the last char
-    assert_eq!('\n'.escape_default().last(), Some('n'));
-    assert_eq!('c'.escape_default().last(), Some('c'));
-    assert_eq!(' '.escape_default().last(), Some(' '));
-    assert_eq!('\\'.escape_default().last(), Some('\\'));
-    assert_eq!('\''.escape_default().last(), Some('\''));
-}
-
-#[test]
-fn eu_iterator_specializations() {
-    fn check(c: char) {
-        let len = c.escape_unicode().count();
-
-        // Check OoB
-        assert_eq!(c.escape_unicode().nth(len), None);
-
-        // For all possible in-bound offsets
-        let mut iter = c.escape_unicode();
-        for offset in 0..len {
-            // Check last
-            assert_eq!(iter.clone().last(), Some('}'));
-
-            // Check len
-            assert_eq!(iter.len(), len - offset);
-
-            // Check size_hint (= len in ExactSizeIterator)
-            assert_eq!(iter.size_hint(), (iter.len(), Some(iter.len())));
-
-            // Check counting
-            assert_eq!(iter.clone().count(), len - offset);
-
-            // Check nth
-            assert_eq!(c.escape_unicode().nth(offset), iter.next());
-        }
-
-        // Check post-last
-        assert_eq!(iter.clone().last(), None);
-        assert_eq!(iter.clone().count(), 0);
-    }
-
-    check('\u{0}');
-    check('\u{1}');
-    check('\u{12}');
-    check('\u{123}');
-    check('\u{1234}');
-    check('\u{12340}');
-    check('\u{10FFFF}');
-}
-
-#[test]
-fn test_decode_utf8() {
-    macro_rules! assert_decode_utf8 {
-        ($input_bytes: expr, $expected_str: expr) => {
-            let input_bytes: &[u8] = &$input_bytes;
-            let s = char::decode_utf8(input_bytes.iter().cloned())
-                .map(|r_b| r_b.unwrap_or('\u{FFFD}'))
-                .collect::<String>();
-            assert_eq!(s, $expected_str,
-                       "input bytes: {:?}, expected str: {:?}, result: {:?}",
-                       input_bytes, $expected_str, s);
-            assert_eq!(String::from_utf8_lossy(&$input_bytes), $expected_str);
-        }
-    }
-
-    assert_decode_utf8!([], "");
-    assert_decode_utf8!([0x41], "A");
-    assert_decode_utf8!([0xC1, 0x81], "��");
-    assert_decode_utf8!([0xE2, 0x99, 0xA5], "♥");
-    assert_decode_utf8!([0xE2, 0x99, 0xA5, 0x41], "♥A");
-    assert_decode_utf8!([0xE2, 0x99], "�");
-    assert_decode_utf8!([0xE2, 0x99, 0x41], "�A");
-    assert_decode_utf8!([0xC0], "�");
-    assert_decode_utf8!([0xC0, 0x41], "�A");
-    assert_decode_utf8!([0x80], "�");
-    assert_decode_utf8!([0x80, 0x41], "�A");
-    assert_decode_utf8!([0xFE], "�");
-    assert_decode_utf8!([0xFE, 0x41], "�A");
-    assert_decode_utf8!([0xFF], "�");
-    assert_decode_utf8!([0xFF, 0x41], "�A");
-    assert_decode_utf8!([0xC0, 0x80], "��");
-
-    // Surrogates
-    assert_decode_utf8!([0xED, 0x9F, 0xBF], "\u{D7FF}");
-    assert_decode_utf8!([0xED, 0xA0, 0x80], "���");
-    assert_decode_utf8!([0xED, 0xBF, 0x80], "���");
-    assert_decode_utf8!([0xEE, 0x80, 0x80], "\u{E000}");
-
-    // char::MAX
-    assert_decode_utf8!([0xF4, 0x8F, 0xBF, 0xBF], "\u{10FFFF}");
-    assert_decode_utf8!([0xF4, 0x8F, 0xBF, 0x41], "�A");
-    assert_decode_utf8!([0xF4, 0x90, 0x80, 0x80], "����");
-
-    // 5 and 6 bytes sequence
-    // Part of the original design of UTF-8,
-    // but invalid now that UTF-8 is artificially restricted to match the range of UTF-16.
-    assert_decode_utf8!([0xF8, 0x80, 0x80, 0x80, 0x80], "�����");
-    assert_decode_utf8!([0xFC, 0x80, 0x80, 0x80, 0x80, 0x80], "������");
-}
diff --git a/src/libcoretest/clone.rs b/src/libcoretest/clone.rs
deleted file mode 100644 (file)
index 91d68ba..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2014-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.
-
-#[test]
-fn test_borrowed_clone() {
-    let x = 5;
-    let y: &i32 = &x;
-    let z: &i32 = (&y).clone();
-    assert_eq!(*z, 5);
-}
-
-#[test]
-fn test_clone_from() {
-    let a = box 5;
-    let mut b = box 10;
-    b.clone_from(&a);
-    assert_eq!(*b, 5);
-}
diff --git a/src/libcoretest/cmp.rs b/src/libcoretest/cmp.rs
deleted file mode 100644 (file)
index e3c65ad..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use core::cmp::Ordering::{Less, Greater, Equal};
-
-#[test]
-fn test_int_totalord() {
-    assert_eq!(5.cmp(&10), Less);
-    assert_eq!(10.cmp(&5), Greater);
-    assert_eq!(5.cmp(&5), Equal);
-    assert_eq!((-5).cmp(&12), Less);
-    assert_eq!(12.cmp(&-5), Greater);
-}
-
-#[test]
-fn test_mut_int_totalord() {
-    assert_eq!((&mut 5).cmp(&&mut 10), Less);
-    assert_eq!((&mut 10).cmp(&&mut 5), Greater);
-    assert_eq!((&mut 5).cmp(&&mut 5), Equal);
-    assert_eq!((&mut -5).cmp(&&mut 12), Less);
-    assert_eq!((&mut 12).cmp(&&mut -5), Greater);
-}
-
-#[test]
-fn test_ordering_reverse() {
-    assert_eq!(Less.reverse(), Greater);
-    assert_eq!(Equal.reverse(), Equal);
-    assert_eq!(Greater.reverse(), Less);
-}
-
-#[test]
-fn test_ordering_order() {
-    assert!(Less < Equal);
-    assert_eq!(Greater.cmp(&Less), Greater);
-}
-
-#[test]
-fn test_ordering_then() {
-    assert_eq!(Equal.then(Less), Less);
-    assert_eq!(Equal.then(Equal), Equal);
-    assert_eq!(Equal.then(Greater), Greater);
-    assert_eq!(Less.then(Less), Less);
-    assert_eq!(Less.then(Equal), Less);
-    assert_eq!(Less.then(Greater), Less);
-    assert_eq!(Greater.then(Less), Greater);
-    assert_eq!(Greater.then(Equal), Greater);
-    assert_eq!(Greater.then(Greater), Greater);
-}
-
-#[test]
-fn test_ordering_then_with() {
-    assert_eq!(Equal.then_with(|| Less), Less);
-    assert_eq!(Equal.then_with(|| Equal), Equal);
-    assert_eq!(Equal.then_with(|| Greater), Greater);
-    assert_eq!(Less.then_with(|| Less), Less);
-    assert_eq!(Less.then_with(|| Equal), Less);
-    assert_eq!(Less.then_with(|| Greater), Less);
-    assert_eq!(Greater.then_with(|| Less), Greater);
-    assert_eq!(Greater.then_with(|| Equal), Greater);
-    assert_eq!(Greater.then_with(|| Greater), Greater);
-}
-
-#[test]
-fn test_user_defined_eq() {
-    // Our type.
-    struct SketchyNum {
-        num : isize
-    }
-
-    // Our implementation of `PartialEq` to support `==` and `!=`.
-    impl PartialEq for SketchyNum {
-        // Our custom eq allows numbers which are near each other to be equal! :D
-        fn eq(&self, other: &SketchyNum) -> bool {
-            (self.num - other.num).abs() < 5
-        }
-    }
-
-    // Now these binary operators will work when applied!
-    assert!(SketchyNum {num: 37} == SketchyNum {num: 34});
-    assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
-}
diff --git a/src/libcoretest/fmt/builders.rs b/src/libcoretest/fmt/builders.rs
deleted file mode 100644 (file)
index e71e61b..0000000
+++ /dev/null
@@ -1,498 +0,0 @@
-// 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 debug_struct {
-    use std::fmt;
-
-    #[test]
-    fn test_empty() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_struct("Foo").finish()
-            }
-        }
-
-        assert_eq!("Foo", format!("{:?}", Foo));
-        assert_eq!("Foo", format!("{:#?}", Foo));
-    }
-
-    #[test]
-    fn test_single() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_struct("Foo")
-                    .field("bar", &true)
-                    .finish()
-            }
-        }
-
-        assert_eq!("Foo { bar: true }", format!("{:?}", Foo));
-        assert_eq!(
-"Foo {
-    bar: true
-}",
-                   format!("{:#?}", Foo));
-    }
-
-    #[test]
-    fn test_multiple() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_struct("Foo")
-                    .field("bar", &true)
-                    .field("baz", &format_args!("{}/{}", 10, 20))
-                    .finish()
-            }
-        }
-
-        assert_eq!("Foo { bar: true, baz: 10/20 }", format!("{:?}", Foo));
-        assert_eq!(
-"Foo {
-    bar: true,
-    baz: 10/20
-}",
-                   format!("{:#?}", Foo));
-    }
-
-    #[test]
-    fn test_nested() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_struct("Foo")
-                    .field("bar", &true)
-                    .field("baz", &format_args!("{}/{}", 10, 20))
-                    .finish()
-            }
-        }
-
-        struct Bar;
-
-        impl fmt::Debug for Bar {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_struct("Bar")
-                    .field("foo", &Foo)
-                    .field("hello", &"world")
-                    .finish()
-            }
-        }
-
-        assert_eq!("Bar { foo: Foo { bar: true, baz: 10/20 }, hello: \"world\" }",
-                   format!("{:?}", Bar));
-        assert_eq!(
-"Bar {
-    foo: Foo {
-        bar: true,
-        baz: 10/20
-    },
-    hello: \"world\"
-}",
-                   format!("{:#?}", Bar));
-    }
-}
-
-mod debug_tuple {
-    use std::fmt;
-
-    #[test]
-    fn test_empty() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_tuple("Foo").finish()
-            }
-        }
-
-        assert_eq!("Foo", format!("{:?}", Foo));
-        assert_eq!("Foo", format!("{:#?}", Foo));
-    }
-
-    #[test]
-    fn test_single() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_tuple("Foo")
-                    .field(&true)
-                    .finish()
-            }
-        }
-
-        assert_eq!("Foo(true)", format!("{:?}", Foo));
-        assert_eq!(
-"Foo(
-    true
-)",
-                   format!("{:#?}", Foo));
-    }
-
-    #[test]
-    fn test_multiple() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_tuple("Foo")
-                    .field(&true)
-                    .field(&format_args!("{}/{}", 10, 20))
-                    .finish()
-            }
-        }
-
-        assert_eq!("Foo(true, 10/20)", format!("{:?}", Foo));
-        assert_eq!(
-"Foo(
-    true,
-    10/20
-)",
-                   format!("{:#?}", Foo));
-    }
-
-    #[test]
-    fn test_nested() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_tuple("Foo")
-                    .field(&true)
-                    .field(&format_args!("{}/{}", 10, 20))
-                    .finish()
-            }
-        }
-
-        struct Bar;
-
-        impl fmt::Debug for Bar {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_tuple("Bar")
-                    .field(&Foo)
-                    .field(&"world")
-                    .finish()
-            }
-        }
-
-        assert_eq!("Bar(Foo(true, 10/20), \"world\")",
-                   format!("{:?}", Bar));
-        assert_eq!(
-"Bar(
-    Foo(
-        true,
-        10/20
-    ),
-    \"world\"
-)",
-                   format!("{:#?}", Bar));
-    }
-}
-
-mod debug_map {
-    use std::fmt;
-
-    #[test]
-    fn test_empty() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_map().finish()
-            }
-        }
-
-        assert_eq!("{}", format!("{:?}", Foo));
-        assert_eq!("{}", format!("{:#?}", Foo));
-    }
-
-    #[test]
-    fn test_single() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_map()
-                    .entry(&"bar", &true)
-                    .finish()
-            }
-        }
-
-        assert_eq!("{\"bar\": true}", format!("{:?}", Foo));
-        assert_eq!(
-"{
-    \"bar\": true
-}",
-                   format!("{:#?}", Foo));
-    }
-
-    #[test]
-    fn test_multiple() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_map()
-                    .entry(&"bar", &true)
-                    .entry(&10, &format_args!("{}/{}", 10, 20))
-                    .finish()
-            }
-        }
-
-        assert_eq!("{\"bar\": true, 10: 10/20}", format!("{:?}", Foo));
-        assert_eq!(
-"{
-    \"bar\": true,
-    10: 10/20
-}",
-                   format!("{:#?}", Foo));
-    }
-
-    #[test]
-    fn test_nested() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_map()
-                    .entry(&"bar", &true)
-                    .entry(&10, &format_args!("{}/{}", 10, 20))
-                    .finish()
-            }
-        }
-
-        struct Bar;
-
-        impl fmt::Debug for Bar {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_map()
-                    .entry(&"foo", &Foo)
-                    .entry(&Foo, &"world")
-                    .finish()
-            }
-        }
-
-        assert_eq!("{\"foo\": {\"bar\": true, 10: 10/20}, \
-                    {\"bar\": true, 10: 10/20}: \"world\"}",
-                   format!("{:?}", Bar));
-        assert_eq!(
-"{
-    \"foo\": {
-        \"bar\": true,
-        10: 10/20
-    },
-    {
-        \"bar\": true,
-        10: 10/20
-    }: \"world\"
-}",
-                   format!("{:#?}", Bar));
-    }
-}
-
-mod debug_set {
-    use std::fmt;
-
-    #[test]
-    fn test_empty() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_set().finish()
-            }
-        }
-
-        assert_eq!("{}", format!("{:?}", Foo));
-        assert_eq!("{}", format!("{:#?}", Foo));
-    }
-
-    #[test]
-    fn test_single() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_set()
-                    .entry(&true)
-                    .finish()
-            }
-        }
-
-        assert_eq!("{true}", format!("{:?}", Foo));
-        assert_eq!(
-"{
-    true
-}",
-                   format!("{:#?}", Foo));
-    }
-
-    #[test]
-    fn test_multiple() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_set()
-                    .entry(&true)
-                    .entry(&format_args!("{}/{}", 10, 20))
-                    .finish()
-            }
-        }
-
-        assert_eq!("{true, 10/20}", format!("{:?}", Foo));
-        assert_eq!(
-"{
-    true,
-    10/20
-}",
-                   format!("{:#?}", Foo));
-    }
-
-    #[test]
-    fn test_nested() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_set()
-                    .entry(&true)
-                    .entry(&format_args!("{}/{}", 10, 20))
-                    .finish()
-            }
-        }
-
-        struct Bar;
-
-        impl fmt::Debug for Bar {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_set()
-                    .entry(&Foo)
-                    .entry(&"world")
-                    .finish()
-            }
-        }
-
-        assert_eq!("{{true, 10/20}, \"world\"}",
-                   format!("{:?}", Bar));
-        assert_eq!(
-"{
-    {
-        true,
-        10/20
-    },
-    \"world\"
-}",
-                   format!("{:#?}", Bar));
-    }
-}
-
-mod debug_list {
-    use std::fmt;
-
-    #[test]
-    fn test_empty() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_list().finish()
-            }
-        }
-
-        assert_eq!("[]", format!("{:?}", Foo));
-        assert_eq!("[]", format!("{:#?}", Foo));
-    }
-
-    #[test]
-    fn test_single() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_list()
-                    .entry(&true)
-                    .finish()
-            }
-        }
-
-        assert_eq!("[true]", format!("{:?}", Foo));
-        assert_eq!(
-"[
-    true
-]",
-                   format!("{:#?}", Foo));
-    }
-
-    #[test]
-    fn test_multiple() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_list()
-                    .entry(&true)
-                    .entry(&format_args!("{}/{}", 10, 20))
-                    .finish()
-            }
-        }
-
-        assert_eq!("[true, 10/20]", format!("{:?}", Foo));
-        assert_eq!(
-"[
-    true,
-    10/20
-]",
-                   format!("{:#?}", Foo));
-    }
-
-    #[test]
-    fn test_nested() {
-        struct Foo;
-
-        impl fmt::Debug for Foo {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_list()
-                    .entry(&true)
-                    .entry(&format_args!("{}/{}", 10, 20))
-                    .finish()
-            }
-        }
-
-        struct Bar;
-
-        impl fmt::Debug for Bar {
-            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-                fmt.debug_list()
-                    .entry(&Foo)
-                    .entry(&"world")
-                    .finish()
-            }
-        }
-
-        assert_eq!("[[true, 10/20], \"world\"]",
-                   format!("{:?}", Bar));
-        assert_eq!(
-"[
-    [
-        true,
-        10/20
-    ],
-    \"world\"
-]",
-                   format!("{:#?}", Bar));
-    }
-}
diff --git a/src/libcoretest/fmt/float.rs b/src/libcoretest/fmt/float.rs
deleted file mode 100644 (file)
index 6950013..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[test]
-fn test_format_f64() {
-    assert_eq!("1", format!("{:.0}", 1.0f64));
-    assert_eq!("9", format!("{:.0}", 9.4f64));
-    assert_eq!("10", format!("{:.0}", 9.9f64));
-    assert_eq!("9.8", format!("{:.1}", 9.849f64));
-    assert_eq!("9.9", format!("{:.1}", 9.851f64));
-    assert_eq!("1", format!("{:.0}", 0.5f64));
-    assert_eq!("1.23456789e6", format!("{:e}", 1234567.89f64));
-    assert_eq!("1.23456789e3", format!("{:e}", 1234.56789f64));
-    assert_eq!("1.23456789E6", format!("{:E}", 1234567.89f64));
-    assert_eq!("1.23456789E3", format!("{:E}", 1234.56789f64));
-}
-
-#[test]
-fn test_format_f32() {
-    assert_eq!("1", format!("{:.0}", 1.0f32));
-    assert_eq!("9", format!("{:.0}", 9.4f32));
-    assert_eq!("10", format!("{:.0}", 9.9f32));
-    assert_eq!("9.8", format!("{:.1}", 9.849f32));
-    assert_eq!("9.9", format!("{:.1}", 9.851f32));
-    assert_eq!("1", format!("{:.0}", 0.5f32));
-    assert_eq!("1.2345679e6", format!("{:e}", 1234567.89f32));
-    assert_eq!("1.2345679e3", format!("{:e}", 1234.56789f32));
-    assert_eq!("1.2345679E6", format!("{:E}", 1234567.89f32));
-    assert_eq!("1.2345679E3", format!("{:E}", 1234.56789f32));
-}
diff --git a/src/libcoretest/fmt/mod.rs b/src/libcoretest/fmt/mod.rs
deleted file mode 100644 (file)
index 5d204c7..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-mod builders;
-mod float;
-mod num;
-
-#[test]
-fn test_format_flags() {
-    // No residual flags left by pointer formatting
-    let p = "".as_ptr();
-    assert_eq!(format!("{:p} {:x}", p, 16), format!("{:p} 10", p));
-
-    assert_eq!(format!("{: >3}", 'a'), "  a");
-}
-
-#[test]
-fn test_pointer_formats_data_pointer() {
-    let b: &[u8] = b"";
-    let s: &str = "";
-    assert_eq!(format!("{:p}", s), format!("{:p}", s.as_ptr()));
-    assert_eq!(format!("{:p}", b), format!("{:p}", b.as_ptr()));
-}
-
-#[test]
-fn test_estimated_capacity() {
-    assert_eq!(format_args!("").estimated_capacity(), 0);
-    assert_eq!(format_args!("{}", "").estimated_capacity(), 0);
-    assert_eq!(format_args!("Hello").estimated_capacity(), 5);
-    assert_eq!(format_args!("Hello, {}!", "").estimated_capacity(), 16);
-    assert_eq!(format_args!("{}, hello!", "World").estimated_capacity(), 0);
-    assert_eq!(format_args!("{}. 16-bytes piece", "World").estimated_capacity(), 32);
-}
diff --git a/src/libcoretest/fmt/num.rs b/src/libcoretest/fmt/num.rs
deleted file mode 100644 (file)
index 4ddedd9..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[test]
-fn test_format_int() {
-    // Formatting integers should select the right implementation based off
-    // the type of the argument. Also, hex/octal/binary should be defined
-    // for integers, but they shouldn't emit the negative sign.
-    assert!(format!("{}", 1isize) == "1");
-    assert!(format!("{}", 1i8) == "1");
-    assert!(format!("{}", 1i16) == "1");
-    assert!(format!("{}", 1i32) == "1");
-    assert!(format!("{}", 1i64) == "1");
-    assert!(format!("{}", -1isize) == "-1");
-    assert!(format!("{}", -1i8) == "-1");
-    assert!(format!("{}", -1i16) == "-1");
-    assert!(format!("{}", -1i32) == "-1");
-    assert!(format!("{}", -1i64) == "-1");
-    assert!(format!("{:?}", 1isize) == "1");
-    assert!(format!("{:?}", 1i8) == "1");
-    assert!(format!("{:?}", 1i16) == "1");
-    assert!(format!("{:?}", 1i32) == "1");
-    assert!(format!("{:?}", 1i64) == "1");
-    assert!(format!("{:b}", 1isize) == "1");
-    assert!(format!("{:b}", 1i8) == "1");
-    assert!(format!("{:b}", 1i16) == "1");
-    assert!(format!("{:b}", 1i32) == "1");
-    assert!(format!("{:b}", 1i64) == "1");
-    assert!(format!("{:x}", 1isize) == "1");
-    assert!(format!("{:x}", 1i8) == "1");
-    assert!(format!("{:x}", 1i16) == "1");
-    assert!(format!("{:x}", 1i32) == "1");
-    assert!(format!("{:x}", 1i64) == "1");
-    assert!(format!("{:X}", 1isize) == "1");
-    assert!(format!("{:X}", 1i8) == "1");
-    assert!(format!("{:X}", 1i16) == "1");
-    assert!(format!("{:X}", 1i32) == "1");
-    assert!(format!("{:X}", 1i64) == "1");
-    assert!(format!("{:o}", 1isize) == "1");
-    assert!(format!("{:o}", 1i8) == "1");
-    assert!(format!("{:o}", 1i16) == "1");
-    assert!(format!("{:o}", 1i32) == "1");
-    assert!(format!("{:o}", 1i64) == "1");
-
-    assert!(format!("{}", 1usize) == "1");
-    assert!(format!("{}", 1u8) == "1");
-    assert!(format!("{}", 1u16) == "1");
-    assert!(format!("{}", 1u32) == "1");
-    assert!(format!("{}", 1u64) == "1");
-    assert!(format!("{:?}", 1usize) == "1");
-    assert!(format!("{:?}", 1u8) == "1");
-    assert!(format!("{:?}", 1u16) == "1");
-    assert!(format!("{:?}", 1u32) == "1");
-    assert!(format!("{:?}", 1u64) == "1");
-    assert!(format!("{:b}", 1usize) == "1");
-    assert!(format!("{:b}", 1u8) == "1");
-    assert!(format!("{:b}", 1u16) == "1");
-    assert!(format!("{:b}", 1u32) == "1");
-    assert!(format!("{:b}", 1u64) == "1");
-    assert!(format!("{:x}", 1usize) == "1");
-    assert!(format!("{:x}", 1u8) == "1");
-    assert!(format!("{:x}", 1u16) == "1");
-    assert!(format!("{:x}", 1u32) == "1");
-    assert!(format!("{:x}", 1u64) == "1");
-    assert!(format!("{:X}", 1usize) == "1");
-    assert!(format!("{:X}", 1u8) == "1");
-    assert!(format!("{:X}", 1u16) == "1");
-    assert!(format!("{:X}", 1u32) == "1");
-    assert!(format!("{:X}", 1u64) == "1");
-    assert!(format!("{:o}", 1usize) == "1");
-    assert!(format!("{:o}", 1u8) == "1");
-    assert!(format!("{:o}", 1u16) == "1");
-    assert!(format!("{:o}", 1u32) == "1");
-    assert!(format!("{:o}", 1u64) == "1");
-
-    // Test a larger number
-    assert!(format!("{:b}", 55) == "110111");
-    assert!(format!("{:o}", 55) == "67");
-    assert!(format!("{}", 55) == "55");
-    assert!(format!("{:x}", 55) == "37");
-    assert!(format!("{:X}", 55) == "37");
-}
-
-#[test]
-fn test_format_int_zero() {
-    assert!(format!("{}", 0) == "0");
-    assert!(format!("{:?}", 0) == "0");
-    assert!(format!("{:b}", 0) == "0");
-    assert!(format!("{:o}", 0) == "0");
-    assert!(format!("{:x}", 0) == "0");
-    assert!(format!("{:X}", 0) == "0");
-
-    assert!(format!("{}", 0u32) == "0");
-    assert!(format!("{:?}", 0u32) == "0");
-    assert!(format!("{:b}", 0u32) == "0");
-    assert!(format!("{:o}", 0u32) == "0");
-    assert!(format!("{:x}", 0u32) == "0");
-    assert!(format!("{:X}", 0u32) == "0");
-}
-
-#[test]
-fn test_format_int_flags() {
-    assert!(format!("{:3}", 1) == "  1");
-    assert!(format!("{:>3}", 1) == "  1");
-    assert!(format!("{:>+3}", 1) == " +1");
-    assert!(format!("{:<3}", 1) == "1  ");
-    assert!(format!("{:#}", 1) == "1");
-    assert!(format!("{:#x}", 10) == "0xa");
-    assert!(format!("{:#X}", 10) == "0xA");
-    assert!(format!("{:#5x}", 10) == "  0xa");
-    assert!(format!("{:#o}", 10) == "0o12");
-    assert!(format!("{:08x}", 10) == "0000000a");
-    assert!(format!("{:8x}", 10) == "       a");
-    assert!(format!("{:<8x}", 10) == "a       ");
-    assert!(format!("{:>8x}", 10) == "       a");
-    assert!(format!("{:#08x}", 10) == "0x00000a");
-    assert!(format!("{:08}", -10) == "-0000010");
-    assert!(format!("{:x}", !0u8) == "ff");
-    assert!(format!("{:X}", !0u8) == "FF");
-    assert!(format!("{:b}", !0u8) == "11111111");
-    assert!(format!("{:o}", !0u8) == "377");
-    assert!(format!("{:#x}", !0u8) == "0xff");
-    assert!(format!("{:#X}", !0u8) == "0xFF");
-    assert!(format!("{:#b}", !0u8) == "0b11111111");
-    assert!(format!("{:#o}", !0u8) == "0o377");
-}
-
-#[test]
-fn test_format_int_sign_padding() {
-    assert!(format!("{:+5}", 1) == "   +1");
-    assert!(format!("{:+5}", -1) == "   -1");
-    assert!(format!("{:05}", 1) == "00001");
-    assert!(format!("{:05}", -1) == "-0001");
-    assert!(format!("{:+05}", 1) == "+0001");
-    assert!(format!("{:+05}", -1) == "-0001");
-}
-
-#[test]
-fn test_format_int_twos_complement() {
-    use core::{i8, i16, i32, i64};
-    assert!(format!("{}", i8::MIN) == "-128");
-    assert!(format!("{}", i16::MIN) == "-32768");
-    assert!(format!("{}", i32::MIN) == "-2147483648");
-    assert!(format!("{}", i64::MIN) == "-9223372036854775808");
-}
diff --git a/src/libcoretest/hash/mod.rs b/src/libcoretest/hash/mod.rs
deleted file mode 100644 (file)
index 53ac17c..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-mod sip;
-
-use std::hash::{Hash, Hasher};
-use std::default::Default;
-
-struct MyHasher {
-    hash: u64,
-}
-
-impl Default for MyHasher {
-    fn default() -> MyHasher {
-        MyHasher { hash: 0 }
-    }
-}
-
-impl Hasher for MyHasher {
-    fn write(&mut self, buf: &[u8]) {
-        for byte in buf {
-            self.hash += *byte as u64;
-        }
-    }
-    fn finish(&self) -> u64 { self.hash }
-}
-
-
-#[test]
-fn test_writer_hasher() {
-    fn hash<T: Hash>(t: &T) -> u64 {
-        let mut s = MyHasher { hash: 0 };
-        t.hash(&mut s);
-        s.finish()
-    }
-
-    assert_eq!(hash(&()), 0);
-
-    assert_eq!(hash(&5_u8), 5);
-    assert_eq!(hash(&5_u16), 5);
-    assert_eq!(hash(&5_u32), 5);
-    assert_eq!(hash(&5_u64), 5);
-    assert_eq!(hash(&5_usize), 5);
-
-    assert_eq!(hash(&5_i8), 5);
-    assert_eq!(hash(&5_i16), 5);
-    assert_eq!(hash(&5_i32), 5);
-    assert_eq!(hash(&5_i64), 5);
-    assert_eq!(hash(&5_isize), 5);
-
-    assert_eq!(hash(&false), 0);
-    assert_eq!(hash(&true), 1);
-
-    assert_eq!(hash(&'a'), 97);
-
-    let s: &str = "a";
-    assert_eq!(hash(& s), 97 + 0xFF);
-    let s: Box<str> = String::from("a").into_boxed_str();
-    assert_eq!(hash(& s), 97 + 0xFF);
-    let cs: &[u8] = &[1, 2, 3];
-    assert_eq!(hash(& cs), 9);
-    let cs: Box<[u8]> = Box::new([1, 2, 3]);
-    assert_eq!(hash(& cs), 9);
-
-    // FIXME (#18248) Add tests for hashing Rc<str> and Rc<[T]>
-
-    let ptr = 5_usize as *const i32;
-    assert_eq!(hash(&ptr), 5);
-
-    let ptr = 5_usize as *mut i32;
-    assert_eq!(hash(&ptr), 5);
-}
-
-struct Custom { hash: u64 }
-struct CustomHasher { output: u64 }
-
-impl Hasher for CustomHasher {
-    fn finish(&self) -> u64 { self.output }
-    fn write(&mut self, _: &[u8]) { panic!() }
-    fn write_u64(&mut self, data: u64) { self.output = data; }
-}
-
-impl Default for CustomHasher {
-    fn default() -> CustomHasher {
-        CustomHasher { output: 0 }
-    }
-}
-
-impl Hash for Custom {
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        state.write_u64(self.hash);
-    }
-}
-
-#[test]
-fn test_custom_state() {
-    fn hash<T: Hash>(t: &T) -> u64 {
-        let mut c = CustomHasher { output: 0 };
-        t.hash(&mut c);
-        c.finish()
-    }
-
-    assert_eq!(hash(&Custom { hash: 5 }), 5);
-}
diff --git a/src/libcoretest/hash/sip.rs b/src/libcoretest/hash/sip.rs
deleted file mode 100644 (file)
index 4a9657e..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(deprecated)]
-
-use core::hash::{Hash, Hasher};
-use core::hash::{SipHasher, SipHasher13, SipHasher24};
-use core::{slice, mem};
-
-// Hash just the bytes of the slice, without length prefix
-struct Bytes<'a>(&'a [u8]);
-
-impl<'a> Hash for Bytes<'a> {
-    #[allow(unused_must_use)]
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        let Bytes(v) = *self;
-        state.write(v);
-    }
-}
-
-macro_rules! u8to64_le {
-    ($buf:expr, $i:expr) =>
-    ($buf[0+$i] as u64 |
-     ($buf[1+$i] as u64) << 8 |
-     ($buf[2+$i] as u64) << 16 |
-     ($buf[3+$i] as u64) << 24 |
-     ($buf[4+$i] as u64) << 32 |
-     ($buf[5+$i] as u64) << 40 |
-     ($buf[6+$i] as u64) << 48 |
-     ($buf[7+$i] as u64) << 56);
-    ($buf:expr, $i:expr, $len:expr) =>
-    ({
-        let mut t = 0;
-        let mut out = 0;
-        while t < $len {
-            out |= ($buf[t+$i] as u64) << t*8;
-            t += 1;
-        }
-        out
-    });
-}
-
-fn hash_with<H: Hasher, T: Hash>(mut st: H, x: &T) -> u64 {
-    x.hash(&mut st);
-    st.finish()
-}
-
-fn hash<T: Hash>(x: &T) -> u64 {
-    hash_with(SipHasher::new(), x)
-}
-
-#[test]
-#[allow(unused_must_use)]
-fn test_siphash_1_3() {
-    let vecs : [[u8; 8]; 64] = [
-        [ 0xdc, 0xc4, 0x0f, 0x05, 0x58, 0x01, 0xac, 0xab ],
-        [ 0x93, 0xca, 0x57, 0x7d, 0xf3, 0x9b, 0xf4, 0xc9 ],
-        [ 0x4d, 0xd4, 0xc7, 0x4d, 0x02, 0x9b, 0xcb, 0x82 ],
-        [ 0xfb, 0xf7, 0xdd, 0xe7, 0xb8, 0x0a, 0xf8, 0x8b ],
-        [ 0x28, 0x83, 0xd3, 0x88, 0x60, 0x57, 0x75, 0xcf ],
-        [ 0x67, 0x3b, 0x53, 0x49, 0x2f, 0xd5, 0xf9, 0xde ],
-        [ 0xa7, 0x22, 0x9f, 0xc5, 0x50, 0x2b, 0x0d, 0xc5 ],
-        [ 0x40, 0x11, 0xb1, 0x9b, 0x98, 0x7d, 0x92, 0xd3 ],
-        [ 0x8e, 0x9a, 0x29, 0x8d, 0x11, 0x95, 0x90, 0x36 ],
-        [ 0xe4, 0x3d, 0x06, 0x6c, 0xb3, 0x8e, 0xa4, 0x25 ],
-        [ 0x7f, 0x09, 0xff, 0x92, 0xee, 0x85, 0xde, 0x79 ],
-        [ 0x52, 0xc3, 0x4d, 0xf9, 0xc1, 0x18, 0xc1, 0x70 ],
-        [ 0xa2, 0xd9, 0xb4, 0x57, 0xb1, 0x84, 0xa3, 0x78 ],
-        [ 0xa7, 0xff, 0x29, 0x12, 0x0c, 0x76, 0x6f, 0x30 ],
-        [ 0x34, 0x5d, 0xf9, 0xc0, 0x11, 0xa1, 0x5a, 0x60 ],
-        [ 0x56, 0x99, 0x51, 0x2a, 0x6d, 0xd8, 0x20, 0xd3 ],
-        [ 0x66, 0x8b, 0x90, 0x7d, 0x1a, 0xdd, 0x4f, 0xcc ],
-        [ 0x0c, 0xd8, 0xdb, 0x63, 0x90, 0x68, 0xf2, 0x9c ],
-        [ 0x3e, 0xe6, 0x73, 0xb4, 0x9c, 0x38, 0xfc, 0x8f ],
-        [ 0x1c, 0x7d, 0x29, 0x8d, 0xe5, 0x9d, 0x1f, 0xf2 ],
-        [ 0x40, 0xe0, 0xcc, 0xa6, 0x46, 0x2f, 0xdc, 0xc0 ],
-        [ 0x44, 0xf8, 0x45, 0x2b, 0xfe, 0xab, 0x92, 0xb9 ],
-        [ 0x2e, 0x87, 0x20, 0xa3, 0x9b, 0x7b, 0xfe, 0x7f ],
-        [ 0x23, 0xc1, 0xe6, 0xda, 0x7f, 0x0e, 0x5a, 0x52 ],
-        [ 0x8c, 0x9c, 0x34, 0x67, 0xb2, 0xae, 0x64, 0xf4 ],
-        [ 0x79, 0x09, 0x5b, 0x70, 0x28, 0x59, 0xcd, 0x45 ],
-        [ 0xa5, 0x13, 0x99, 0xca, 0xe3, 0x35, 0x3e, 0x3a ],
-        [ 0x35, 0x3b, 0xde, 0x4a, 0x4e, 0xc7, 0x1d, 0xa9 ],
-        [ 0x0d, 0xd0, 0x6c, 0xef, 0x02, 0xed, 0x0b, 0xfb ],
-        [ 0xf4, 0xe1, 0xb1, 0x4a, 0xb4, 0x3c, 0xd9, 0x88 ],
-        [ 0x63, 0xe6, 0xc5, 0x43, 0xd6, 0x11, 0x0f, 0x54 ],
-        [ 0xbc, 0xd1, 0x21, 0x8c, 0x1f, 0xdd, 0x70, 0x23 ],
-        [ 0x0d, 0xb6, 0xa7, 0x16, 0x6c, 0x7b, 0x15, 0x81 ],
-        [ 0xbf, 0xf9, 0x8f, 0x7a, 0xe5, 0xb9, 0x54, 0x4d ],
-        [ 0x3e, 0x75, 0x2a, 0x1f, 0x78, 0x12, 0x9f, 0x75 ],
-        [ 0x91, 0x6b, 0x18, 0xbf, 0xbe, 0xa3, 0xa1, 0xce ],
-        [ 0x06, 0x62, 0xa2, 0xad, 0xd3, 0x08, 0xf5, 0x2c ],
-        [ 0x57, 0x30, 0xc3, 0xa3, 0x2d, 0x1c, 0x10, 0xb6 ],
-        [ 0xa1, 0x36, 0x3a, 0xae, 0x96, 0x74, 0xf4, 0xb3 ],
-        [ 0x92, 0x83, 0x10, 0x7b, 0x54, 0x57, 0x6b, 0x62 ],
-        [ 0x31, 0x15, 0xe4, 0x99, 0x32, 0x36, 0xd2, 0xc1 ],
-        [ 0x44, 0xd9, 0x1a, 0x3f, 0x92, 0xc1, 0x7c, 0x66 ],
-        [ 0x25, 0x88, 0x13, 0xc8, 0xfe, 0x4f, 0x70, 0x65 ],
-        [ 0xa6, 0x49, 0x89, 0xc2, 0xd1, 0x80, 0xf2, 0x24 ],
-        [ 0x6b, 0x87, 0xf8, 0xfa, 0xed, 0x1c, 0xca, 0xc2 ],
-        [ 0x96, 0x21, 0x04, 0x9f, 0xfc, 0x4b, 0x16, 0xc2 ],
-        [ 0x23, 0xd6, 0xb1, 0x68, 0x93, 0x9c, 0x6e, 0xa1 ],
-        [ 0xfd, 0x14, 0x51, 0x8b, 0x9c, 0x16, 0xfb, 0x49 ],
-        [ 0x46, 0x4c, 0x07, 0xdf, 0xf8, 0x43, 0x31, 0x9f ],
-        [ 0xb3, 0x86, 0xcc, 0x12, 0x24, 0xaf, 0xfd, 0xc6 ],
-        [ 0x8f, 0x09, 0x52, 0x0a, 0xd1, 0x49, 0xaf, 0x7e ],
-        [ 0x9a, 0x2f, 0x29, 0x9d, 0x55, 0x13, 0xf3, 0x1c ],
-        [ 0x12, 0x1f, 0xf4, 0xa2, 0xdd, 0x30, 0x4a, 0xc4 ],
-        [ 0xd0, 0x1e, 0xa7, 0x43, 0x89, 0xe9, 0xfa, 0x36 ],
-        [ 0xe6, 0xbc, 0xf0, 0x73, 0x4c, 0xb3, 0x8f, 0x31 ],
-        [ 0x80, 0xe9, 0xa7, 0x70, 0x36, 0xbf, 0x7a, 0xa2 ],
-        [ 0x75, 0x6d, 0x3c, 0x24, 0xdb, 0xc0, 0xbc, 0xb4 ],
-        [ 0x13, 0x15, 0xb7, 0xfd, 0x52, 0xd8, 0xf8, 0x23 ],
-        [ 0x08, 0x8a, 0x7d, 0xa6, 0x4d, 0x5f, 0x03, 0x8f ],
-        [ 0x48, 0xf1, 0xe8, 0xb7, 0xe5, 0xd0, 0x9c, 0xd8 ],
-        [ 0xee, 0x44, 0xa6, 0xf7, 0xbc, 0xe6, 0xf4, 0xf6 ],
-        [ 0xf2, 0x37, 0x18, 0x0f, 0xd8, 0x9a, 0xc5, 0xae ],
-        [ 0xe0, 0x94, 0x66, 0x4b, 0x15, 0xf6, 0xb2, 0xc3 ],
-        [ 0xa8, 0xb3, 0xbb, 0xb7, 0x62, 0x90, 0x19, 0x9d ]
-    ];
-
-    let k0 = 0x_07_06_05_04_03_02_01_00;
-    let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08;
-    let mut buf = Vec::new();
-    let mut t = 0;
-    let mut state_inc = SipHasher13::new_with_keys(k0, k1);
-
-    while t < 64 {
-        let vec = u8to64_le!(vecs[t], 0);
-        let out = hash_with(SipHasher13::new_with_keys(k0, k1), &Bytes(&buf));
-        assert_eq!(vec, out);
-
-        let full = hash_with(SipHasher13::new_with_keys(k0, k1), &Bytes(&buf));
-        let i = state_inc.finish();
-
-        assert_eq!(full, i);
-        assert_eq!(full, vec);
-
-        buf.push(t as u8);
-        Hasher::write(&mut state_inc, &[t as u8]);
-
-        t += 1;
-    }
-}
-
-#[test]
-#[allow(unused_must_use)]
-fn test_siphash_2_4() {
-    let vecs : [[u8; 8]; 64] = [
-        [ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, ],
-        [ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, ],
-        [ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, ],
-        [ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, ],
-        [ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, ],
-        [ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, ],
-        [ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, ],
-        [ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, ],
-        [ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, ],
-        [ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, ],
-        [ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, ],
-        [ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, ],
-        [ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, ],
-        [ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, ],
-        [ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, ],
-        [ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, ],
-        [ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, ],
-        [ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, ],
-        [ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, ],
-        [ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, ],
-        [ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, ],
-        [ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, ],
-        [ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, ],
-        [ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, ],
-        [ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, ],
-        [ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, ],
-        [ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, ],
-        [ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, ],
-        [ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, ],
-        [ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, ],
-        [ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, ],
-        [ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, ],
-        [ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, ],
-        [ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, ],
-        [ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, ],
-        [ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, ],
-        [ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, ],
-        [ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, ],
-        [ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, ],
-        [ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, ],
-        [ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, ],
-        [ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, ],
-        [ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, ],
-        [ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, ],
-        [ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, ],
-        [ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, ],
-        [ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, ],
-        [ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, ],
-        [ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, ],
-        [ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, ],
-        [ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, ],
-        [ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, ],
-        [ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, ],
-        [ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, ],
-        [ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, ],
-        [ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, ],
-        [ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, ],
-        [ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, ],
-        [ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, ],
-        [ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, ],
-        [ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, ],
-        [ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, ],
-        [ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, ],
-        [ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, ]
-    ];
-
-    let k0 = 0x_07_06_05_04_03_02_01_00;
-    let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08;
-    let mut buf = Vec::new();
-    let mut t = 0;
-    let mut state_inc = SipHasher24::new_with_keys(k0, k1);
-
-    while t < 64 {
-        let vec = u8to64_le!(vecs[t], 0);
-        let out = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf));
-        assert_eq!(vec, out);
-
-        let full = hash_with(SipHasher24::new_with_keys(k0, k1), &Bytes(&buf));
-        let i = state_inc.finish();
-
-        assert_eq!(full, i);
-        assert_eq!(full, vec);
-
-        buf.push(t as u8);
-        Hasher::write(&mut state_inc, &[t as u8]);
-
-        t += 1;
-    }
-}
-#[test] #[cfg(target_arch = "arm")]
-fn test_hash_usize() {
-    let val = 0xdeadbeef_deadbeef_u64;
-    assert!(hash(&(val as u64)) != hash(&(val as usize)));
-    assert_eq!(hash(&(val as u32)), hash(&(val as usize)));
-}
-#[test] #[cfg(target_arch = "x86_64")]
-fn test_hash_usize() {
-    let val = 0xdeadbeef_deadbeef_u64;
-    assert_eq!(hash(&(val as u64)), hash(&(val as usize)));
-    assert!(hash(&(val as u32)) != hash(&(val as usize)));
-}
-#[test] #[cfg(target_arch = "x86")]
-fn test_hash_usize() {
-    let val = 0xdeadbeef_deadbeef_u64;
-    assert!(hash(&(val as u64)) != hash(&(val as usize)));
-    assert_eq!(hash(&(val as u32)), hash(&(val as usize)));
-}
-
-#[test]
-fn test_hash_idempotent() {
-    let val64 = 0xdeadbeef_deadbeef_u64;
-    assert_eq!(hash(&val64), hash(&val64));
-    let val32 = 0xdeadbeef_u32;
-    assert_eq!(hash(&val32), hash(&val32));
-}
-
-#[test]
-fn test_hash_no_bytes_dropped_64() {
-    let val = 0xdeadbeef_deadbeef_u64;
-
-    assert!(hash(&val) != hash(&zero_byte(val, 0)));
-    assert!(hash(&val) != hash(&zero_byte(val, 1)));
-    assert!(hash(&val) != hash(&zero_byte(val, 2)));
-    assert!(hash(&val) != hash(&zero_byte(val, 3)));
-    assert!(hash(&val) != hash(&zero_byte(val, 4)));
-    assert!(hash(&val) != hash(&zero_byte(val, 5)));
-    assert!(hash(&val) != hash(&zero_byte(val, 6)));
-    assert!(hash(&val) != hash(&zero_byte(val, 7)));
-
-    fn zero_byte(val: u64, byte: usize) -> u64 {
-        assert!(byte < 8);
-        val & !(0xff << (byte * 8))
-    }
-}
-
-#[test]
-fn test_hash_no_bytes_dropped_32() {
-    let val = 0xdeadbeef_u32;
-
-    assert!(hash(&val) != hash(&zero_byte(val, 0)));
-    assert!(hash(&val) != hash(&zero_byte(val, 1)));
-    assert!(hash(&val) != hash(&zero_byte(val, 2)));
-    assert!(hash(&val) != hash(&zero_byte(val, 3)));
-
-    fn zero_byte(val: u32, byte: usize) -> u32 {
-        assert!(byte < 4);
-        val & !(0xff << (byte * 8))
-    }
-}
-
-#[test]
-fn test_hash_no_concat_alias() {
-    let s = ("aa", "bb");
-    let t = ("aabb", "");
-    let u = ("a", "abb");
-
-    assert!(s != t && t != u);
-    assert!(hash(&s) != hash(&t) && hash(&s) != hash(&u));
-
-    let u = [1, 0, 0, 0];
-    let v = (&u[..1], &u[1..3], &u[3..]);
-    let w = (&u[..], &u[4..4], &u[4..4]);
-
-    assert!(v != w);
-    assert!(hash(&v) != hash(&w));
-}
-
-#[test]
-fn test_write_short_works() {
-    let test_usize = 0xd0c0b0a0usize;
-    let mut h1 = SipHasher24::new();
-    h1.write_usize(test_usize);
-    h1.write(b"bytes");
-    h1.write(b"string");
-    h1.write_u8(0xFFu8);
-    h1.write_u8(0x01u8);
-    let mut h2 = SipHasher24::new();
-    h2.write(unsafe {
-        slice::from_raw_parts(&test_usize as *const _ as *const u8,
-                              mem::size_of::<usize>())
-    });
-    h2.write(b"bytes");
-    h2.write(b"string");
-    h2.write(&[0xFFu8, 0x01u8]);
-    assert_eq!(h1.finish(), h2.finish());
-}
diff --git a/src/libcoretest/intrinsics.rs b/src/libcoretest/intrinsics.rs
deleted file mode 100644 (file)
index 2b380ab..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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 core::any::TypeId;
-
-#[test]
-fn test_typeid_sized_types() {
-    struct X; struct Y(u32);
-
-    assert_eq!(TypeId::of::<X>(), TypeId::of::<X>());
-    assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());
-    assert!(TypeId::of::<X>() != TypeId::of::<Y>());
-}
-
-#[test]
-fn test_typeid_unsized_types() {
-    trait Z {}
-    struct X(str); struct Y(Z + 'static);
-
-    assert_eq!(TypeId::of::<X>(), TypeId::of::<X>());
-    assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());
-    assert!(TypeId::of::<X>() != TypeId::of::<Y>());
-}
diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs
deleted file mode 100644 (file)
index 08442f9..0000000
+++ /dev/null
@@ -1,1084 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use core::iter::*;
-use core::{i8, i16, isize};
-use core::usize;
-
-#[test]
-fn test_lt() {
-    let empty: [isize; 0] = [];
-    let xs = [1,2,3];
-    let ys = [1,2,0];
-
-    assert!(!xs.iter().lt(ys.iter()));
-    assert!(!xs.iter().le(ys.iter()));
-    assert!( xs.iter().gt(ys.iter()));
-    assert!( xs.iter().ge(ys.iter()));
-
-    assert!( ys.iter().lt(xs.iter()));
-    assert!( ys.iter().le(xs.iter()));
-    assert!(!ys.iter().gt(xs.iter()));
-    assert!(!ys.iter().ge(xs.iter()));
-
-    assert!( empty.iter().lt(xs.iter()));
-    assert!( empty.iter().le(xs.iter()));
-    assert!(!empty.iter().gt(xs.iter()));
-    assert!(!empty.iter().ge(xs.iter()));
-
-    // Sequence with NaN
-    let u = [1.0f64, 2.0];
-    let v = [0.0f64/0.0, 3.0];
-
-    assert!(!u.iter().lt(v.iter()));
-    assert!(!u.iter().le(v.iter()));
-    assert!(!u.iter().gt(v.iter()));
-    assert!(!u.iter().ge(v.iter()));
-
-    let a = [0.0f64/0.0];
-    let b = [1.0f64];
-    let c = [2.0f64];
-
-    assert!(a.iter().lt(b.iter()) == (a[0] <  b[0]));
-    assert!(a.iter().le(b.iter()) == (a[0] <= b[0]));
-    assert!(a.iter().gt(b.iter()) == (a[0] >  b[0]));
-    assert!(a.iter().ge(b.iter()) == (a[0] >= b[0]));
-
-    assert!(c.iter().lt(b.iter()) == (c[0] <  b[0]));
-    assert!(c.iter().le(b.iter()) == (c[0] <= b[0]));
-    assert!(c.iter().gt(b.iter()) == (c[0] >  b[0]));
-    assert!(c.iter().ge(b.iter()) == (c[0] >= b[0]));
-}
-
-#[test]
-fn test_multi_iter() {
-    let xs = [1,2,3,4];
-    let ys = [4,3,2,1];
-    assert!(xs.iter().eq(ys.iter().rev()));
-    assert!(xs.iter().lt(xs.iter().skip(2)));
-}
-
-#[test]
-fn test_counter_from_iter() {
-    let it = (0..).step_by(5).take(10);
-    let xs: Vec<isize> = FromIterator::from_iter(it);
-    assert_eq!(xs, [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
-}
-
-#[test]
-fn test_iterator_chain() {
-    let xs = [0, 1, 2, 3, 4, 5];
-    let ys = [30, 40, 50, 60];
-    let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
-    let it = xs.iter().chain(&ys);
-    let mut i = 0;
-    for &x in it {
-        assert_eq!(x, expected[i]);
-        i += 1;
-    }
-    assert_eq!(i, expected.len());
-
-    let ys = (30..).step_by(10).take(4);
-    let it = xs.iter().cloned().chain(ys);
-    let mut i = 0;
-    for x in it {
-        assert_eq!(x, expected[i]);
-        i += 1;
-    }
-    assert_eq!(i, expected.len());
-}
-
-#[test]
-fn test_iterator_chain_nth() {
-    let xs = [0, 1, 2, 3, 4, 5];
-    let ys = [30, 40, 50, 60];
-    let zs = [];
-    let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
-    for (i, x) in expected.iter().enumerate() {
-        assert_eq!(Some(x), xs.iter().chain(&ys).nth(i));
-    }
-    assert_eq!(zs.iter().chain(&xs).nth(0), Some(&0));
-
-    let mut it = xs.iter().chain(&zs);
-    assert_eq!(it.nth(5), Some(&5));
-    assert_eq!(it.next(), None);
-}
-
-#[test]
-fn test_iterator_chain_last() {
-    let xs = [0, 1, 2, 3, 4, 5];
-    let ys = [30, 40, 50, 60];
-    let zs = [];
-    assert_eq!(xs.iter().chain(&ys).last(), Some(&60));
-    assert_eq!(zs.iter().chain(&ys).last(), Some(&60));
-    assert_eq!(ys.iter().chain(&zs).last(), Some(&60));
-    assert_eq!(zs.iter().chain(&zs).last(), None);
-}
-
-#[test]
-fn test_iterator_chain_count() {
-    let xs = [0, 1, 2, 3, 4, 5];
-    let ys = [30, 40, 50, 60];
-    let zs = [];
-    assert_eq!(xs.iter().chain(&ys).count(), 10);
-    assert_eq!(zs.iter().chain(&ys).count(), 4);
-}
-
-#[test]
-fn test_iterator_chain_find() {
-    let xs = [0, 1, 2, 3, 4, 5];
-    let ys = [30, 40, 50, 60];
-    let mut iter = xs.iter().chain(&ys);
-    assert_eq!(iter.find(|&&i| i == 4), Some(&4));
-    assert_eq!(iter.next(), Some(&5));
-    assert_eq!(iter.find(|&&i| i == 40), Some(&40));
-    assert_eq!(iter.next(), Some(&50));
-    assert_eq!(iter.find(|&&i| i == 100), None);
-    assert_eq!(iter.next(), None);
-}
-
-#[test]
-fn test_filter_map() {
-    let it = (0..).step_by(1).take(10)
-        .filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None });
-    assert_eq!(it.collect::<Vec<usize>>(), [0*0, 2*2, 4*4, 6*6, 8*8]);
-}
-
-#[test]
-fn test_iterator_enumerate() {
-    let xs = [0, 1, 2, 3, 4, 5];
-    let it = xs.iter().enumerate();
-    for (i, &x) in it {
-        assert_eq!(i, x);
-    }
-}
-
-#[test]
-fn test_iterator_enumerate_nth() {
-    let xs = [0, 1, 2, 3, 4, 5];
-    for (i, &x) in xs.iter().enumerate() {
-        assert_eq!(i, x);
-    }
-
-    let mut it = xs.iter().enumerate();
-    while let Some((i, &x)) = it.nth(0) {
-        assert_eq!(i, x);
-    }
-
-    let mut it = xs.iter().enumerate();
-    while let Some((i, &x)) = it.nth(1) {
-        assert_eq!(i, x);
-    }
-
-    let (i, &x) = xs.iter().enumerate().nth(3).unwrap();
-    assert_eq!(i, x);
-    assert_eq!(i, 3);
-}
-
-#[test]
-fn test_iterator_enumerate_count() {
-    let xs = [0, 1, 2, 3, 4, 5];
-    assert_eq!(xs.iter().count(), 6);
-}
-
-#[test]
-fn test_iterator_filter_count() {
-    let xs = [0, 1, 2, 3, 4, 5, 6, 7, 8];
-    assert_eq!(xs.iter().filter(|&&x| x % 2 == 0).count(), 5);
-}
-
-#[test]
-fn test_iterator_peekable() {
-    let xs = vec![0, 1, 2, 3, 4, 5];
-    let mut it = xs.iter().cloned().peekable();
-
-    assert_eq!(it.len(), 6);
-    assert_eq!(it.peek().unwrap(), &0);
-    assert_eq!(it.len(), 6);
-    assert_eq!(it.next().unwrap(), 0);
-    assert_eq!(it.len(), 5);
-    assert_eq!(it.next().unwrap(), 1);
-    assert_eq!(it.len(), 4);
-    assert_eq!(it.next().unwrap(), 2);
-    assert_eq!(it.len(), 3);
-    assert_eq!(it.peek().unwrap(), &3);
-    assert_eq!(it.len(), 3);
-    assert_eq!(it.peek().unwrap(), &3);
-    assert_eq!(it.len(), 3);
-    assert_eq!(it.next().unwrap(), 3);
-    assert_eq!(it.len(), 2);
-    assert_eq!(it.next().unwrap(), 4);
-    assert_eq!(it.len(), 1);
-    assert_eq!(it.peek().unwrap(), &5);
-    assert_eq!(it.len(), 1);
-    assert_eq!(it.next().unwrap(), 5);
-    assert_eq!(it.len(), 0);
-    assert!(it.peek().is_none());
-    assert_eq!(it.len(), 0);
-    assert!(it.next().is_none());
-    assert_eq!(it.len(), 0);
-}
-
-#[test]
-fn test_iterator_peekable_count() {
-    let xs = [0, 1, 2, 3, 4, 5];
-    let ys = [10];
-    let zs: [i32; 0] = [];
-
-    assert_eq!(xs.iter().peekable().count(), 6);
-
-    let mut it = xs.iter().peekable();
-    assert_eq!(it.peek(), Some(&&0));
-    assert_eq!(it.count(), 6);
-
-    assert_eq!(ys.iter().peekable().count(), 1);
-
-    let mut it = ys.iter().peekable();
-    assert_eq!(it.peek(), Some(&&10));
-    assert_eq!(it.count(), 1);
-
-    assert_eq!(zs.iter().peekable().count(), 0);
-
-    let mut it = zs.iter().peekable();
-    assert_eq!(it.peek(), None);
-
-}
-
-#[test]
-fn test_iterator_peekable_nth() {
-    let xs = [0, 1, 2, 3, 4, 5];
-    let mut it = xs.iter().peekable();
-
-    assert_eq!(it.peek(), Some(&&0));
-    assert_eq!(it.nth(0), Some(&0));
-    assert_eq!(it.peek(), Some(&&1));
-    assert_eq!(it.nth(1), Some(&2));
-    assert_eq!(it.peek(), Some(&&3));
-    assert_eq!(it.nth(2), Some(&5));
-    assert_eq!(it.next(), None);
-}
-
-#[test]
-fn test_iterator_peekable_last() {
-    let xs = [0, 1, 2, 3, 4, 5];
-    let ys = [0];
-
-    let mut it = xs.iter().peekable();
-    assert_eq!(it.peek(), Some(&&0));
-    assert_eq!(it.last(), Some(&5));
-
-    let mut it = ys.iter().peekable();
-    assert_eq!(it.peek(), Some(&&0));
-    assert_eq!(it.last(), Some(&0));
-
-    let mut it = ys.iter().peekable();
-    assert_eq!(it.next(), Some(&0));
-    assert_eq!(it.peek(), None);
-    assert_eq!(it.last(), None);
-}
-
-/// This is an iterator that follows the Iterator contract,
-/// but it is not fused. After having returned None once, it will start
-/// producing elements if .next() is called again.
-pub struct CycleIter<'a, T: 'a> {
-    index: usize,
-    data: &'a [T],
-}
-
-pub fn cycle<T>(data: &[T]) -> CycleIter<T> {
-    CycleIter {
-        index: 0,
-        data: data,
-    }
-}
-
-impl<'a, T> Iterator for CycleIter<'a, T> {
-    type Item = &'a T;
-    fn next(&mut self) -> Option<Self::Item> {
-        let elt = self.data.get(self.index);
-        self.index += 1;
-        self.index %= 1 + self.data.len();
-        elt
-    }
-}
-
-#[test]
-fn test_iterator_peekable_remember_peek_none_1() {
-    // Check that the loop using .peek() terminates
-    let data = [1, 2, 3];
-    let mut iter = cycle(&data).peekable();
-
-    let mut n = 0;
-    while let Some(_) = iter.next() {
-        let is_the_last = iter.peek().is_none();
-        assert_eq!(is_the_last, n == data.len() - 1);
-        n += 1;
-        if n > data.len() { break; }
-    }
-    assert_eq!(n, data.len());
-}
-
-#[test]
-fn test_iterator_peekable_remember_peek_none_2() {
-    let data = [0];
-    let mut iter = cycle(&data).peekable();
-    iter.next();
-    assert_eq!(iter.peek(), None);
-    assert_eq!(iter.last(), None);
-}
-
-#[test]
-fn test_iterator_peekable_remember_peek_none_3() {
-    let data = [0];
-    let mut iter = cycle(&data).peekable();
-    iter.peek();
-    assert_eq!(iter.nth(0), Some(&0));
-
-    let mut iter = cycle(&data).peekable();
-    iter.next();
-    assert_eq!(iter.peek(), None);
-    assert_eq!(iter.nth(0), None);
-}
-
-#[test]
-fn test_iterator_take_while() {
-    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19];
-    let ys = [0, 1, 2, 3, 5, 13];
-    let it = xs.iter().take_while(|&x| *x < 15);
-    let mut i = 0;
-    for x in it {
-        assert_eq!(*x, ys[i]);
-        i += 1;
-    }
-    assert_eq!(i, ys.len());
-}
-
-#[test]
-fn test_iterator_skip_while() {
-    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19];
-    let ys = [15, 16, 17, 19];
-    let it = xs.iter().skip_while(|&x| *x < 15);
-    let mut i = 0;
-    for x in it {
-        assert_eq!(*x, ys[i]);
-        i += 1;
-    }
-    assert_eq!(i, ys.len());
-}
-
-#[test]
-fn test_iterator_skip() {
-    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
-    let ys = [13, 15, 16, 17, 19, 20, 30];
-    let mut it = xs.iter().skip(5);
-    let mut i = 0;
-    while let Some(&x) = it.next() {
-        assert_eq!(x, ys[i]);
-        i += 1;
-        assert_eq!(it.len(), xs.len()-5-i);
-    }
-    assert_eq!(i, ys.len());
-    assert_eq!(it.len(), 0);
-}
-
-#[test]
-fn test_iterator_skip_doubleended() {
-    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
-    let mut it = xs.iter().rev().skip(5);
-    assert_eq!(it.next(), Some(&15));
-    assert_eq!(it.by_ref().rev().next(), Some(&0));
-    assert_eq!(it.next(), Some(&13));
-    assert_eq!(it.by_ref().rev().next(), Some(&1));
-    assert_eq!(it.next(), Some(&5));
-    assert_eq!(it.by_ref().rev().next(), Some(&2));
-    assert_eq!(it.next(), Some(&3));
-    assert_eq!(it.next(), None);
-    let mut it = xs.iter().rev().skip(5).rev();
-    assert_eq!(it.next(), Some(&0));
-    assert_eq!(it.rev().next(), Some(&15));
-    let mut it_base = xs.iter();
-    {
-        let mut it = it_base.by_ref().skip(5).rev();
-        assert_eq!(it.next(), Some(&30));
-        assert_eq!(it.next(), Some(&20));
-        assert_eq!(it.next(), Some(&19));
-        assert_eq!(it.next(), Some(&17));
-        assert_eq!(it.next(), Some(&16));
-        assert_eq!(it.next(), Some(&15));
-        assert_eq!(it.next(), Some(&13));
-        assert_eq!(it.next(), None);
-    }
-    // make sure the skipped parts have not been consumed
-    assert_eq!(it_base.next(), Some(&0));
-    assert_eq!(it_base.next(), Some(&1));
-    assert_eq!(it_base.next(), Some(&2));
-    assert_eq!(it_base.next(), Some(&3));
-    assert_eq!(it_base.next(), Some(&5));
-    assert_eq!(it_base.next(), None);
-    let it = xs.iter().skip(5).rev();
-    assert_eq!(it.last(), Some(&13));
-}
-
-#[test]
-fn test_iterator_skip_nth() {
-    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
-
-    let mut it = xs.iter().skip(0);
-    assert_eq!(it.nth(0), Some(&0));
-    assert_eq!(it.nth(1), Some(&2));
-
-    let mut it = xs.iter().skip(5);
-    assert_eq!(it.nth(0), Some(&13));
-    assert_eq!(it.nth(1), Some(&16));
-
-    let mut it = xs.iter().skip(12);
-    assert_eq!(it.nth(0), None);
-
-}
-
-#[test]
-fn test_iterator_skip_count() {
-    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
-
-    assert_eq!(xs.iter().skip(0).count(), 12);
-    assert_eq!(xs.iter().skip(1).count(), 11);
-    assert_eq!(xs.iter().skip(11).count(), 1);
-    assert_eq!(xs.iter().skip(12).count(), 0);
-    assert_eq!(xs.iter().skip(13).count(), 0);
-}
-
-#[test]
-fn test_iterator_skip_last() {
-    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
-
-    assert_eq!(xs.iter().skip(0).last(), Some(&30));
-    assert_eq!(xs.iter().skip(1).last(), Some(&30));
-    assert_eq!(xs.iter().skip(11).last(), Some(&30));
-    assert_eq!(xs.iter().skip(12).last(), None);
-    assert_eq!(xs.iter().skip(13).last(), None);
-
-    let mut it = xs.iter().skip(5);
-    assert_eq!(it.next(), Some(&13));
-    assert_eq!(it.last(), Some(&30));
-}
-
-#[test]
-fn test_iterator_take() {
-    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19];
-    let ys = [0, 1, 2, 3, 5];
-    let mut it = xs.iter().take(5);
-    let mut i = 0;
-    assert_eq!(it.len(), 5);
-    while let Some(&x) = it.next() {
-        assert_eq!(x, ys[i]);
-        i += 1;
-        assert_eq!(it.len(), 5-i);
-    }
-    assert_eq!(i, ys.len());
-    assert_eq!(it.len(), 0);
-}
-
-#[test]
-fn test_iterator_take_nth() {
-    let xs = [0, 1, 2, 4, 5];
-    let mut it = xs.iter();
-    {
-        let mut take = it.by_ref().take(3);
-        let mut i = 0;
-        while let Some(&x) = take.nth(0) {
-            assert_eq!(x, i);
-            i += 1;
-        }
-    }
-    assert_eq!(it.nth(1), Some(&5));
-    assert_eq!(it.nth(0), None);
-
-    let xs = [0, 1, 2, 3, 4];
-    let mut it = xs.iter().take(7);
-    let mut i = 1;
-    while let Some(&x) = it.nth(1) {
-        assert_eq!(x, i);
-        i += 2;
-    }
-}
-
-#[test]
-fn test_iterator_take_short() {
-    let xs = [0, 1, 2, 3];
-    let ys = [0, 1, 2, 3];
-    let mut it = xs.iter().take(5);
-    let mut i = 0;
-    assert_eq!(it.len(), 4);
-    while let Some(&x) = it.next() {
-        assert_eq!(x, ys[i]);
-        i += 1;
-        assert_eq!(it.len(), 4-i);
-    }
-    assert_eq!(i, ys.len());
-    assert_eq!(it.len(), 0);
-}
-
-#[test]
-fn test_iterator_scan() {
-    // test the type inference
-    fn add(old: &mut isize, new: &usize) -> Option<f64> {
-        *old += *new as isize;
-        Some(*old as f64)
-    }
-    let xs = [0, 1, 2, 3, 4];
-    let ys = [0f64, 1.0, 3.0, 6.0, 10.0];
-
-    let it = xs.iter().scan(0, add);
-    let mut i = 0;
-    for x in it {
-        assert_eq!(x, ys[i]);
-        i += 1;
-    }
-    assert_eq!(i, ys.len());
-}
-
-#[test]
-fn test_iterator_flat_map() {
-    let xs = [0, 3, 6];
-    let ys = [0, 1, 2, 3, 4, 5, 6, 7, 8];
-    let it = xs.iter().flat_map(|&x| (x..).step_by(1).take(3));
-    let mut i = 0;
-    for x in it {
-        assert_eq!(x, ys[i]);
-        i += 1;
-    }
-    assert_eq!(i, ys.len());
-}
-
-#[test]
-fn test_inspect() {
-    let xs = [1, 2, 3, 4];
-    let mut n = 0;
-
-    let ys = xs.iter()
-               .cloned()
-               .inspect(|_| n += 1)
-               .collect::<Vec<usize>>();
-
-    assert_eq!(n, xs.len());
-    assert_eq!(&xs[..], &ys[..]);
-}
-
-#[test]
-fn test_cycle() {
-    let cycle_len = 3;
-    let it = (0..).step_by(1).take(cycle_len).cycle();
-    assert_eq!(it.size_hint(), (usize::MAX, None));
-    for (i, x) in it.take(100).enumerate() {
-        assert_eq!(i % cycle_len, x);
-    }
-
-    let mut it = (0..).step_by(1).take(0).cycle();
-    assert_eq!(it.size_hint(), (0, Some(0)));
-    assert_eq!(it.next(), None);
-}
-
-#[test]
-fn test_iterator_nth() {
-    let v: &[_] = &[0, 1, 2, 3, 4];
-    for i in 0..v.len() {
-        assert_eq!(v.iter().nth(i).unwrap(), &v[i]);
-    }
-    assert_eq!(v.iter().nth(v.len()), None);
-}
-
-#[test]
-fn test_iterator_last() {
-    let v: &[_] = &[0, 1, 2, 3, 4];
-    assert_eq!(v.iter().last().unwrap(), &4);
-    assert_eq!(v[..1].iter().last().unwrap(), &0);
-}
-
-#[test]
-fn test_iterator_len() {
-    let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().count(), 4);
-    assert_eq!(v[..10].iter().count(), 10);
-    assert_eq!(v[..0].iter().count(), 0);
-}
-
-#[test]
-fn test_iterator_sum() {
-    let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().cloned().sum::<i32>(), 6);
-    assert_eq!(v.iter().cloned().sum::<i32>(), 55);
-    assert_eq!(v[..0].iter().cloned().sum::<i32>(), 0);
-}
-
-#[test]
-fn test_iterator_sum_result() {
-    let v: &[Result<i32, ()>] = &[Ok(1), Ok(2), Ok(3), Ok(4)];
-    assert_eq!(v.iter().cloned().sum::<Result<i32, _>>(), Ok(10));
-    let v: &[Result<i32, ()>] = &[Ok(1), Err(()), Ok(3), Ok(4)];
-    assert_eq!(v.iter().cloned().sum::<Result<i32, _>>(), Err(()));
-}
-
-#[test]
-fn test_iterator_product() {
-    let v: &[i32] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().cloned().product::<i32>(), 0);
-    assert_eq!(v[1..5].iter().cloned().product::<i32>(), 24);
-    assert_eq!(v[..0].iter().cloned().product::<i32>(), 1);
-}
-
-#[test]
-fn test_iterator_product_result() {
-    let v: &[Result<i32, ()>] = &[Ok(1), Ok(2), Ok(3), Ok(4)];
-    assert_eq!(v.iter().cloned().product::<Result<i32, _>>(), Ok(24));
-    let v: &[Result<i32, ()>] = &[Ok(1), Err(()), Ok(3), Ok(4)];
-    assert_eq!(v.iter().cloned().product::<Result<i32, _>>(), Err(()));
-}
-
-#[test]
-fn test_iterator_max() {
-    let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().cloned().max(), Some(3));
-    assert_eq!(v.iter().cloned().max(), Some(10));
-    assert_eq!(v[..0].iter().cloned().max(), None);
-}
-
-#[test]
-fn test_iterator_min() {
-    let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
-    assert_eq!(v[..4].iter().cloned().min(), Some(0));
-    assert_eq!(v.iter().cloned().min(), Some(0));
-    assert_eq!(v[..0].iter().cloned().min(), None);
-}
-
-#[test]
-fn test_iterator_size_hint() {
-    let c = (0..).step_by(1);
-    let v: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
-    let v2 = &[10, 11, 12];
-    let vi = v.iter();
-
-    assert_eq!(c.size_hint(), (usize::MAX, None));
-    assert_eq!(vi.clone().size_hint(), (10, Some(10)));
-
-    assert_eq!(c.clone().take(5).size_hint(), (5, Some(5)));
-    assert_eq!(c.clone().skip(5).size_hint().1, None);
-    assert_eq!(c.clone().take_while(|_| false).size_hint(), (0, None));
-    assert_eq!(c.clone().skip_while(|_| false).size_hint(), (0, None));
-    assert_eq!(c.clone().enumerate().size_hint(), (usize::MAX, None));
-    assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (usize::MAX, None));
-    assert_eq!(c.clone().zip(vi.clone()).size_hint(), (10, Some(10)));
-    assert_eq!(c.clone().scan(0, |_,_| Some(0)).size_hint(), (0, None));
-    assert_eq!(c.clone().filter(|_| false).size_hint(), (0, None));
-    assert_eq!(c.clone().map(|_| 0).size_hint(), (usize::MAX, None));
-    assert_eq!(c.filter_map(|_| Some(0)).size_hint(), (0, None));
-
-    assert_eq!(vi.clone().take(5).size_hint(), (5, Some(5)));
-    assert_eq!(vi.clone().take(12).size_hint(), (10, Some(10)));
-    assert_eq!(vi.clone().skip(3).size_hint(), (7, Some(7)));
-    assert_eq!(vi.clone().skip(12).size_hint(), (0, Some(0)));
-    assert_eq!(vi.clone().take_while(|_| false).size_hint(), (0, Some(10)));
-    assert_eq!(vi.clone().skip_while(|_| false).size_hint(), (0, Some(10)));
-    assert_eq!(vi.clone().enumerate().size_hint(), (10, Some(10)));
-    assert_eq!(vi.clone().chain(v2).size_hint(), (13, Some(13)));
-    assert_eq!(vi.clone().zip(v2).size_hint(), (3, Some(3)));
-    assert_eq!(vi.clone().scan(0, |_,_| Some(0)).size_hint(), (0, Some(10)));
-    assert_eq!(vi.clone().filter(|_| false).size_hint(), (0, Some(10)));
-    assert_eq!(vi.clone().map(|&i| i+1).size_hint(), (10, Some(10)));
-    assert_eq!(vi.filter_map(|_| Some(0)).size_hint(), (0, Some(10)));
-}
-
-#[test]
-fn test_collect() {
-    let a = vec![1, 2, 3, 4, 5];
-    let b: Vec<isize> = a.iter().cloned().collect();
-    assert!(a == b);
-}
-
-#[test]
-fn test_all() {
-    let v: Box<[isize]> = Box::new([1, 2, 3, 4, 5]);
-    assert!(v.iter().all(|&x| x < 10));
-    assert!(!v.iter().all(|&x| x % 2 == 0));
-    assert!(!v.iter().all(|&x| x > 100));
-    assert!(v[..0].iter().all(|_| panic!()));
-}
-
-#[test]
-fn test_any() {
-    let v: Box<[isize]> = Box::new([1, 2, 3, 4, 5]);
-    assert!(v.iter().any(|&x| x < 10));
-    assert!(v.iter().any(|&x| x % 2 == 0));
-    assert!(!v.iter().any(|&x| x > 100));
-    assert!(!v[..0].iter().any(|_| panic!()));
-}
-
-#[test]
-fn test_find() {
-    let v: &[isize] = &[1, 3, 9, 27, 103, 14, 11];
-    assert_eq!(*v.iter().find(|&&x| x & 1 == 0).unwrap(), 14);
-    assert_eq!(*v.iter().find(|&&x| x % 3 == 0).unwrap(), 3);
-    assert!(v.iter().find(|&&x| x % 12 == 0).is_none());
-}
-
-#[test]
-fn test_position() {
-    let v = &[1, 3, 9, 27, 103, 14, 11];
-    assert_eq!(v.iter().position(|x| *x & 1 == 0).unwrap(), 5);
-    assert_eq!(v.iter().position(|x| *x % 3 == 0).unwrap(), 1);
-    assert!(v.iter().position(|x| *x % 12 == 0).is_none());
-}
-
-#[test]
-fn test_count() {
-    let xs = &[1, 2, 2, 1, 5, 9, 0, 2];
-    assert_eq!(xs.iter().filter(|x| **x == 2).count(), 3);
-    assert_eq!(xs.iter().filter(|x| **x == 5).count(), 1);
-    assert_eq!(xs.iter().filter(|x| **x == 95).count(), 0);
-}
-
-#[test]
-fn test_max_by_key() {
-    let xs: &[isize] = &[-3, 0, 1, 5, -10];
-    assert_eq!(*xs.iter().max_by_key(|x| x.abs()).unwrap(), -10);
-}
-
-#[test]
-fn test_max_by() {
-    let xs: &[isize] = &[-3, 0, 1, 5, -10];
-    assert_eq!(*xs.iter().max_by(|x, y| x.abs().cmp(&y.abs())).unwrap(), -10);
-}
-
-#[test]
-fn test_min_by_key() {
-    let xs: &[isize] = &[-3, 0, 1, 5, -10];
-    assert_eq!(*xs.iter().min_by_key(|x| x.abs()).unwrap(), 0);
-}
-
-#[test]
-fn test_min_by() {
-    let xs: &[isize] = &[-3, 0, 1, 5, -10];
-    assert_eq!(*xs.iter().min_by(|x, y| x.abs().cmp(&y.abs())).unwrap(), 0);
-}
-
-#[test]
-fn test_by_ref() {
-    let mut xs = 0..10;
-    // sum the first five values
-    let partial_sum = xs.by_ref().take(5).fold(0, |a, b| a + b);
-    assert_eq!(partial_sum, 10);
-    assert_eq!(xs.next(), Some(5));
-}
-
-#[test]
-fn test_rev() {
-    let xs = [2, 4, 6, 8, 10, 12, 14, 16];
-    let mut it = xs.iter();
-    it.next();
-    it.next();
-    assert!(it.rev().cloned().collect::<Vec<isize>>() ==
-            vec![16, 14, 12, 10, 8, 6]);
-}
-
-#[test]
-fn test_cloned() {
-    let xs = [2, 4, 6, 8];
-
-    let mut it = xs.iter().cloned();
-    assert_eq!(it.len(), 4);
-    assert_eq!(it.next(), Some(2));
-    assert_eq!(it.len(), 3);
-    assert_eq!(it.next(), Some(4));
-    assert_eq!(it.len(), 2);
-    assert_eq!(it.next_back(), Some(8));
-    assert_eq!(it.len(), 1);
-    assert_eq!(it.next_back(), Some(6));
-    assert_eq!(it.len(), 0);
-    assert_eq!(it.next_back(), None);
-}
-
-#[test]
-fn test_double_ended_map() {
-    let xs = [1, 2, 3, 4, 5, 6];
-    let mut it = xs.iter().map(|&x| x * -1);
-    assert_eq!(it.next(), Some(-1));
-    assert_eq!(it.next(), Some(-2));
-    assert_eq!(it.next_back(), Some(-6));
-    assert_eq!(it.next_back(), Some(-5));
-    assert_eq!(it.next(), Some(-3));
-    assert_eq!(it.next_back(), Some(-4));
-    assert_eq!(it.next(), None);
-}
-
-#[test]
-fn test_double_ended_enumerate() {
-    let xs = [1, 2, 3, 4, 5, 6];
-    let mut it = xs.iter().cloned().enumerate();
-    assert_eq!(it.next(), Some((0, 1)));
-    assert_eq!(it.next(), Some((1, 2)));
-    assert_eq!(it.next_back(), Some((5, 6)));
-    assert_eq!(it.next_back(), Some((4, 5)));
-    assert_eq!(it.next_back(), Some((3, 4)));
-    assert_eq!(it.next_back(), Some((2, 3)));
-    assert_eq!(it.next(), None);
-}
-
-#[test]
-fn test_double_ended_zip() {
-    let xs = [1, 2, 3, 4, 5, 6];
-    let ys = [1, 2, 3, 7];
-    let a = xs.iter().cloned();
-    let b = ys.iter().cloned();
-    let mut it = a.zip(b);
-    assert_eq!(it.next(), Some((1, 1)));
-    assert_eq!(it.next(), Some((2, 2)));
-    assert_eq!(it.next_back(), Some((4, 7)));
-    assert_eq!(it.next_back(), Some((3, 3)));
-    assert_eq!(it.next(), None);
-}
-
-#[test]
-fn test_double_ended_filter() {
-    let xs = [1, 2, 3, 4, 5, 6];
-    let mut it = xs.iter().filter(|&x| *x & 1 == 0);
-    assert_eq!(it.next_back().unwrap(), &6);
-    assert_eq!(it.next_back().unwrap(), &4);
-    assert_eq!(it.next().unwrap(), &2);
-    assert_eq!(it.next_back(), None);
-}
-
-#[test]
-fn test_double_ended_filter_map() {
-    let xs = [1, 2, 3, 4, 5, 6];
-    let mut it = xs.iter().filter_map(|&x| if x & 1 == 0 { Some(x * 2) } else { None });
-    assert_eq!(it.next_back().unwrap(), 12);
-    assert_eq!(it.next_back().unwrap(), 8);
-    assert_eq!(it.next().unwrap(), 4);
-    assert_eq!(it.next_back(), None);
-}
-
-#[test]
-fn test_double_ended_chain() {
-    let xs = [1, 2, 3, 4, 5];
-    let ys = [7, 9, 11];
-    let mut it = xs.iter().chain(&ys).rev();
-    assert_eq!(it.next().unwrap(), &11);
-    assert_eq!(it.next().unwrap(), &9);
-    assert_eq!(it.next_back().unwrap(), &1);
-    assert_eq!(it.next_back().unwrap(), &2);
-    assert_eq!(it.next_back().unwrap(), &3);
-    assert_eq!(it.next_back().unwrap(), &4);
-    assert_eq!(it.next_back().unwrap(), &5);
-    assert_eq!(it.next_back().unwrap(), &7);
-    assert_eq!(it.next_back(), None);
-
-
-    // test that .chain() is well behaved with an unfused iterator
-    struct CrazyIterator(bool);
-    impl CrazyIterator { fn new() -> CrazyIterator { CrazyIterator(false) } }
-    impl Iterator for CrazyIterator {
-        type Item = i32;
-        fn next(&mut self) -> Option<i32> {
-            if self.0 { Some(99) } else { self.0 = true; None }
-        }
-    }
-
-    impl DoubleEndedIterator for CrazyIterator {
-        fn next_back(&mut self) -> Option<i32> {
-            self.next()
-        }
-    }
-
-    assert_eq!(CrazyIterator::new().chain(0..10).rev().last(), Some(0));
-    assert!((0..10).chain(CrazyIterator::new()).rev().any(|i| i == 0));
-}
-
-#[test]
-fn test_rposition() {
-    fn f(xy: &(isize, char)) -> bool { let (_x, y) = *xy; y == 'b' }
-    fn g(xy: &(isize, char)) -> bool { let (_x, y) = *xy; y == 'd' }
-    let v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
-
-    assert_eq!(v.iter().rposition(f), Some(3));
-    assert!(v.iter().rposition(g).is_none());
-}
-
-#[test]
-#[should_panic]
-fn test_rposition_panic() {
-    let v: [(Box<_>, Box<_>); 4] =
-        [(box 0, box 0), (box 0, box 0),
-         (box 0, box 0), (box 0, box 0)];
-    let mut i = 0;
-    v.iter().rposition(|_elt| {
-        if i == 2 {
-            panic!()
-        }
-        i += 1;
-        false
-    });
-}
-
-
-#[test]
-fn test_double_ended_flat_map() {
-    let u = [0,1];
-    let v = [5,6,7,8];
-    let mut it = u.iter().flat_map(|x| &v[*x..v.len()]);
-    assert_eq!(it.next_back().unwrap(), &8);
-    assert_eq!(it.next().unwrap(),      &5);
-    assert_eq!(it.next_back().unwrap(), &7);
-    assert_eq!(it.next_back().unwrap(), &6);
-    assert_eq!(it.next_back().unwrap(), &8);
-    assert_eq!(it.next().unwrap(),      &6);
-    assert_eq!(it.next_back().unwrap(), &7);
-    assert_eq!(it.next_back(), None);
-    assert_eq!(it.next(),      None);
-    assert_eq!(it.next_back(), None);
-}
-
-#[test]
-fn test_double_ended_range() {
-    assert_eq!((11..14).rev().collect::<Vec<_>>(), [13, 12, 11]);
-    for _ in (10..0).rev() {
-        panic!("unreachable");
-    }
-
-    assert_eq!((11..14).rev().collect::<Vec<_>>(), [13, 12, 11]);
-    for _ in (10..0).rev() {
-        panic!("unreachable");
-    }
-}
-
-#[test]
-fn test_range() {
-    assert_eq!((0..5).collect::<Vec<_>>(), [0, 1, 2, 3, 4]);
-    assert_eq!((-10..-1).collect::<Vec<_>>(), [-10, -9, -8, -7, -6, -5, -4, -3, -2]);
-    assert_eq!((0..5).rev().collect::<Vec<_>>(), [4, 3, 2, 1, 0]);
-    assert_eq!((200..-5).count(), 0);
-    assert_eq!((200..-5).rev().count(), 0);
-    assert_eq!((200..200).count(), 0);
-    assert_eq!((200..200).rev().count(), 0);
-
-    assert_eq!((0..100).size_hint(), (100, Some(100)));
-    // this test is only meaningful when sizeof usize < sizeof u64
-    assert_eq!((usize::MAX - 1..usize::MAX).size_hint(), (1, Some(1)));
-    assert_eq!((-10..-1).size_hint(), (9, Some(9)));
-    assert_eq!((-1..-10).size_hint(), (0, Some(0)));
-
-    assert_eq!((-70..58).size_hint(), (128, Some(128)));
-    assert_eq!((-128..127).size_hint(), (255, Some(255)));
-    assert_eq!((-2..isize::MAX).size_hint(),
-               (isize::MAX as usize + 2, Some(isize::MAX as usize + 2)));
-}
-
-#[test]
-fn test_range_step() {
-    assert_eq!((0..20).step_by(5).collect::<Vec<isize>>(), [0, 5, 10, 15]);
-    assert_eq!((20..0).step_by(-5).collect::<Vec<isize>>(), [20, 15, 10, 5]);
-    assert_eq!((20..0).step_by(-6).collect::<Vec<isize>>(), [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<isize>>(), []);
-    assert_eq!((200..200).step_by(1).collect::<Vec<isize>>(), []);
-
-    assert_eq!((0..20).step_by(1).size_hint(), (20, Some(20)));
-    assert_eq!((0..20).step_by(21).size_hint(), (1, Some(1)));
-    assert_eq!((0..20).step_by(5).size_hint(), (4, Some(4)));
-    assert_eq!((20..0).step_by(-5).size_hint(), (4, Some(4)));
-    assert_eq!((20..0).step_by(-6).size_hint(), (4, Some(4)));
-    assert_eq!((20..-5).step_by(1).size_hint(), (0, Some(0)));
-    assert_eq!((20..20).step_by(1).size_hint(), (0, Some(0)));
-    assert_eq!((0..1).step_by(0).size_hint(), (0, None));
-    assert_eq!((i8::MAX..i8::MIN).step_by(i8::MIN).size_hint(), (2, Some(2)));
-    assert_eq!((i16::MIN..i16::MAX).step_by(i16::MAX).size_hint(), (3, Some(3)));
-    assert_eq!((isize::MIN..isize::MAX).step_by(1).size_hint(), (usize::MAX, Some(usize::MAX)));
-}
-
-#[test]
-fn test_repeat() {
-    let mut it = repeat(42);
-    assert_eq!(it.next(), Some(42));
-    assert_eq!(it.next(), Some(42));
-    assert_eq!(it.next(), Some(42));
-}
-
-#[test]
-fn test_fuse() {
-    let mut it = 0..3;
-    assert_eq!(it.len(), 3);
-    assert_eq!(it.next(), Some(0));
-    assert_eq!(it.len(), 2);
-    assert_eq!(it.next(), Some(1));
-    assert_eq!(it.len(), 1);
-    assert_eq!(it.next(), Some(2));
-    assert_eq!(it.len(), 0);
-    assert_eq!(it.next(), None);
-    assert_eq!(it.len(), 0);
-    assert_eq!(it.next(), None);
-    assert_eq!(it.len(), 0);
-    assert_eq!(it.next(), None);
-    assert_eq!(it.len(), 0);
-}
-
-#[test]
-fn test_fuse_nth() {
-    let xs = [0, 1, 2];
-    let mut it = xs.iter();
-
-    assert_eq!(it.len(), 3);
-    assert_eq!(it.nth(2), Some(&2));
-    assert_eq!(it.len(), 0);
-    assert_eq!(it.nth(2), None);
-    assert_eq!(it.len(), 0);
-}
-
-#[test]
-fn test_fuse_last() {
-    let xs = [0, 1, 2];
-    let it = xs.iter();
-
-    assert_eq!(it.len(), 3);
-    assert_eq!(it.last(), Some(&2));
-}
-
-#[test]
-fn test_fuse_count() {
-    let xs = [0, 1, 2];
-    let it = xs.iter();
-
-    assert_eq!(it.len(), 3);
-    assert_eq!(it.count(), 3);
-    // Can't check len now because count consumes.
-}
-
-#[test]
-fn test_once() {
-    let mut it = once(42);
-    assert_eq!(it.next(), Some(42));
-    assert_eq!(it.next(), None);
-}
-
-#[test]
-fn test_empty() {
-    let mut it = empty::<i32>();
-    assert_eq!(it.next(), None);
-}
-
-#[test]
-fn test_chain_fold() {
-    let xs = [1, 2, 3];
-    let ys = [1, 2, 0];
-
-    let mut iter = xs.iter().chain(&ys);
-    iter.next();
-    let mut result = Vec::new();
-    iter.fold((), |(), &elt| result.push(elt));
-    assert_eq!(&[2, 3, 1, 2, 0], &result[..]);
-}
-
diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs
deleted file mode 100644 (file)
index d92c378..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![deny(warnings)]
-
-#![feature(box_syntax)]
-#![feature(char_escape_debug)]
-#![feature(const_fn)]
-#![feature(core_private_bignum)]
-#![feature(core_private_diy_float)]
-#![feature(dec2flt)]
-#![feature(decode_utf8)]
-#![feature(fixed_size_array)]
-#![feature(flt2dec)]
-#![feature(fmt_internals)]
-#![feature(libc)]
-#![feature(nonzero)]
-#![feature(rand)]
-#![feature(raw)]
-#![feature(sip_hash_13)]
-#![feature(slice_patterns)]
-#![feature(sort_internals)]
-#![feature(sort_unstable)]
-#![feature(step_by)]
-#![feature(test)]
-#![feature(try_from)]
-#![feature(unicode)]
-#![feature(unique)]
-
-extern crate core;
-extern crate test;
-extern crate libc;
-extern crate std_unicode;
-extern crate rand;
-
-mod any;
-mod array;
-mod atomic;
-mod cell;
-mod char;
-mod clone;
-mod cmp;
-mod fmt;
-mod hash;
-mod intrinsics;
-mod iter;
-mod mem;
-mod nonzero;
-mod num;
-mod ops;
-mod option;
-mod ptr;
-mod result;
-mod slice;
-mod str;
-mod tuple;
diff --git a/src/libcoretest/mem.rs b/src/libcoretest/mem.rs
deleted file mode 100644 (file)
index 86e59c7..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2014-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 core::mem::*;
-
-#[test]
-fn size_of_basic() {
-    assert_eq!(size_of::<u8>(), 1);
-    assert_eq!(size_of::<u16>(), 2);
-    assert_eq!(size_of::<u32>(), 4);
-    assert_eq!(size_of::<u64>(), 8);
-}
-
-#[test]
-#[cfg(target_pointer_width = "16")]
-fn size_of_16() {
-    assert_eq!(size_of::<usize>(), 2);
-    assert_eq!(size_of::<*const usize>(), 2);
-}
-
-#[test]
-#[cfg(target_pointer_width = "32")]
-fn size_of_32() {
-    assert_eq!(size_of::<usize>(), 4);
-    assert_eq!(size_of::<*const usize>(), 4);
-}
-
-#[test]
-#[cfg(target_pointer_width = "64")]
-fn size_of_64() {
-    assert_eq!(size_of::<usize>(), 8);
-    assert_eq!(size_of::<*const usize>(), 8);
-}
-
-#[test]
-fn size_of_val_basic() {
-    assert_eq!(size_of_val(&1u8), 1);
-    assert_eq!(size_of_val(&1u16), 2);
-    assert_eq!(size_of_val(&1u32), 4);
-    assert_eq!(size_of_val(&1u64), 8);
-}
-
-#[test]
-fn align_of_basic() {
-    assert_eq!(align_of::<u8>(), 1);
-    assert_eq!(align_of::<u16>(), 2);
-    assert_eq!(align_of::<u32>(), 4);
-}
-
-#[test]
-#[cfg(target_pointer_width = "16")]
-fn align_of_16() {
-    assert_eq!(align_of::<usize>(), 2);
-    assert_eq!(align_of::<*const usize>(), 2);
-}
-
-#[test]
-#[cfg(target_pointer_width = "32")]
-fn align_of_32() {
-    assert_eq!(align_of::<usize>(), 4);
-    assert_eq!(align_of::<*const usize>(), 4);
-}
-
-#[test]
-#[cfg(target_pointer_width = "64")]
-fn align_of_64() {
-    assert_eq!(align_of::<usize>(), 8);
-    assert_eq!(align_of::<*const usize>(), 8);
-}
-
-#[test]
-fn align_of_val_basic() {
-    assert_eq!(align_of_val(&1u8), 1);
-    assert_eq!(align_of_val(&1u16), 2);
-    assert_eq!(align_of_val(&1u32), 4);
-}
-
-#[test]
-fn test_swap() {
-    let mut x = 31337;
-    let mut y = 42;
-    swap(&mut x, &mut y);
-    assert_eq!(x, 42);
-    assert_eq!(y, 31337);
-}
-
-#[test]
-fn test_replace() {
-    let mut x = Some("test".to_string());
-    let y = replace(&mut x, None);
-    assert!(x.is_none());
-    assert!(y.is_some());
-}
-
-#[test]
-fn test_transmute_copy() {
-    assert_eq!(1, unsafe { transmute_copy(&1) });
-}
-
-#[test]
-fn test_transmute() {
-    trait Foo { fn dummy(&self) { } }
-    impl Foo for isize {}
-
-    let a = box 100isize as Box<Foo>;
-    unsafe {
-        let x: ::core::raw::TraitObject = transmute(a);
-        assert!(*(x.data as *const isize) == 100);
-        let _x: Box<Foo> = transmute(x);
-    }
-
-    unsafe {
-        assert_eq!(transmute::<_, Vec<u8>>("L".to_string()), [76]);
-    }
-}
-
diff --git a/src/libcoretest/nonzero.rs b/src/libcoretest/nonzero.rs
deleted file mode 100644 (file)
index 7a367dd..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-// 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 core::nonzero::NonZero;
-use core::option::Option;
-use core::option::Option::{Some, None};
-use std::mem::size_of;
-
-#[test]
-fn test_create_nonzero_instance() {
-    let _a = unsafe {
-        NonZero::new(21)
-    };
-}
-
-#[test]
-fn test_size_nonzero_in_option() {
-    assert_eq!(size_of::<NonZero<u32>>(), size_of::<Option<NonZero<u32>>>());
-}
-
-#[test]
-fn test_match_on_nonzero_option() {
-    let a = Some(unsafe {
-        NonZero::new(42)
-    });
-    match a {
-        Some(val) => assert_eq!(*val, 42),
-        None => panic!("unexpected None while matching on Some(NonZero(_))")
-    }
-
-    match unsafe { Some(NonZero::new(43)) } {
-        Some(val) => assert_eq!(*val, 43),
-        None => panic!("unexpected None while matching on Some(NonZero(_))")
-    }
-}
-
-#[test]
-fn test_match_option_empty_vec() {
-    let a: Option<Vec<isize>> = Some(vec![]);
-    match a {
-        None => panic!("unexpected None while matching on Some(vec![])"),
-        _ => {}
-    }
-}
-
-#[test]
-fn test_match_option_vec() {
-    let a = Some(vec![1, 2, 3, 4]);
-    match a {
-        Some(v) => assert_eq!(v, [1, 2, 3, 4]),
-        None => panic!("unexpected None while matching on Some(vec![1, 2, 3, 4])")
-    }
-}
-
-#[test]
-fn test_match_option_rc() {
-    use std::rc::Rc;
-
-    let five = Rc::new(5);
-    match Some(five) {
-        Some(r) => assert_eq!(*r, 5),
-        None => panic!("unexpected None while matching on Some(Rc::new(5))")
-    }
-}
-
-#[test]
-fn test_match_option_arc() {
-    use std::sync::Arc;
-
-    let five = Arc::new(5);
-    match Some(five) {
-        Some(a) => assert_eq!(*a, 5),
-        None => panic!("unexpected None while matching on Some(Arc::new(5))")
-    }
-}
-
-#[test]
-fn test_match_option_empty_string() {
-    let a = Some(String::new());
-    match a {
-        None => panic!("unexpected None while matching on Some(String::new())"),
-        _ => {}
-    }
-}
-
-#[test]
-fn test_match_option_string() {
-    let five = "Five".to_string();
-    match Some(five) {
-        Some(s) => assert_eq!(s, "Five"),
-        None => panic!("unexpected None while matching on Some(String { ... })")
-    }
-}
diff --git a/src/libcoretest/num/bignum.rs b/src/libcoretest/num/bignum.rs
deleted file mode 100644 (file)
index 58a9dd1..0000000
+++ /dev/null
@@ -1,249 +0,0 @@
-// 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::prelude::v1::*;
-use core::num::bignum::tests::Big8x3 as Big;
-
-#[test]
-#[should_panic]
-fn test_from_u64_overflow() {
-    Big::from_u64(0x1000000);
-}
-
-#[test]
-fn test_add() {
-    assert_eq!(*Big::from_small(3).add(&Big::from_small(4)), Big::from_small(7));
-    assert_eq!(*Big::from_small(3).add(&Big::from_small(0)), Big::from_small(3));
-    assert_eq!(*Big::from_small(0).add(&Big::from_small(3)), Big::from_small(3));
-    assert_eq!(*Big::from_small(3).add(&Big::from_u64(0xfffe)), Big::from_u64(0x10001));
-    assert_eq!(*Big::from_u64(0xfedc).add(&Big::from_u64(0x789)), Big::from_u64(0x10665));
-    assert_eq!(*Big::from_u64(0x789).add(&Big::from_u64(0xfedc)), Big::from_u64(0x10665));
-}
-
-#[test]
-#[should_panic]
-fn test_add_overflow_1() {
-    Big::from_small(1).add(&Big::from_u64(0xffffff));
-}
-
-#[test]
-#[should_panic]
-fn test_add_overflow_2() {
-    Big::from_u64(0xffffff).add(&Big::from_small(1));
-}
-
-#[test]
-fn test_add_small() {
-    assert_eq!(*Big::from_small(3).add_small(4), Big::from_small(7));
-    assert_eq!(*Big::from_small(3).add_small(0), Big::from_small(3));
-    assert_eq!(*Big::from_small(0).add_small(3), Big::from_small(3));
-    assert_eq!(*Big::from_small(7).add_small(250), Big::from_u64(257));
-    assert_eq!(*Big::from_u64(0x7fff).add_small(1), Big::from_u64(0x8000));
-    assert_eq!(*Big::from_u64(0x2ffe).add_small(0x35), Big::from_u64(0x3033));
-    assert_eq!(*Big::from_small(0xdc).add_small(0x89), Big::from_u64(0x165));
-}
-
-#[test]
-#[should_panic]
-fn test_add_small_overflow() {
-    Big::from_u64(0xffffff).add_small(1);
-}
-
-#[test]
-fn test_sub() {
-    assert_eq!(*Big::from_small(7).sub(&Big::from_small(4)), Big::from_small(3));
-    assert_eq!(*Big::from_u64(0x10665).sub(&Big::from_u64(0x789)), Big::from_u64(0xfedc));
-    assert_eq!(*Big::from_u64(0x10665).sub(&Big::from_u64(0xfedc)), Big::from_u64(0x789));
-    assert_eq!(*Big::from_u64(0x10665).sub(&Big::from_u64(0x10664)), Big::from_small(1));
-    assert_eq!(*Big::from_u64(0x10665).sub(&Big::from_u64(0x10665)), Big::from_small(0));
-}
-
-#[test]
-#[should_panic]
-fn test_sub_underflow_1() {
-    Big::from_u64(0x10665).sub(&Big::from_u64(0x10666));
-}
-
-#[test]
-#[should_panic]
-fn test_sub_underflow_2() {
-    Big::from_small(0).sub(&Big::from_u64(0x123456));
-}
-
-#[test]
-fn test_mul_small() {
-    assert_eq!(*Big::from_small(7).mul_small(5), Big::from_small(35));
-    assert_eq!(*Big::from_small(0xff).mul_small(0xff), Big::from_u64(0xfe01));
-    assert_eq!(*Big::from_u64(0xffffff/13).mul_small(13), Big::from_u64(0xffffff));
-}
-
-#[test]
-#[should_panic]
-fn test_mul_small_overflow() {
-    Big::from_u64(0x800000).mul_small(2);
-}
-
-#[test]
-fn test_mul_pow2() {
-    assert_eq!(*Big::from_small(0x7).mul_pow2(4), Big::from_small(0x70));
-    assert_eq!(*Big::from_small(0xff).mul_pow2(1), Big::from_u64(0x1fe));
-    assert_eq!(*Big::from_small(0xff).mul_pow2(12), Big::from_u64(0xff000));
-    assert_eq!(*Big::from_small(0x1).mul_pow2(23), Big::from_u64(0x800000));
-    assert_eq!(*Big::from_u64(0x123).mul_pow2(0), Big::from_u64(0x123));
-    assert_eq!(*Big::from_u64(0x123).mul_pow2(7), Big::from_u64(0x9180));
-    assert_eq!(*Big::from_u64(0x123).mul_pow2(15), Big::from_u64(0x918000));
-    assert_eq!(*Big::from_small(0).mul_pow2(23), Big::from_small(0));
-}
-
-#[test]
-#[should_panic]
-fn test_mul_pow2_overflow_1() {
-    Big::from_u64(0x1).mul_pow2(24);
-}
-
-#[test]
-#[should_panic]
-fn test_mul_pow2_overflow_2() {
-    Big::from_u64(0x123).mul_pow2(16);
-}
-
-#[test]
-fn test_mul_pow5() {
-    assert_eq!(*Big::from_small(42).mul_pow5(0), Big::from_small(42));
-    assert_eq!(*Big::from_small(1).mul_pow5(2), Big::from_small(25));
-    assert_eq!(*Big::from_small(1).mul_pow5(4), Big::from_u64(25 * 25));
-    assert_eq!(*Big::from_small(4).mul_pow5(3), Big::from_u64(500));
-    assert_eq!(*Big::from_small(140).mul_pow5(2), Big::from_u64(25 * 140));
-    assert_eq!(*Big::from_small(25).mul_pow5(1), Big::from_small(125));
-    assert_eq!(*Big::from_small(125).mul_pow5(7), Big::from_u64(9765625));
-    assert_eq!(*Big::from_small(0).mul_pow5(127), Big::from_small(0));
-}
-
-#[test]
-#[should_panic]
-fn test_mul_pow5_overflow_1() {
-    Big::from_small(1).mul_pow5(12);
-}
-
-#[test]
-#[should_panic]
-fn test_mul_pow5_overflow_2() {
-    Big::from_small(230).mul_pow5(8);
-}
-
-#[test]
-fn test_mul_digits() {
-    assert_eq!(*Big::from_small(3).mul_digits(&[5]), Big::from_small(15));
-    assert_eq!(*Big::from_small(0xff).mul_digits(&[0xff]), Big::from_u64(0xfe01));
-    assert_eq!(*Big::from_u64(0x123).mul_digits(&[0x56, 0x4]), Big::from_u64(0x4edc2));
-    assert_eq!(*Big::from_u64(0x12345).mul_digits(&[0x67]), Big::from_u64(0x7530c3));
-    assert_eq!(*Big::from_small(0x12).mul_digits(&[0x67, 0x45, 0x3]), Big::from_u64(0x3ae13e));
-    assert_eq!(*Big::from_u64(0xffffff/13).mul_digits(&[13]), Big::from_u64(0xffffff));
-    assert_eq!(*Big::from_small(13).mul_digits(&[0x3b, 0xb1, 0x13]), Big::from_u64(0xffffff));
-}
-
-#[test]
-#[should_panic]
-fn test_mul_digits_overflow_1() {
-    Big::from_u64(0x800000).mul_digits(&[2]);
-}
-
-#[test]
-#[should_panic]
-fn test_mul_digits_overflow_2() {
-    Big::from_u64(0x1000).mul_digits(&[0, 0x10]);
-}
-
-#[test]
-fn test_div_rem_small() {
-    let as_val = |(q, r): (&mut Big, u8)| (q.clone(), r);
-    assert_eq!(as_val(Big::from_small(0xff).div_rem_small(15)), (Big::from_small(17), 0));
-    assert_eq!(as_val(Big::from_small(0xff).div_rem_small(16)), (Big::from_small(15), 15));
-    assert_eq!(as_val(Big::from_small(3).div_rem_small(40)), (Big::from_small(0), 3));
-    assert_eq!(as_val(Big::from_u64(0xffffff).div_rem_small(123)),
-               (Big::from_u64(0xffffff / 123), (0xffffffu64 % 123) as u8));
-    assert_eq!(as_val(Big::from_u64(0x10000).div_rem_small(123)),
-               (Big::from_u64(0x10000 / 123), (0x10000u64 % 123) as u8));
-}
-
-#[test]
-fn test_div_rem() {
-    fn div_rem(n: u64, d: u64) -> (Big, Big) {
-        let mut q = Big::from_small(42);
-        let mut r = Big::from_small(42);
-        Big::from_u64(n).div_rem(&Big::from_u64(d), &mut q, &mut r);
-        (q, r)
-    }
-    assert_eq!(div_rem(1, 1), (Big::from_small(1), Big::from_small(0)));
-    assert_eq!(div_rem(4, 3), (Big::from_small(1), Big::from_small(1)));
-    assert_eq!(div_rem(1, 7), (Big::from_small(0), Big::from_small(1)));
-    assert_eq!(div_rem(45, 9), (Big::from_small(5), Big::from_small(0)));
-    assert_eq!(div_rem(103, 9), (Big::from_small(11), Big::from_small(4)));
-    assert_eq!(div_rem(123456, 77), (Big::from_u64(1603), Big::from_small(25)));
-    assert_eq!(div_rem(0xffff, 1), (Big::from_u64(0xffff), Big::from_small(0)));
-    assert_eq!(div_rem(0xeeee, 0xffff), (Big::from_small(0), Big::from_u64(0xeeee)));
-    assert_eq!(div_rem(2_000_000, 2), (Big::from_u64(1_000_000), Big::from_u64(0)));
-}
-
-#[test]
-fn test_is_zero() {
-    assert!(Big::from_small(0).is_zero());
-    assert!(!Big::from_small(3).is_zero());
-    assert!(!Big::from_u64(0x123).is_zero());
-    assert!(!Big::from_u64(0xffffff).sub(&Big::from_u64(0xfffffe)).is_zero());
-    assert!(Big::from_u64(0xffffff).sub(&Big::from_u64(0xffffff)).is_zero());
-}
-
-#[test]
-fn test_get_bit() {
-    let x = Big::from_small(0b1101);
-    assert_eq!(x.get_bit(0), 1);
-    assert_eq!(x.get_bit(1), 0);
-    assert_eq!(x.get_bit(2), 1);
-    assert_eq!(x.get_bit(3), 1);
-    let y = Big::from_u64(1 << 15);
-    assert_eq!(y.get_bit(14), 0);
-    assert_eq!(y.get_bit(15), 1);
-    assert_eq!(y.get_bit(16), 0);
-}
-
-#[test]
-#[should_panic]
-fn test_get_bit_out_of_range() {
-    Big::from_small(42).get_bit(24);
-}
-
-#[test]
-fn test_bit_length() {
-    assert_eq!(Big::from_small(0).bit_length(), 0);
-    assert_eq!(Big::from_small(1).bit_length(), 1);
-    assert_eq!(Big::from_small(5).bit_length(), 3);
-    assert_eq!(Big::from_small(0x18).bit_length(), 5);
-    assert_eq!(Big::from_u64(0x4073).bit_length(), 15);
-    assert_eq!(Big::from_u64(0xffffff).bit_length(), 24);
-}
-
-#[test]
-fn test_ord() {
-    assert!(Big::from_u64(0) < Big::from_u64(0xffffff));
-    assert!(Big::from_u64(0x102) < Big::from_u64(0x201));
-}
-
-#[test]
-fn test_fmt() {
-    assert_eq!(format!("{:?}", Big::from_u64(0)), "0x0");
-    assert_eq!(format!("{:?}", Big::from_u64(0x1)), "0x1");
-    assert_eq!(format!("{:?}", Big::from_u64(0x12)), "0x12");
-    assert_eq!(format!("{:?}", Big::from_u64(0x123)), "0x1_23");
-    assert_eq!(format!("{:?}", Big::from_u64(0x1234)), "0x12_34");
-    assert_eq!(format!("{:?}", Big::from_u64(0x12345)), "0x1_23_45");
-    assert_eq!(format!("{:?}", Big::from_u64(0x123456)), "0x12_34_56");
-}
-
diff --git a/src/libcoretest/num/dec2flt/mod.rs b/src/libcoretest/num/dec2flt/mod.rs
deleted file mode 100644 (file)
index 5d546c6..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-// 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(overflowing_literals)]
-
-use std::{i64, f32, f64};
-
-mod parse;
-mod rawfp;
-
-// Take a float literal, turn it into a string in various ways (that are all trusted
-// to be correct) and see if those strings are parsed back to the value of the literal.
-// Requires a *polymorphic literal*, i.e. one that can serve as f64 as well as f32.
-macro_rules! test_literal {
-    ($x: expr) => ({
-        let x32: f32 = $x;
-        let x64: f64 = $x;
-        let inputs = &[stringify!($x).into(), format!("{:?}", x64), format!("{:e}", x64)];
-        for input in inputs {
-            assert_eq!(input.parse(), Ok(x64));
-            assert_eq!(input.parse(), Ok(x32));
-            let neg_input = &format!("-{}", input);
-            assert_eq!(neg_input.parse(), Ok(-x64));
-            assert_eq!(neg_input.parse(), Ok(-x32));
-        }
-    })
-}
-
-#[test]
-fn ordinary() {
-    test_literal!(1.0);
-    test_literal!(3e-5);
-    test_literal!(0.1);
-    test_literal!(12345.);
-    test_literal!(0.9999999);
-    test_literal!(2.2250738585072014e-308);
-}
-
-#[test]
-fn special_code_paths() {
-    test_literal!(36893488147419103229.0); // 2^65 - 3, triggers half-to-even with even significand
-    test_literal!(101e-33); // Triggers the tricky underflow case in AlgorithmM (for f32)
-    test_literal!(1e23); // Triggers AlgorithmR
-    test_literal!(2075e23); // Triggers another path through AlgorithmR
-    test_literal!(8713e-23); // ... and yet another.
-}
-
-#[test]
-fn large() {
-    test_literal!(1e300);
-    test_literal!(123456789.34567e250);
-    test_literal!(943794359898089732078308743689303290943794359843568973207830874368930329.);
-}
-
-#[test]
-fn subnormals() {
-    test_literal!(5e-324);
-    test_literal!(91e-324);
-    test_literal!(1e-322);
-    test_literal!(13245643e-320);
-    test_literal!(2.22507385851e-308);
-    test_literal!(2.1e-308);
-    test_literal!(4.9406564584124654e-324);
-}
-
-#[test]
-fn infinity() {
-    test_literal!(1e400);
-    test_literal!(1e309);
-    test_literal!(2e308);
-    test_literal!(1.7976931348624e308);
-}
-
-#[test]
-fn zero() {
-    test_literal!(0.0);
-    test_literal!(1e-325);
-    test_literal!(1e-326);
-    test_literal!(1e-500);
-}
-
-#[test]
-fn fast_path_correct() {
-    // This number triggers the fast path and is handled incorrectly when compiling on
-    // x86 without SSE2 (i.e., using the x87 FPU stack).
-    test_literal!(1.448997445238699);
-}
-
-#[test]
-fn lonely_dot() {
-    assert!(".".parse::<f32>().is_err());
-    assert!(".".parse::<f64>().is_err());
-}
-
-#[test]
-fn lonely_sign() {
-    assert!("+".parse::<f32>().is_err());
-    assert!("-".parse::<f64>().is_err());
-}
-
-#[test]
-fn whitespace() {
-    assert!(" 1.0".parse::<f32>().is_err());
-    assert!("1.0 ".parse::<f64>().is_err());
-}
-
-#[test]
-fn nan() {
-    assert!("NaN".parse::<f32>().unwrap().is_nan());
-    assert!("NaN".parse::<f64>().unwrap().is_nan());
-}
-
-#[test]
-fn inf() {
-    assert_eq!("inf".parse(), Ok(f64::INFINITY));
-    assert_eq!("-inf".parse(), Ok(f64::NEG_INFINITY));
-    assert_eq!("inf".parse(), Ok(f32::INFINITY));
-    assert_eq!("-inf".parse(), Ok(f32::NEG_INFINITY));
-}
-
-#[test]
-fn massive_exponent() {
-    let max = i64::MAX;
-    assert_eq!(format!("1e{}000", max).parse(), Ok(f64::INFINITY));
-    assert_eq!(format!("1e-{}000", max).parse(), Ok(0.0));
-    assert_eq!(format!("1e{}000", max).parse(), Ok(f64::INFINITY));
-}
-
-#[test]
-fn borderline_overflow() {
-    let mut s = "0.".to_string();
-    for _ in 0..375 {
-        s.push('3');
-    }
-    // At the time of this writing, this returns Err(..), but this is a bug that should be fixed.
-    // It makes no sense to enshrine that in a test, the important part is that it doesn't panic.
-    let _ = s.parse::<f64>();
-}
diff --git a/src/libcoretest/num/dec2flt/parse.rs b/src/libcoretest/num/dec2flt/parse.rs
deleted file mode 100644 (file)
index 09acf2b..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-// 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::iter;
-use core::num::dec2flt::parse::{Decimal, parse_decimal};
-use core::num::dec2flt::parse::ParseResult::{Valid, Invalid};
-
-#[test]
-fn missing_pieces() {
-    let permutations = &[".e", "1e", "e4", "e", ".12e", "321.e", "32.12e+", "12.32e-"];
-    for &s in permutations {
-        assert_eq!(parse_decimal(s), Invalid);
-    }
-}
-
-#[test]
-fn invalid_chars() {
-    let invalid = "r,?<j";
-    let valid_strings = &["123", "666.", ".1", "5e1", "7e-3", "0.0e+1"];
-    for c in invalid.chars() {
-        for s in valid_strings {
-            for i in 0..s.len() {
-                let mut input = String::new();
-                input.push_str(s);
-                input.insert(i, c);
-                assert!(parse_decimal(&input) == Invalid, "did not reject invalid {:?}", input);
-            }
-        }
-    }
-}
-
-#[test]
-fn valid() {
-    assert_eq!(parse_decimal("123.456e789"), Valid(Decimal::new(b"123", b"456", 789)));
-    assert_eq!(parse_decimal("123.456e+789"), Valid(Decimal::new(b"123", b"456", 789)));
-    assert_eq!(parse_decimal("123.456e-789"), Valid(Decimal::new(b"123", b"456", -789)));
-    assert_eq!(parse_decimal(".050"), Valid(Decimal::new(b"", b"050", 0)));
-    assert_eq!(parse_decimal("999"), Valid(Decimal::new(b"999", b"", 0)));
-    assert_eq!(parse_decimal("1.e300"), Valid(Decimal::new(b"1", b"", 300)));
-    assert_eq!(parse_decimal(".1e300"), Valid(Decimal::new(b"", b"1", 300)));
-    assert_eq!(parse_decimal("101e-33"), Valid(Decimal::new(b"101", b"", -33)));
-    let zeros: String = iter::repeat('0').take(25).collect();
-    let s = format!("1.5e{}", zeros);
-    assert_eq!(parse_decimal(&s), Valid(Decimal::new(b"1", b"5", 0)));
-}
diff --git a/src/libcoretest/num/dec2flt/rawfp.rs b/src/libcoretest/num/dec2flt/rawfp.rs
deleted file mode 100644 (file)
index 1a35333..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-// 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::f64;
-use std::mem;
-use core::num::diy_float::Fp;
-use core::num::dec2flt::rawfp::{fp_to_float, prev_float, next_float, round_normal};
-
-fn integer_decode(f: f64) -> (u64, i16, i8) {
-    let bits: u64 = unsafe { mem::transmute(f) };
-    let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
-    let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
-    let mantissa = if exponent == 0 {
-        (bits & 0xfffffffffffff) << 1
-    } else {
-        (bits & 0xfffffffffffff) | 0x10000000000000
-    };
-    // Exponent bias + mantissa shift
-    exponent -= 1023 + 52;
-    (mantissa, exponent, sign)
-}
-
-#[test]
-fn fp_to_float_half_to_even() {
-    fn is_normalized(sig: u64) -> bool {
-        // intentionally written without {min,max}_sig() as a sanity check
-        sig >> 52 == 1 && sig >> 53 == 0
-    }
-
-    fn conv(sig: u64) -> u64 {
-        // The significands are perfectly in range, so the exponent should not matter
-        let (m1, e1, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: 0 }));
-        assert_eq!(e1, 0 + 64 - 53);
-        let (m2, e2, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: 55 }));
-        assert_eq!(e2, 55 + 64 - 53);
-        assert_eq!(m2, m1);
-        let (m3, e3, _) = integer_decode(fp_to_float::<f64>(Fp { f: sig, e: -78 }));
-        assert_eq!(e3, -78 + 64 - 53);
-        assert_eq!(m3, m2);
-        m3
-    }
-
-    let odd = 0x1F_EDCB_A012_345F;
-    let even = odd - 1;
-    assert!(is_normalized(odd));
-    assert!(is_normalized(even));
-    assert_eq!(conv(odd << 11), odd);
-    assert_eq!(conv(even << 11), even);
-    assert_eq!(conv(odd << 11 | 1 << 10), odd + 1);
-    assert_eq!(conv(even << 11 | 1 << 10), even);
-    assert_eq!(conv(even << 11 | 1 << 10 | 1), even + 1);
-    assert_eq!(conv(odd << 11 | 1 << 9), odd);
-    assert_eq!(conv(even << 11 | 1 << 9), even);
-    assert_eq!(conv(odd << 11 | 0x7FF), odd + 1);
-    assert_eq!(conv(even << 11 | 0x7FF), even + 1);
-    assert_eq!(conv(odd << 11 | 0x3FF), odd);
-    assert_eq!(conv(even << 11 | 0x3FF), even);
-}
-
-#[test]
-fn integers_to_f64() {
-    assert_eq!(fp_to_float::<f64>(Fp { f: 1, e: 0 }), 1.0);
-    assert_eq!(fp_to_float::<f64>(Fp { f: 42, e: 7 }), (42 << 7) as f64);
-    assert_eq!(fp_to_float::<f64>(Fp { f: 1 << 20, e: 30 }), (1u64 << 50) as f64);
-    assert_eq!(fp_to_float::<f64>(Fp { f: 4, e: -3 }), 0.5);
-}
-
-const SOME_FLOATS: [f64; 9] =
-    [0.1f64, 33.568, 42.1e-5, 777.0e9, 1.1111, 0.347997,
-     9843579834.35892, 12456.0e-150, 54389573.0e-150];
-
-
-#[test]
-fn human_f64_roundtrip() {
-    for &x in &SOME_FLOATS {
-        let (f, e, _) = integer_decode(x);
-        let fp = Fp { f: f, e: e};
-        assert_eq!(fp_to_float::<f64>(fp), x);
-    }
-}
-
-#[test]
-fn rounding_overflow() {
-    let x = Fp { f: 0xFF_FF_FF_FF_FF_FF_FF_00u64, e: 42 };
-    let rounded = round_normal::<f64>(x);
-    let adjusted_k = x.e + 64 - 53;
-    assert_eq!(rounded.sig, 1 << 52);
-    assert_eq!(rounded.k, adjusted_k + 1);
-}
-
-#[test]
-fn prev_float_monotonic() {
-    let mut x = 1.0;
-    for _ in 0..100 {
-        let x1 = prev_float(x);
-        assert!(x1 < x);
-        assert!(x - x1 < 1e-15);
-        x = x1;
-    }
-}
-
-const MIN_SUBNORMAL: f64 = 5e-324;
-
-#[test]
-fn next_float_zero() {
-    let tiny = next_float(0.0);
-    assert_eq!(tiny, MIN_SUBNORMAL);
-    assert!(tiny != 0.0);
-}
-
-#[test]
-fn next_float_subnormal() {
-    let second = next_float(MIN_SUBNORMAL);
-    // For subnormals, MIN_SUBNORMAL is the ULP
-    assert!(second != MIN_SUBNORMAL);
-    assert!(second > 0.0);
-    assert_eq!(second - MIN_SUBNORMAL, MIN_SUBNORMAL);
-}
-
-#[test]
-fn next_float_inf() {
-    assert_eq!(next_float(f64::MAX), f64::INFINITY);
-    assert_eq!(next_float(f64::INFINITY), f64::INFINITY);
-}
-
-#[test]
-fn next_prev_identity() {
-    for &x in &SOME_FLOATS {
-        assert_eq!(prev_float(next_float(x)), x);
-        assert_eq!(prev_float(prev_float(next_float(next_float(x)))), x);
-        assert_eq!(next_float(prev_float(x)), x);
-        assert_eq!(next_float(next_float(prev_float(prev_float(x)))), x);
-    }
-}
-
-#[test]
-fn next_float_monotonic() {
-    let mut x = 0.49999999999999;
-    assert!(x < 0.5);
-    for _ in 0..200 {
-        let x1 = next_float(x);
-        assert!(x1 > x);
-        assert!(x1 - x < 1e-15, "next_float_monotonic: delta = {:?}", x1 - x);
-        x = x1;
-    }
-    assert!(x > 0.5);
-}
diff --git a/src/libcoretest/num/flt2dec/estimator.rs b/src/libcoretest/num/flt2dec/estimator.rs
deleted file mode 100644 (file)
index 0bca616..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-// 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.
-
-// FIXME https://github.com/kripken/emscripten/issues/4563
-// NB we have to actually not compile this test to avoid
-// an undefined symbol error
-#![cfg(not(target_os = "emscripten"))]
-
-use core::num::flt2dec::estimator::*;
-
-#[test]
-fn test_estimate_scaling_factor() {
-    macro_rules! assert_almost_eq {
-        ($actual:expr, $expected:expr) => ({
-            let actual = $actual;
-            let expected = $expected;
-            println!("{} - {} = {} - {} = {}", stringify!($expected), stringify!($actual),
-                     expected, actual, expected - actual);
-            assert!(expected == actual || expected == actual + 1,
-                    "expected {}, actual {}", expected, actual);
-        })
-    }
-
-    assert_almost_eq!(estimate_scaling_factor(1, 0), 0);
-    assert_almost_eq!(estimate_scaling_factor(2, 0), 1);
-    assert_almost_eq!(estimate_scaling_factor(10, 0), 1);
-    assert_almost_eq!(estimate_scaling_factor(11, 0), 2);
-    assert_almost_eq!(estimate_scaling_factor(100, 0), 2);
-    assert_almost_eq!(estimate_scaling_factor(101, 0), 3);
-    assert_almost_eq!(estimate_scaling_factor(10000000000000000000, 0), 19);
-    assert_almost_eq!(estimate_scaling_factor(10000000000000000001, 0), 20);
-
-    // 1/2^20 = 0.00000095367...
-    assert_almost_eq!(estimate_scaling_factor(1 * 1048576 / 1000000, -20), -6);
-    assert_almost_eq!(estimate_scaling_factor(1 * 1048576 / 1000000 + 1, -20), -5);
-    assert_almost_eq!(estimate_scaling_factor(10 * 1048576 / 1000000, -20), -5);
-    assert_almost_eq!(estimate_scaling_factor(10 * 1048576 / 1000000 + 1, -20), -4);
-    assert_almost_eq!(estimate_scaling_factor(100 * 1048576 / 1000000, -20), -4);
-    assert_almost_eq!(estimate_scaling_factor(100 * 1048576 / 1000000 + 1, -20), -3);
-    assert_almost_eq!(estimate_scaling_factor(1048575, -20), 0);
-    assert_almost_eq!(estimate_scaling_factor(1048576, -20), 0);
-    assert_almost_eq!(estimate_scaling_factor(1048577, -20), 1);
-    assert_almost_eq!(estimate_scaling_factor(10485759999999999999, -20), 13);
-    assert_almost_eq!(estimate_scaling_factor(10485760000000000000, -20), 13);
-    assert_almost_eq!(estimate_scaling_factor(10485760000000000001, -20), 14);
-
-    // extreme values:
-    // 2^-1074 = 4.94065... * 10^-324
-    // (2^53-1) * 2^971 = 1.79763... * 10^308
-    assert_almost_eq!(estimate_scaling_factor(1, -1074), -323);
-    assert_almost_eq!(estimate_scaling_factor(0x1fffffffffffff, 971), 309);
-
-    for i in -1074..972 {
-        let expected = super::ldexp_f64(1.0, i).log10().ceil();
-        assert_almost_eq!(estimate_scaling_factor(1, i as i16), expected as i16);
-    }
-}
-
diff --git a/src/libcoretest/num/flt2dec/mod.rs b/src/libcoretest/num/flt2dec/mod.rs
deleted file mode 100644 (file)
index 0f4d19e..0000000
+++ /dev/null
@@ -1,1201 +0,0 @@
-// 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::prelude::v1::*;
-use std::{str, mem, i16, f32, f64, fmt};
-use std::__rand as rand;
-use rand::{Rand, XorShiftRng};
-use rand::distributions::{IndependentSample, Range};
-
-use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded};
-use core::num::flt2dec::{MAX_SIG_DIGITS, round_up, Part, Formatted, Sign};
-use core::num::flt2dec::{to_shortest_str, to_shortest_exp_str,
-                         to_exact_exp_str, to_exact_fixed_str};
-
-pub use test::Bencher;
-
-mod estimator;
-mod strategy {
-    mod dragon;
-    mod grisu;
-}
-
-pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
-    match decode(v).1 {
-        FullDecoded::Finite(decoded) => decoded,
-        full_decoded => panic!("expected finite, got {:?} instead", full_decoded)
-    }
-}
-
-macro_rules! check_shortest {
-    ($f:ident($v:expr) => $buf:expr, $exp:expr) => (
-        check_shortest!($f($v) => $buf, $exp;
-                        "shortest mismatch for v={v}: actual {actual:?}, expected {expected:?}",
-                        v = stringify!($v))
-    );
-
-    ($f:ident{$($k:ident: $v:expr),+} => $buf:expr, $exp:expr) => (
-        check_shortest!($f{$($k: $v),+} => $buf, $exp;
-                        "shortest mismatch for {v:?}: actual {actual:?}, expected {expected:?}",
-                        v = Decoded { $($k: $v),+ })
-    );
-
-    ($f:ident($v:expr) => $buf:expr, $exp:expr; $fmt:expr, $($key:ident = $val:expr),*) => ({
-        let mut buf = [b'_'; MAX_SIG_DIGITS];
-        let (len, k) = $f(&decode_finite($v), &mut buf);
-        assert!((&buf[..len], k) == ($buf, $exp),
-                $fmt, actual = (str::from_utf8(&buf[..len]).unwrap(), k),
-                      expected = (str::from_utf8($buf).unwrap(), $exp),
-                      $($key = $val),*);
-    });
-
-    ($f:ident{$($k:ident: $v:expr),+} => $buf:expr, $exp:expr;
-                                         $fmt:expr, $($key:ident = $val:expr),*) => ({
-        let mut buf = [b'_'; MAX_SIG_DIGITS];
-        let (len, k) = $f(&Decoded { $($k: $v),+ }, &mut buf);
-        assert!((&buf[..len], k) == ($buf, $exp),
-                $fmt, actual = (str::from_utf8(&buf[..len]).unwrap(), k),
-                      expected = (str::from_utf8($buf).unwrap(), $exp),
-                      $($key = $val),*);
-    })
-}
-
-macro_rules! try_exact {
-    ($f:ident($decoded:expr) => $buf:expr, $expected:expr, $expectedk:expr;
-                                $fmt:expr, $($key:ident = $val:expr),*) => ({
-        let (len, k) = $f($decoded, &mut $buf[..$expected.len()], i16::MIN);
-        assert!((&$buf[..len], k) == ($expected, $expectedk),
-                $fmt, actual = (str::from_utf8(&$buf[..len]).unwrap(), k),
-                      expected = (str::from_utf8($expected).unwrap(), $expectedk),
-                      $($key = $val),*);
-    })
-}
-
-macro_rules! try_fixed {
-    ($f:ident($decoded:expr) => $buf:expr, $request:expr, $expected:expr, $expectedk:expr;
-                                $fmt:expr, $($key:ident = $val:expr),*) => ({
-        let (len, k) = $f($decoded, &mut $buf[..], $request);
-        assert!((&$buf[..len], k) == ($expected, $expectedk),
-                $fmt, actual = (str::from_utf8(&$buf[..len]).unwrap(), k),
-                      expected = (str::from_utf8($expected).unwrap(), $expectedk),
-                      $($key = $val),*);
-    })
-}
-
-fn ldexp_f32(a: f32, b: i32) -> f32 {
-    ldexp_f64(a as f64, b) as f32
-}
-
-fn ldexp_f64(a: f64, b: i32) -> f64 {
-    extern {
-        fn ldexp(x: f64, n: i32) -> f64;
-    }
-    unsafe { ldexp(a, b) }
-}
-
-fn check_exact<F, T>(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16)
-        where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
-    // use a large enough buffer
-    let mut buf = [b'_'; 1024];
-    let mut expected_ = [b'_'; 1024];
-
-    let decoded = decode_finite(v);
-    let cut = expected.iter().position(|&c| c == b' ');
-
-    // check significant digits
-    for i in 1..cut.unwrap_or(expected.len() - 1) {
-        expected_[..i].copy_from_slice(&expected[..i]);
-        let mut expectedk_ = expectedk;
-        if expected[i] >= b'5' {
-            // check if this is a rounding-to-even case.
-            // we avoid rounding ...x5000... (with infinite zeroes) to ...(x+1) when x is even.
-            if !(i+1 < expected.len() && expected[i-1] & 1 == 0 &&
-                                         expected[i] == b'5' &&
-                                         expected[i+1] == b' ') {
-                // if this returns true, expected_[..i] is all `9`s and being rounded up.
-                // we should always return `100..00` (`i` digits) instead, since that's
-                // what we can came up with `i` digits anyway. `round_up` assumes that
-                // the adjustment to the length is done by caller, which we simply ignore.
-                if let Some(_) = round_up(&mut expected_, i) { expectedk_ += 1; }
-            }
-        }
-
-        try_exact!(f(&decoded) => &mut buf, &expected_[..i], expectedk_;
-                   "exact sigdigit mismatch for v={v}, i={i}: \
-                    actual {actual:?}, expected {expected:?}",
-                   v = vstr, i = i);
-        try_fixed!(f(&decoded) => &mut buf, expectedk_ - i as i16, &expected_[..i], expectedk_;
-                   "fixed sigdigit mismatch for v={v}, i={i}: \
-                    actual {actual:?}, expected {expected:?}",
-                   v = vstr, i = i);
-    }
-
-    // check exact rounding for zero- and negative-width cases
-    let start;
-    if expected[0] >= b'5' {
-        try_fixed!(f(&decoded) => &mut buf, expectedk, b"1", expectedk + 1;
-                   "zero-width rounding-up mismatch for v={v}: \
-                    actual {actual:?}, expected {expected:?}",
-                   v = vstr);
-        start = 1;
-    } else {
-        start = 0;
-    }
-    for i in start..-10 {
-        try_fixed!(f(&decoded) => &mut buf, expectedk - i, b"", expectedk;
-                   "rounding-down mismatch for v={v}, i={i}: \
-                    actual {actual:?}, expected {expected:?}",
-                   v = vstr, i = -i);
-    }
-
-    // check infinite zero digits
-    if let Some(cut) = cut {
-        for i in cut..expected.len()-1 {
-            expected_[..cut].copy_from_slice(&expected[..cut]);
-            for c in &mut expected_[cut..i] { *c = b'0'; }
-
-            try_exact!(f(&decoded) => &mut buf, &expected_[..i], expectedk;
-                       "exact infzero mismatch for v={v}, i={i}: \
-                        actual {actual:?}, expected {expected:?}",
-                       v = vstr, i = i);
-            try_fixed!(f(&decoded) => &mut buf, expectedk - i as i16, &expected_[..i], expectedk;
-                       "fixed infzero mismatch for v={v}, i={i}: \
-                        actual {actual:?}, expected {expected:?}",
-                       v = vstr, i = i);
-        }
-    }
-}
-
-trait TestableFloat : DecodableFloat + fmt::Display {
-    /// Returns `x * 2^exp`. Almost same to `std::{f32,f64}::ldexp`.
-    /// This is used for testing.
-    fn ldexpi(f: i64, exp: isize) -> Self;
-}
-
-impl TestableFloat for f32 {
-    fn ldexpi(f: i64, exp: isize) -> Self { f as Self * (exp as Self).exp2() }
-}
-
-impl TestableFloat for f64 {
-    fn ldexpi(f: i64, exp: isize) -> Self { f as Self * (exp as Self).exp2() }
-}
-
-fn check_exact_one<F, T>(mut f: F, x: i64, e: isize, tstr: &str, expected: &[u8], expectedk: i16)
-        where T: TestableFloat,
-              F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
-    // use a large enough buffer
-    let mut buf = [b'_'; 1024];
-    let v: T = TestableFloat::ldexpi(x, e);
-    let decoded = decode_finite(v);
-
-    try_exact!(f(&decoded) => &mut buf, &expected, expectedk;
-               "exact mismatch for v={x}p{e}{t}: actual {actual:?}, expected {expected:?}",
-               x = x, e = e, t = tstr);
-    try_fixed!(f(&decoded) => &mut buf, expectedk - expected.len() as i16, &expected, expectedk;
-               "fixed mismatch for v={x}p{e}{t}: actual {actual:?}, expected {expected:?}",
-               x = x, e = e, t = tstr);
-}
-
-macro_rules! check_exact {
-    ($f:ident($v:expr) => $buf:expr, $exp:expr) => (
-        check_exact(|d,b,k| $f(d,b,k), $v, stringify!($v), $buf, $exp)
-    )
-}
-
-macro_rules! check_exact_one {
-    ($f:ident($x:expr, $e:expr; $t:ty) => $buf:expr, $exp:expr) => (
-        check_exact_one::<_, $t>(|d,b,k| $f(d,b,k), $x, $e, stringify!($t), $buf, $exp)
-    )
-}
-
-// in the following comments, three numbers are spaced by 1 ulp apart,
-// and the second one is being formatted.
-//
-// some tests are derived from [1].
-//
-// [1] Vern Paxson, A Program for Testing IEEE Decimal-Binary Conversion
-//     ftp://ftp.ee.lbl.gov/testbase-report.ps.Z
-
-pub fn f32_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
-    // 0.0999999940395355224609375
-    // 0.100000001490116119384765625
-    // 0.10000000894069671630859375
-    check_shortest!(f(0.1f32) => b"1", 0);
-
-    // 0.333333313465118408203125
-    // 0.3333333432674407958984375 (1/3 in the default rounding)
-    // 0.33333337306976318359375
-    check_shortest!(f(1.0f32/3.0) => b"33333334", 0);
-
-    // 10^1 * 0.31415917873382568359375
-    // 10^1 * 0.31415920257568359375
-    // 10^1 * 0.31415922641754150390625
-    check_shortest!(f(3.141592f32) => b"3141592", 1);
-
-    // 10^18 * 0.31415916243714048
-    // 10^18 * 0.314159196796878848
-    // 10^18 * 0.314159231156617216
-    check_shortest!(f(3.141592e17f32) => b"3141592", 18);
-
-    // regression test for decoders
-    // 10^8 * 0.3355443
-    // 10^8 * 0.33554432
-    // 10^8 * 0.33554436
-    check_shortest!(f(ldexp_f32(1.0, 25)) => b"33554432", 8);
-
-    // 10^39 * 0.340282326356119256160033759537265639424
-    // 10^39 * 0.34028234663852885981170418348451692544
-    // 10^39 * 0.340282366920938463463374607431768211456
-    check_shortest!(f(f32::MAX) => b"34028235", 39);
-
-    // 10^-37 * 0.1175494210692441075487029444849287348827...
-    // 10^-37 * 0.1175494350822287507968736537222245677818...
-    // 10^-37 * 0.1175494490952133940450443629595204006810...
-    check_shortest!(f(f32::MIN_POSITIVE) => b"11754944", -37);
-
-    // 10^-44 * 0
-    // 10^-44 * 0.1401298464324817070923729583289916131280...
-    // 10^-44 * 0.2802596928649634141847459166579832262560...
-    let minf32 = ldexp_f32(1.0, -149);
-    check_shortest!(f(minf32) => b"1", -44);
-}
-
-pub fn f32_exact_sanity_test<F>(mut f: F)
-        where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
-    let minf32 = ldexp_f32(1.0, -149);
-
-    check_exact!(f(0.1f32)            => b"100000001490116119384765625             ", 0);
-    check_exact!(f(0.5f32)            => b"5                                       ", 0);
-    check_exact!(f(1.0f32/3.0)        => b"3333333432674407958984375               ", 0);
-    check_exact!(f(3.141592f32)       => b"31415920257568359375                    ", 1);
-    check_exact!(f(3.141592e17f32)    => b"314159196796878848                      ", 18);
-    check_exact!(f(f32::MAX)          => b"34028234663852885981170418348451692544  ", 39);
-    check_exact!(f(f32::MIN_POSITIVE) => b"1175494350822287507968736537222245677818", -37);
-    check_exact!(f(minf32)            => b"1401298464324817070923729583289916131280", -44);
-
-    // [1], Table 16: Stress Inputs for Converting 24-bit Binary to Decimal, < 1/2 ULP
-    check_exact_one!(f(12676506, -102; f32) => b"2",            -23);
-    check_exact_one!(f(12676506, -103; f32) => b"12",           -23);
-    check_exact_one!(f(15445013,   86; f32) => b"119",           34);
-    check_exact_one!(f(13734123, -138; f32) => b"3941",         -34);
-    check_exact_one!(f(12428269, -130; f32) => b"91308",        -32);
-    check_exact_one!(f(15334037, -146; f32) => b"171900",       -36);
-    check_exact_one!(f(11518287,  -41; f32) => b"5237910",       -5);
-    check_exact_one!(f(12584953, -145; f32) => b"28216440",     -36);
-    check_exact_one!(f(15961084, -125; f32) => b"375243281",    -30);
-    check_exact_one!(f(14915817, -146; f32) => b"1672120916",   -36);
-    check_exact_one!(f(10845484, -102; f32) => b"21388945814",  -23);
-    check_exact_one!(f(16431059,  -61; f32) => b"712583594561", -11);
-
-    // [1], Table 17: Stress Inputs for Converting 24-bit Binary to Decimal, > 1/2 ULP
-    check_exact_one!(f(16093626,   69; f32) => b"1",             29);
-    check_exact_one!(f( 9983778,   25; f32) => b"34",            15);
-    check_exact_one!(f(12745034,  104; f32) => b"259",           39);
-    check_exact_one!(f(12706553,   72; f32) => b"6001",          29);
-    check_exact_one!(f(11005028,   45; f32) => b"38721",         21);
-    check_exact_one!(f(15059547,   71; f32) => b"355584",        29);
-    check_exact_one!(f(16015691,  -99; f32) => b"2526831",      -22);
-    check_exact_one!(f( 8667859,   56; f32) => b"62458507",      24);
-    check_exact_one!(f(14855922,  -82; f32) => b"307213267",    -17);
-    check_exact_one!(f(14855922,  -83; f32) => b"1536066333",   -17);
-    check_exact_one!(f(10144164, -110; f32) => b"78147796834",  -26);
-    check_exact_one!(f(13248074,   95; f32) => b"524810279937",  36);
-}
-
-pub fn f64_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
-    // 0.0999999999999999777955395074968691915273...
-    // 0.1000000000000000055511151231257827021181...
-    // 0.1000000000000000333066907387546962127089...
-    check_shortest!(f(0.1f64) => b"1", 0);
-
-    // this example is explicitly mentioned in the paper.
-    // 10^3 * 0.0999999999999999857891452847979962825775...
-    // 10^3 * 0.1 (exact)
-    // 10^3 * 0.1000000000000000142108547152020037174224...
-    check_shortest!(f(100.0f64) => b"1", 3);
-
-    // 0.3333333333333332593184650249895639717578...
-    // 0.3333333333333333148296162562473909929394... (1/3 in the default rounding)
-    // 0.3333333333333333703407674875052180141210...
-    check_shortest!(f(1.0f64/3.0) => b"3333333333333333", 0);
-
-    // explicit test case for equally closest representations.
-    // Dragon has its own tie-breaking rule; Grisu should fall back.
-    // 10^1 * 0.1000007629394531027955395074968691915273...
-    // 10^1 * 0.100000762939453125 (exact)
-    // 10^1 * 0.1000007629394531472044604925031308084726...
-    check_shortest!(f(1.00000762939453125f64) => b"10000076293945313", 1);
-
-    // 10^1 * 0.3141591999999999718085064159822650253772...
-    // 10^1 * 0.3141592000000000162174274009885266423225...
-    // 10^1 * 0.3141592000000000606263483859947882592678...
-    check_shortest!(f(3.141592f64) => b"3141592", 1);
-
-    // 10^18 * 0.314159199999999936
-    // 10^18 * 0.3141592 (exact)
-    // 10^18 * 0.314159200000000064
-    check_shortest!(f(3.141592e17f64) => b"3141592", 18);
-
-    // regression test for decoders
-    // 10^20 * 0.18446744073709549568
-    // 10^20 * 0.18446744073709551616
-    // 10^20 * 0.18446744073709555712
-    check_shortest!(f(ldexp_f64(1.0, 64)) => b"18446744073709552", 20);
-
-    // pathological case: high = 10^23 (exact). tie breaking should always prefer that.
-    // 10^24 * 0.099999999999999974834176
-    // 10^24 * 0.099999999999999991611392
-    // 10^24 * 0.100000000000000008388608
-    check_shortest!(f(1.0e23f64) => b"1", 24);
-
-    // 10^309 * 0.1797693134862315508561243283845062402343...
-    // 10^309 * 0.1797693134862315708145274237317043567980...
-    // 10^309 * 0.1797693134862315907729305190789024733617...
-    check_shortest!(f(f64::MAX) => b"17976931348623157", 309);
-
-    // 10^-307 * 0.2225073858507200889024586876085859887650...
-    // 10^-307 * 0.2225073858507201383090232717332404064219...
-    // 10^-307 * 0.2225073858507201877155878558578948240788...
-    check_shortest!(f(f64::MIN_POSITIVE) => b"22250738585072014", -307);
-
-    // 10^-323 * 0
-    // 10^-323 * 0.4940656458412465441765687928682213723650...
-    // 10^-323 * 0.9881312916824930883531375857364427447301...
-    let minf64 = ldexp_f64(1.0, -1074);
-    check_shortest!(f(minf64) => b"5", -323);
-}
-
-pub fn f64_exact_sanity_test<F>(mut f: F)
-        where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
-    let minf64 = ldexp_f64(1.0, -1074);
-
-    check_exact!(f(0.1f64)            => b"1000000000000000055511151231257827021181", 0);
-    check_exact!(f(0.45f64)           => b"4500000000000000111022302462515654042363", 0);
-    check_exact!(f(0.5f64)            => b"5                                       ", 0);
-    check_exact!(f(0.95f64)           => b"9499999999999999555910790149937383830547", 0);
-    check_exact!(f(100.0f64)          => b"1                                       ", 3);
-    check_exact!(f(999.5f64)          => b"9995000000000000000000000000000000000000", 3);
-    check_exact!(f(1.0f64/3.0)        => b"3333333333333333148296162562473909929394", 0);
-    check_exact!(f(3.141592f64)       => b"3141592000000000162174274009885266423225", 1);
-    check_exact!(f(3.141592e17f64)    => b"3141592                                 ", 18);
-    check_exact!(f(1.0e23f64)         => b"99999999999999991611392                 ", 23);
-    check_exact!(f(f64::MAX)          => b"1797693134862315708145274237317043567980", 309);
-    check_exact!(f(f64::MIN_POSITIVE) => b"2225073858507201383090232717332404064219", -307);
-    check_exact!(f(minf64)            => b"4940656458412465441765687928682213723650\
-                                           5980261432476442558568250067550727020875\
-                                           1865299836361635992379796564695445717730\
-                                           9266567103559397963987747960107818781263\
-                                           0071319031140452784581716784898210368871\
-                                           8636056998730723050006387409153564984387\
-                                           3124733972731696151400317153853980741262\
-                                           3856559117102665855668676818703956031062\
-                                           4931945271591492455329305456544401127480\
-                                           1297099995419319894090804165633245247571\
-                                           4786901472678015935523861155013480352649\
-                                           3472019379026810710749170333222684475333\
-                                           5720832431936092382893458368060106011506\
-                                           1698097530783422773183292479049825247307\
-                                           7637592724787465608477820373446969953364\
-                                           7017972677717585125660551199131504891101\
-                                           4510378627381672509558373897335989936648\
-                                           0994116420570263709027924276754456522908\
-                                           7538682506419718265533447265625         ", -323);
-
-    // [1], Table 3: Stress Inputs for Converting 53-bit Binary to Decimal, < 1/2 ULP
-    check_exact_one!(f(8511030020275656,  -342; f64) => b"9",                       -87);
-    check_exact_one!(f(5201988407066741,  -824; f64) => b"46",                     -232);
-    check_exact_one!(f(6406892948269899,   237; f64) => b"141",                      88);
-    check_exact_one!(f(8431154198732492,    72; f64) => b"3981",                     38);
-    check_exact_one!(f(6475049196144587,    99; f64) => b"41040",                    46);
-    check_exact_one!(f(8274307542972842,   726; f64) => b"292084",                  235);
-    check_exact_one!(f(5381065484265332,  -456; f64) => b"2891946",                -121);
-    check_exact_one!(f(6761728585499734, -1057; f64) => b"43787718",               -302);
-    check_exact_one!(f(7976538478610756,   376; f64) => b"122770163",               130);
-    check_exact_one!(f(5982403858958067,   377; f64) => b"1841552452",              130);
-    check_exact_one!(f(5536995190630837,    93; f64) => b"54835744350",              44);
-    check_exact_one!(f(7225450889282194,   710; f64) => b"389190181146",            230);
-    check_exact_one!(f(7225450889282194,   709; f64) => b"1945950905732",           230);
-    check_exact_one!(f(8703372741147379,   117; f64) => b"14460958381605",           52);
-    check_exact_one!(f(8944262675275217, -1001; f64) => b"417367747458531",        -285);
-    check_exact_one!(f(7459803696087692,  -707; f64) => b"1107950772878888",       -196);
-    check_exact_one!(f(6080469016670379,  -381; f64) => b"12345501366327440",       -98);
-    check_exact_one!(f(8385515147034757,   721; f64) => b"925031711960365024",      233);
-    check_exact_one!(f(7514216811389786,  -828; f64) => b"4198047150284889840",    -233);
-    check_exact_one!(f(8397297803260511,  -345; f64) => b"11716315319786511046",    -87);
-    check_exact_one!(f(6733459239310543,   202; f64) => b"432810072844612493629",    77);
-    check_exact_one!(f(8091450587292794,  -473; f64) => b"3317710118160031081518", -126);
-
-    // [1], Table 4: Stress Inputs for Converting 53-bit Binary to Decimal, > 1/2 ULP
-    check_exact_one!(f(6567258882077402,   952; f64) => b"3",                       303);
-    check_exact_one!(f(6712731423444934,   535; f64) => b"76",                      177);
-    check_exact_one!(f(6712731423444934,   534; f64) => b"378",                     177);
-    check_exact_one!(f(5298405411573037,  -957; f64) => b"4350",                   -272);
-    check_exact_one!(f(5137311167659507,  -144; f64) => b"23037",                   -27);
-    check_exact_one!(f(6722280709661868,   363; f64) => b"126301",                  126);
-    check_exact_one!(f(5344436398034927,  -169; f64) => b"7142211",                 -35);
-    check_exact_one!(f(8369123604277281,  -853; f64) => b"13934574",               -240);
-    check_exact_one!(f(8995822108487663,  -780; f64) => b"141463449",              -218);
-    check_exact_one!(f(8942832835564782,  -383; f64) => b"4539277920",              -99);
-    check_exact_one!(f(8942832835564782,  -384; f64) => b"22696389598",             -99);
-    check_exact_one!(f(8942832835564782,  -385; f64) => b"113481947988",            -99);
-    check_exact_one!(f(6965949469487146,  -249; f64) => b"7700366561890",           -59);
-    check_exact_one!(f(6965949469487146,  -250; f64) => b"38501832809448",          -59);
-    check_exact_one!(f(6965949469487146,  -251; f64) => b"192509164047238",         -59);
-    check_exact_one!(f(7487252720986826,   548; f64) => b"6898586531774201",        181);
-    check_exact_one!(f(5592117679628511,   164; f64) => b"13076622631878654",        66);
-    check_exact_one!(f(8887055249355788,   665; f64) => b"136052020756121240",      217);
-    check_exact_one!(f(6994187472632449,   690; f64) => b"3592810217475959676",     224);
-    check_exact_one!(f(8797576579012143,   588; f64) => b"89125197712484551899",    193);
-    check_exact_one!(f(7363326733505337,   272; f64) => b"558769757362301140950",    98);
-    check_exact_one!(f(8549497411294502,  -448; f64) => b"1176257830728540379990", -118);
-}
-
-pub fn more_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
-    check_shortest!(f{mant: 99_999_999_999_999_999, minus: 1, plus: 1,
-                      exp: 0, inclusive: true} => b"1", 18);
-    check_shortest!(f{mant: 99_999_999_999_999_999, minus: 1, plus: 1,
-                      exp: 0, inclusive: false} => b"99999999999999999", 17);
-}
-
-fn iterate<F, G, V>(func: &str, k: usize, n: usize, mut f: F, mut g: G, mut v: V) -> (usize, usize)
-        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
-              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
-              V: FnMut(usize) -> Decoded {
-    assert!(k <= 1024);
-
-    let mut npassed = 0; // f(x) = Some(g(x))
-    let mut nignored = 0; // f(x) = None
-
-    for i in 0..n {
-        if (i & 0xfffff) == 0 {
-            println!("in progress, {:x}/{:x} (ignored={} passed={} failed={})",
-                     i, n, nignored, npassed, i - nignored - npassed);
-        }
-
-        let decoded = v(i);
-        let mut buf1 = [0; 1024];
-        if let Some((len1, e1)) = f(&decoded, &mut buf1[..k]) {
-            let mut buf2 = [0; 1024];
-            let (len2, e2) = g(&decoded, &mut buf2[..k]);
-            if e1 == e2 && &buf1[..len1] == &buf2[..len2] {
-                npassed += 1;
-            } else {
-                println!("equivalence test failed, {:x}/{:x}: {:?} f(i)={}e{} g(i)={}e{}",
-                         i, n, decoded, str::from_utf8(&buf1[..len1]).unwrap(), e1,
-                                        str::from_utf8(&buf2[..len2]).unwrap(), e2);
-            }
-        } else {
-            nignored += 1;
-        }
-    }
-    println!("{}({}): done, ignored={} passed={} failed={}",
-             func, k, nignored, npassed, n - nignored - npassed);
-    assert!(nignored + npassed == n,
-            "{}({}): {} out of {} values returns an incorrect value!",
-            func, k, n - nignored - npassed, n);
-    (npassed, nignored)
-}
-
-pub fn f32_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
-        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
-              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
-    let mut rng: XorShiftRng = Rand::rand(&mut rand::thread_rng());
-    let f32_range = Range::new(0x0000_0001u32, 0x7f80_0000);
-    iterate("f32_random_equivalence_test", k, n, f, g, |_| {
-        let i: u32 = f32_range.ind_sample(&mut rng);
-        let x: f32 = unsafe {mem::transmute(i)};
-        decode_finite(x)
-    });
-}
-
-pub fn f64_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
-        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
-              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
-    let mut rng: XorShiftRng = Rand::rand(&mut rand::thread_rng());
-    let f64_range = Range::new(0x0000_0000_0000_0001u64, 0x7ff0_0000_0000_0000);
-    iterate("f64_random_equivalence_test", k, n, f, g, |_| {
-        let i: u64 = f64_range.ind_sample(&mut rng);
-        let x: f64 = unsafe {mem::transmute(i)};
-        decode_finite(x)
-    });
-}
-
-pub fn f32_exhaustive_equivalence_test<F, G>(f: F, g: G, k: usize)
-        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
-              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
-    // we have only 2^23 * (2^8 - 1) - 1 = 2,139,095,039 positive finite f32 values,
-    // so why not simply testing all of them?
-    //
-    // this is of course very stressful (and thus should be behind an `#[ignore]` attribute),
-    // but with `-C opt-level=3 -C lto` this only takes about an hour or so.
-
-    // iterate from 0x0000_0001 to 0x7f7f_ffff, i.e. all finite ranges
-    let (npassed, nignored) = iterate("f32_exhaustive_equivalence_test",
-                                      k, 0x7f7f_ffff, f, g, |i: usize| {
-        let x: f32 = unsafe {mem::transmute(i as u32 + 1)};
-        decode_finite(x)
-    });
-    assert_eq!((npassed, nignored), (2121451881, 17643158));
-}
-
-fn to_string_with_parts<F>(mut f: F) -> String
-        where F: for<'a> FnMut(&'a mut [u8], &'a mut [Part<'a>]) -> Formatted<'a> {
-    let mut buf = [0; 1024];
-    let mut parts = [Part::Zero(0); 16];
-    let formatted = f(&mut buf, &mut parts);
-    let mut ret = vec![0; formatted.len()];
-    assert_eq!(formatted.write(&mut ret), Some(ret.len()));
-    String::from_utf8(ret).unwrap()
-}
-
-pub fn to_shortest_str_test<F>(mut f_: F)
-        where F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
-    use core::num::flt2dec::Sign::*;
-
-    fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize, upper: bool) -> String
-            where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
-        to_string_with_parts(|buf, parts| to_shortest_str(|d,b| f(d,b), v, sign,
-                                                          frac_digits, upper, buf, parts))
-    }
-
-    let f = &mut f_;
-
-    assert_eq!(to_string(f,  0.0, Minus,        0, false), "0");
-    assert_eq!(to_string(f,  0.0, MinusRaw,     0, false), "0");
-    assert_eq!(to_string(f,  0.0, MinusPlus,    0, false), "+0");
-    assert_eq!(to_string(f,  0.0, MinusPlusRaw, 0, false), "+0");
-    assert_eq!(to_string(f, -0.0, Minus,        0, false), "0");
-    assert_eq!(to_string(f, -0.0, MinusRaw,     0, false), "-0");
-    assert_eq!(to_string(f, -0.0, MinusPlus,    0, false), "+0");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 0, false), "-0");
-    assert_eq!(to_string(f,  0.0, Minus,        1,  true), "0.0");
-    assert_eq!(to_string(f,  0.0, MinusRaw,     1,  true), "0.0");
-    assert_eq!(to_string(f,  0.0, MinusPlus,    1,  true), "+0.0");
-    assert_eq!(to_string(f,  0.0, MinusPlusRaw, 1,  true), "+0.0");
-    assert_eq!(to_string(f, -0.0, Minus,        8,  true), "0.00000000");
-    assert_eq!(to_string(f, -0.0, MinusRaw,     8,  true), "-0.00000000");
-    assert_eq!(to_string(f, -0.0, MinusPlus,    8,  true), "+0.00000000");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8,  true), "-0.00000000");
-
-    assert_eq!(to_string(f,  1.0/0.0, Minus,         0, false), "inf");
-    assert_eq!(to_string(f,  1.0/0.0, MinusRaw,      0,  true), "inf");
-    assert_eq!(to_string(f,  1.0/0.0, MinusPlus,     0, false), "+inf");
-    assert_eq!(to_string(f,  1.0/0.0, MinusPlusRaw,  0,  true), "+inf");
-    assert_eq!(to_string(f,  0.0/0.0, Minus,         0, false), "NaN");
-    assert_eq!(to_string(f,  0.0/0.0, MinusRaw,      1,  true), "NaN");
-    assert_eq!(to_string(f,  0.0/0.0, MinusPlus,     8, false), "NaN");
-    assert_eq!(to_string(f,  0.0/0.0, MinusPlusRaw, 64,  true), "NaN");
-    assert_eq!(to_string(f, -1.0/0.0, Minus,         0, false), "-inf");
-    assert_eq!(to_string(f, -1.0/0.0, MinusRaw,      1,  true), "-inf");
-    assert_eq!(to_string(f, -1.0/0.0, MinusPlus,     8, false), "-inf");
-    assert_eq!(to_string(f, -1.0/0.0, MinusPlusRaw, 64,  true), "-inf");
-
-    assert_eq!(to_string(f,  3.14, Minus,        0, false), "3.14");
-    assert_eq!(to_string(f,  3.14, MinusRaw,     0, false), "3.14");
-    assert_eq!(to_string(f,  3.14, MinusPlus,    0, false), "+3.14");
-    assert_eq!(to_string(f,  3.14, MinusPlusRaw, 0, false), "+3.14");
-    assert_eq!(to_string(f, -3.14, Minus,        0, false), "-3.14");
-    assert_eq!(to_string(f, -3.14, MinusRaw,     0, false), "-3.14");
-    assert_eq!(to_string(f, -3.14, MinusPlus,    0, false), "-3.14");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 0, false), "-3.14");
-    assert_eq!(to_string(f,  3.14, Minus,        1,  true), "3.14");
-    assert_eq!(to_string(f,  3.14, MinusRaw,     2,  true), "3.14");
-    assert_eq!(to_string(f,  3.14, MinusPlus,    3,  true), "+3.140");
-    assert_eq!(to_string(f,  3.14, MinusPlusRaw, 4,  true), "+3.1400");
-    assert_eq!(to_string(f, -3.14, Minus,        8,  true), "-3.14000000");
-    assert_eq!(to_string(f, -3.14, MinusRaw,     8,  true), "-3.14000000");
-    assert_eq!(to_string(f, -3.14, MinusPlus,    8,  true), "-3.14000000");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 8,  true), "-3.14000000");
-
-    assert_eq!(to_string(f, 7.5e-11, Minus,  0, false), "0.000000000075");
-    assert_eq!(to_string(f, 7.5e-11, Minus,  3, false), "0.000000000075");
-    assert_eq!(to_string(f, 7.5e-11, Minus, 12, false), "0.000000000075");
-    assert_eq!(to_string(f, 7.5e-11, Minus, 13, false), "0.0000000000750");
-
-    assert_eq!(to_string(f, 1.9971e20, Minus, 0, false), "199710000000000000000");
-    assert_eq!(to_string(f, 1.9971e20, Minus, 1, false), "199710000000000000000.0");
-    assert_eq!(to_string(f, 1.9971e20, Minus, 8, false), "199710000000000000000.00000000");
-
-    assert_eq!(to_string(f, f32::MAX, Minus, 0, false), format!("34028235{:0>31}", ""));
-    assert_eq!(to_string(f, f32::MAX, Minus, 1, false), format!("34028235{:0>31}.0", ""));
-    assert_eq!(to_string(f, f32::MAX, Minus, 8, false), format!("34028235{:0>31}.00000000", ""));
-
-    let minf32 = ldexp_f32(1.0, -149);
-    assert_eq!(to_string(f, minf32, Minus,  0, false), format!("0.{:0>44}1", ""));
-    assert_eq!(to_string(f, minf32, Minus, 45, false), format!("0.{:0>44}1", ""));
-    assert_eq!(to_string(f, minf32, Minus, 46, false), format!("0.{:0>44}10", ""));
-
-    assert_eq!(to_string(f, f64::MAX, Minus, 0, false),
-               format!("17976931348623157{:0>292}", ""));
-    assert_eq!(to_string(f, f64::MAX, Minus, 1, false),
-               format!("17976931348623157{:0>292}.0", ""));
-    assert_eq!(to_string(f, f64::MAX, Minus, 8, false),
-               format!("17976931348623157{:0>292}.00000000", ""));
-
-    let minf64 = ldexp_f64(1.0, -1074);
-    assert_eq!(to_string(f, minf64, Minus,   0, false), format!("0.{:0>323}5", ""));
-    assert_eq!(to_string(f, minf64, Minus, 324, false), format!("0.{:0>323}5", ""));
-    assert_eq!(to_string(f, minf64, Minus, 325, false), format!("0.{:0>323}50", ""));
-
-    // very large output
-    assert_eq!(to_string(f, 1.1, Minus, 80000, false), format!("1.1{:0>79999}", ""));
-}
-
-pub fn to_shortest_exp_str_test<F>(mut f_: F)
-        where F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
-    use core::num::flt2dec::Sign::*;
-
-    fn to_string<T, F>(f: &mut F, v: T, sign: Sign, exp_bounds: (i16, i16), upper: bool) -> String
-            where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
-        to_string_with_parts(|buf, parts| to_shortest_exp_str(|d,b| f(d,b), v, sign,
-                                                              exp_bounds, upper, buf, parts))
-    }
-
-    let f = &mut f_;
-
-    assert_eq!(to_string(f,  0.0, Minus,        (-4, 16), false), "0");
-    assert_eq!(to_string(f,  0.0, MinusRaw,     (-4, 16), false), "0");
-    assert_eq!(to_string(f,  0.0, MinusPlus,    (-4, 16), false), "+0");
-    assert_eq!(to_string(f,  0.0, MinusPlusRaw, (-4, 16), false), "+0");
-    assert_eq!(to_string(f, -0.0, Minus,        (-4, 16), false), "0");
-    assert_eq!(to_string(f, -0.0, MinusRaw,     (-4, 16), false), "-0");
-    assert_eq!(to_string(f, -0.0, MinusPlus,    (-4, 16), false), "+0");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, (-4, 16), false), "-0");
-    assert_eq!(to_string(f,  0.0, Minus,        ( 0,  0),  true), "0E0");
-    assert_eq!(to_string(f,  0.0, MinusRaw,     ( 0,  0), false), "0e0");
-    assert_eq!(to_string(f,  0.0, MinusPlus,    (-9, -5),  true), "+0E0");
-    assert_eq!(to_string(f,  0.0, MinusPlusRaw, ( 5,  9), false), "+0e0");
-    assert_eq!(to_string(f, -0.0, Minus,        ( 0,  0),  true), "0E0");
-    assert_eq!(to_string(f, -0.0, MinusRaw,     ( 0,  0), false), "-0e0");
-    assert_eq!(to_string(f, -0.0, MinusPlus,    (-9, -5),  true), "+0E0");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, ( 5,  9), false), "-0e0");
-
-    assert_eq!(to_string(f,  1.0/0.0, Minus,        (-4, 16), false), "inf");
-    assert_eq!(to_string(f,  1.0/0.0, MinusRaw,     (-4, 16),  true), "inf");
-    assert_eq!(to_string(f,  1.0/0.0, MinusPlus,    (-4, 16), false), "+inf");
-    assert_eq!(to_string(f,  1.0/0.0, MinusPlusRaw, (-4, 16),  true), "+inf");
-    assert_eq!(to_string(f,  0.0/0.0, Minus,        ( 0,  0), false), "NaN");
-    assert_eq!(to_string(f,  0.0/0.0, MinusRaw,     ( 0,  0),  true), "NaN");
-    assert_eq!(to_string(f,  0.0/0.0, MinusPlus,    (-9, -5), false), "NaN");
-    assert_eq!(to_string(f,  0.0/0.0, MinusPlusRaw, ( 5,  9),  true), "NaN");
-    assert_eq!(to_string(f, -1.0/0.0, Minus,        ( 0,  0), false), "-inf");
-    assert_eq!(to_string(f, -1.0/0.0, MinusRaw,     ( 0,  0),  true), "-inf");
-    assert_eq!(to_string(f, -1.0/0.0, MinusPlus,    (-9, -5), false), "-inf");
-    assert_eq!(to_string(f, -1.0/0.0, MinusPlusRaw, ( 5,  9),  true), "-inf");
-
-    assert_eq!(to_string(f,  3.14, Minus,        (-4, 16), false), "3.14");
-    assert_eq!(to_string(f,  3.14, MinusRaw,     (-4, 16), false), "3.14");
-    assert_eq!(to_string(f,  3.14, MinusPlus,    (-4, 16), false), "+3.14");
-    assert_eq!(to_string(f,  3.14, MinusPlusRaw, (-4, 16), false), "+3.14");
-    assert_eq!(to_string(f, -3.14, Minus,        (-4, 16), false), "-3.14");
-    assert_eq!(to_string(f, -3.14, MinusRaw,     (-4, 16), false), "-3.14");
-    assert_eq!(to_string(f, -3.14, MinusPlus,    (-4, 16), false), "-3.14");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, (-4, 16), false), "-3.14");
-    assert_eq!(to_string(f,  3.14, Minus,        ( 0,  0),  true), "3.14E0");
-    assert_eq!(to_string(f,  3.14, MinusRaw,     ( 0,  0), false), "3.14e0");
-    assert_eq!(to_string(f,  3.14, MinusPlus,    (-9, -5),  true), "+3.14E0");
-    assert_eq!(to_string(f,  3.14, MinusPlusRaw, ( 5,  9), false), "+3.14e0");
-    assert_eq!(to_string(f, -3.14, Minus,        ( 0,  0),  true), "-3.14E0");
-    assert_eq!(to_string(f, -3.14, MinusRaw,     ( 0,  0), false), "-3.14e0");
-    assert_eq!(to_string(f, -3.14, MinusPlus,    (-9, -5),  true), "-3.14E0");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, ( 5,  9), false), "-3.14e0");
-
-    assert_eq!(to_string(f,  0.1, Minus,        (-4, 16), false), "0.1");
-    assert_eq!(to_string(f,  0.1, MinusRaw,     (-4, 16), false), "0.1");
-    assert_eq!(to_string(f,  0.1, MinusPlus,    (-4, 16), false), "+0.1");
-    assert_eq!(to_string(f,  0.1, MinusPlusRaw, (-4, 16), false), "+0.1");
-    assert_eq!(to_string(f, -0.1, Minus,        (-4, 16), false), "-0.1");
-    assert_eq!(to_string(f, -0.1, MinusRaw,     (-4, 16), false), "-0.1");
-    assert_eq!(to_string(f, -0.1, MinusPlus,    (-4, 16), false), "-0.1");
-    assert_eq!(to_string(f, -0.1, MinusPlusRaw, (-4, 16), false), "-0.1");
-    assert_eq!(to_string(f,  0.1, Minus,        ( 0,  0),  true), "1E-1");
-    assert_eq!(to_string(f,  0.1, MinusRaw,     ( 0,  0), false), "1e-1");
-    assert_eq!(to_string(f,  0.1, MinusPlus,    (-9, -5),  true), "+1E-1");
-    assert_eq!(to_string(f,  0.1, MinusPlusRaw, ( 5,  9), false), "+1e-1");
-    assert_eq!(to_string(f, -0.1, Minus,        ( 0,  0),  true), "-1E-1");
-    assert_eq!(to_string(f, -0.1, MinusRaw,     ( 0,  0), false), "-1e-1");
-    assert_eq!(to_string(f, -0.1, MinusPlus,    (-9, -5),  true), "-1E-1");
-    assert_eq!(to_string(f, -0.1, MinusPlusRaw, ( 5,  9), false), "-1e-1");
-
-    assert_eq!(to_string(f, 7.5e-11, Minus, ( -4, 16), false), "7.5e-11");
-    assert_eq!(to_string(f, 7.5e-11, Minus, (-11, 10), false), "0.000000000075");
-    assert_eq!(to_string(f, 7.5e-11, Minus, (-10, 11), false), "7.5e-11");
-
-    assert_eq!(to_string(f, 1.9971e20, Minus, ( -4, 16), false), "1.9971e20");
-    assert_eq!(to_string(f, 1.9971e20, Minus, (-20, 21), false), "199710000000000000000");
-    assert_eq!(to_string(f, 1.9971e20, Minus, (-21, 20), false), "1.9971e20");
-
-    // the true value of 1.0e23f64 is less than 10^23, but that shouldn't matter here
-    assert_eq!(to_string(f, 1.0e23, Minus, (22, 23), false), "1e23");
-    assert_eq!(to_string(f, 1.0e23, Minus, (23, 24), false), "100000000000000000000000");
-    assert_eq!(to_string(f, 1.0e23, Minus, (24, 25), false), "1e23");
-
-    assert_eq!(to_string(f, f32::MAX, Minus, ( -4, 16), false), "3.4028235e38");
-    assert_eq!(to_string(f, f32::MAX, Minus, (-39, 38), false), "3.4028235e38");
-    assert_eq!(to_string(f, f32::MAX, Minus, (-38, 39), false), format!("34028235{:0>31}", ""));
-
-    let minf32 = ldexp_f32(1.0, -149);
-    assert_eq!(to_string(f, minf32, Minus, ( -4, 16), false), "1e-45");
-    assert_eq!(to_string(f, minf32, Minus, (-44, 45), false), "1e-45");
-    assert_eq!(to_string(f, minf32, Minus, (-45, 44), false), format!("0.{:0>44}1", ""));
-
-    assert_eq!(to_string(f, f64::MAX, Minus, (  -4,  16), false),
-               "1.7976931348623157e308");
-    assert_eq!(to_string(f, f64::MAX, Minus, (-308, 309), false),
-               format!("17976931348623157{:0>292}", ""));
-    assert_eq!(to_string(f, f64::MAX, Minus, (-309, 308), false),
-               "1.7976931348623157e308");
-
-    let minf64 = ldexp_f64(1.0, -1074);
-    assert_eq!(to_string(f, minf64, Minus, (  -4,  16), false), "5e-324");
-    assert_eq!(to_string(f, minf64, Minus, (-324, 323), false), format!("0.{:0>323}5", ""));
-    assert_eq!(to_string(f, minf64, Minus, (-323, 324), false), "5e-324");
-
-    assert_eq!(to_string(f, 1.1, Minus, (i16::MIN, i16::MAX), false), "1.1");
-}
-
-pub fn to_exact_exp_str_test<F>(mut f_: F)
-        where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
-    use core::num::flt2dec::Sign::*;
-
-    fn to_string<T, F>(f: &mut F, v: T, sign: Sign, ndigits: usize, upper: bool) -> String
-            where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
-        to_string_with_parts(|buf, parts| to_exact_exp_str(|d,b,l| f(d,b,l), v, sign,
-                                                           ndigits, upper, buf, parts))
-    }
-
-    let f = &mut f_;
-
-    assert_eq!(to_string(f,  0.0, Minus,        1,  true), "0E0");
-    assert_eq!(to_string(f,  0.0, MinusRaw,     1, false), "0e0");
-    assert_eq!(to_string(f,  0.0, MinusPlus,    1,  true), "+0E0");
-    assert_eq!(to_string(f,  0.0, MinusPlusRaw, 1, false), "+0e0");
-    assert_eq!(to_string(f, -0.0, Minus,        1,  true), "0E0");
-    assert_eq!(to_string(f, -0.0, MinusRaw,     1, false), "-0e0");
-    assert_eq!(to_string(f, -0.0, MinusPlus,    1,  true), "+0E0");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 1, false), "-0e0");
-    assert_eq!(to_string(f,  0.0, Minus,        2,  true), "0.0E0");
-    assert_eq!(to_string(f,  0.0, MinusRaw,     2, false), "0.0e0");
-    assert_eq!(to_string(f,  0.0, MinusPlus,    2,  true), "+0.0E0");
-    assert_eq!(to_string(f,  0.0, MinusPlusRaw, 2, false), "+0.0e0");
-    assert_eq!(to_string(f, -0.0, Minus,        8,  true), "0.0000000E0");
-    assert_eq!(to_string(f, -0.0, MinusRaw,     8, false), "-0.0000000e0");
-    assert_eq!(to_string(f, -0.0, MinusPlus,    8,  true), "+0.0000000E0");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8, false), "-0.0000000e0");
-
-    assert_eq!(to_string(f,  1.0/0.0, Minus,         1, false), "inf");
-    assert_eq!(to_string(f,  1.0/0.0, MinusRaw,      1,  true), "inf");
-    assert_eq!(to_string(f,  1.0/0.0, MinusPlus,     1, false), "+inf");
-    assert_eq!(to_string(f,  1.0/0.0, MinusPlusRaw,  1,  true), "+inf");
-    assert_eq!(to_string(f,  0.0/0.0, Minus,         8, false), "NaN");
-    assert_eq!(to_string(f,  0.0/0.0, MinusRaw,      8,  true), "NaN");
-    assert_eq!(to_string(f,  0.0/0.0, MinusPlus,     8, false), "NaN");
-    assert_eq!(to_string(f,  0.0/0.0, MinusPlusRaw,  8,  true), "NaN");
-    assert_eq!(to_string(f, -1.0/0.0, Minus,        64, false), "-inf");
-    assert_eq!(to_string(f, -1.0/0.0, MinusRaw,     64,  true), "-inf");
-    assert_eq!(to_string(f, -1.0/0.0, MinusPlus,    64, false), "-inf");
-    assert_eq!(to_string(f, -1.0/0.0, MinusPlusRaw, 64,  true), "-inf");
-
-    assert_eq!(to_string(f,  3.14, Minus,        1,  true), "3E0");
-    assert_eq!(to_string(f,  3.14, MinusRaw,     1, false), "3e0");
-    assert_eq!(to_string(f,  3.14, MinusPlus,    1,  true), "+3E0");
-    assert_eq!(to_string(f,  3.14, MinusPlusRaw, 1, false), "+3e0");
-    assert_eq!(to_string(f, -3.14, Minus,        2,  true), "-3.1E0");
-    assert_eq!(to_string(f, -3.14, MinusRaw,     2, false), "-3.1e0");
-    assert_eq!(to_string(f, -3.14, MinusPlus,    2,  true), "-3.1E0");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 2, false), "-3.1e0");
-    assert_eq!(to_string(f,  3.14, Minus,        3,  true), "3.14E0");
-    assert_eq!(to_string(f,  3.14, MinusRaw,     3, false), "3.14e0");
-    assert_eq!(to_string(f,  3.14, MinusPlus,    3,  true), "+3.14E0");
-    assert_eq!(to_string(f,  3.14, MinusPlusRaw, 3, false), "+3.14e0");
-    assert_eq!(to_string(f, -3.14, Minus,        4,  true), "-3.140E0");
-    assert_eq!(to_string(f, -3.14, MinusRaw,     4, false), "-3.140e0");
-    assert_eq!(to_string(f, -3.14, MinusPlus,    4,  true), "-3.140E0");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 4, false), "-3.140e0");
-
-    assert_eq!(to_string(f,  0.195, Minus,        1, false), "2e-1");
-    assert_eq!(to_string(f,  0.195, MinusRaw,     1,  true), "2E-1");
-    assert_eq!(to_string(f,  0.195, MinusPlus,    1, false), "+2e-1");
-    assert_eq!(to_string(f,  0.195, MinusPlusRaw, 1,  true), "+2E-1");
-    assert_eq!(to_string(f, -0.195, Minus,        2, false), "-2.0e-1");
-    assert_eq!(to_string(f, -0.195, MinusRaw,     2,  true), "-2.0E-1");
-    assert_eq!(to_string(f, -0.195, MinusPlus,    2, false), "-2.0e-1");
-    assert_eq!(to_string(f, -0.195, MinusPlusRaw, 2,  true), "-2.0E-1");
-    assert_eq!(to_string(f,  0.195, Minus,        3, false), "1.95e-1");
-    assert_eq!(to_string(f,  0.195, MinusRaw,     3,  true), "1.95E-1");
-    assert_eq!(to_string(f,  0.195, MinusPlus,    3, false), "+1.95e-1");
-    assert_eq!(to_string(f,  0.195, MinusPlusRaw, 3,  true), "+1.95E-1");
-    assert_eq!(to_string(f, -0.195, Minus,        4, false), "-1.950e-1");
-    assert_eq!(to_string(f, -0.195, MinusRaw,     4,  true), "-1.950E-1");
-    assert_eq!(to_string(f, -0.195, MinusPlus,    4, false), "-1.950e-1");
-    assert_eq!(to_string(f, -0.195, MinusPlusRaw, 4,  true), "-1.950E-1");
-
-    assert_eq!(to_string(f, 9.5, Minus,  1, false), "1e1");
-    assert_eq!(to_string(f, 9.5, Minus,  2, false), "9.5e0");
-    assert_eq!(to_string(f, 9.5, Minus,  3, false), "9.50e0");
-    assert_eq!(to_string(f, 9.5, Minus, 30, false), "9.50000000000000000000000000000e0");
-
-    assert_eq!(to_string(f, 1.0e25, Minus,  1, false), "1e25");
-    assert_eq!(to_string(f, 1.0e25, Minus,  2, false), "1.0e25");
-    assert_eq!(to_string(f, 1.0e25, Minus, 15, false), "1.00000000000000e25");
-    assert_eq!(to_string(f, 1.0e25, Minus, 16, false), "1.000000000000000e25");
-    assert_eq!(to_string(f, 1.0e25, Minus, 17, false), "1.0000000000000001e25");
-    assert_eq!(to_string(f, 1.0e25, Minus, 18, false), "1.00000000000000009e25");
-    assert_eq!(to_string(f, 1.0e25, Minus, 19, false), "1.000000000000000091e25");
-    assert_eq!(to_string(f, 1.0e25, Minus, 20, false), "1.0000000000000000906e25");
-    assert_eq!(to_string(f, 1.0e25, Minus, 21, false), "1.00000000000000009060e25");
-    assert_eq!(to_string(f, 1.0e25, Minus, 22, false), "1.000000000000000090597e25");
-    assert_eq!(to_string(f, 1.0e25, Minus, 23, false), "1.0000000000000000905970e25");
-    assert_eq!(to_string(f, 1.0e25, Minus, 24, false), "1.00000000000000009059697e25");
-    assert_eq!(to_string(f, 1.0e25, Minus, 25, false), "1.000000000000000090596966e25");
-    assert_eq!(to_string(f, 1.0e25, Minus, 26, false), "1.0000000000000000905969664e25");
-    assert_eq!(to_string(f, 1.0e25, Minus, 27, false), "1.00000000000000009059696640e25");
-    assert_eq!(to_string(f, 1.0e25, Minus, 30, false), "1.00000000000000009059696640000e25");
-
-    assert_eq!(to_string(f, 1.0e-6, Minus,  1, false), "1e-6");
-    assert_eq!(to_string(f, 1.0e-6, Minus,  2, false), "1.0e-6");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 16, false), "1.000000000000000e-6");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 17, false), "9.9999999999999995e-7");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 18, false), "9.99999999999999955e-7");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 19, false), "9.999999999999999547e-7");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 20, false), "9.9999999999999995475e-7");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 30, false), "9.99999999999999954748111825886e-7");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 40, false),
-               "9.999999999999999547481118258862586856139e-7");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 50, false),
-               "9.9999999999999995474811182588625868561393872369081e-7");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 60, false),
-               "9.99999999999999954748111825886258685613938723690807819366455e-7");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 70, false),
-               "9.999999999999999547481118258862586856139387236908078193664550781250000e-7");
-
-    assert_eq!(to_string(f, f32::MAX, Minus,  1, false), "3e38");
-    assert_eq!(to_string(f, f32::MAX, Minus,  2, false), "3.4e38");
-    assert_eq!(to_string(f, f32::MAX, Minus,  4, false), "3.403e38");
-    assert_eq!(to_string(f, f32::MAX, Minus,  8, false), "3.4028235e38");
-    assert_eq!(to_string(f, f32::MAX, Minus, 16, false), "3.402823466385289e38");
-    assert_eq!(to_string(f, f32::MAX, Minus, 32, false), "3.4028234663852885981170418348452e38");
-    assert_eq!(to_string(f, f32::MAX, Minus, 64, false),
-               "3.402823466385288598117041834845169254400000000000000000000000000e38");
-
-    let minf32 = ldexp_f32(1.0, -149);
-    assert_eq!(to_string(f, minf32, Minus,   1, false), "1e-45");
-    assert_eq!(to_string(f, minf32, Minus,   2, false), "1.4e-45");
-    assert_eq!(to_string(f, minf32, Minus,   4, false), "1.401e-45");
-    assert_eq!(to_string(f, minf32, Minus,   8, false), "1.4012985e-45");
-    assert_eq!(to_string(f, minf32, Minus,  16, false), "1.401298464324817e-45");
-    assert_eq!(to_string(f, minf32, Minus,  32, false), "1.4012984643248170709237295832899e-45");
-    assert_eq!(to_string(f, minf32, Minus,  64, false),
-               "1.401298464324817070923729583289916131280261941876515771757068284e-45");
-    assert_eq!(to_string(f, minf32, Minus, 128, false),
-               "1.401298464324817070923729583289916131280261941876515771757068283\
-                 8897910826858606014866381883621215820312500000000000000000000000e-45");
-
-    assert_eq!(to_string(f, f64::MAX, Minus,   1, false), "2e308");
-    assert_eq!(to_string(f, f64::MAX, Minus,   2, false), "1.8e308");
-    assert_eq!(to_string(f, f64::MAX, Minus,   4, false), "1.798e308");
-    assert_eq!(to_string(f, f64::MAX, Minus,   8, false), "1.7976931e308");
-    assert_eq!(to_string(f, f64::MAX, Minus,  16, false), "1.797693134862316e308");
-    assert_eq!(to_string(f, f64::MAX, Minus,  32, false), "1.7976931348623157081452742373170e308");
-    assert_eq!(to_string(f, f64::MAX, Minus,  64, false),
-               "1.797693134862315708145274237317043567980705675258449965989174768e308");
-    assert_eq!(to_string(f, f64::MAX, Minus, 128, false),
-               "1.797693134862315708145274237317043567980705675258449965989174768\
-                 0315726078002853876058955863276687817154045895351438246423432133e308");
-    assert_eq!(to_string(f, f64::MAX, Minus, 256, false),
-               "1.797693134862315708145274237317043567980705675258449965989174768\
-                 0315726078002853876058955863276687817154045895351438246423432132\
-                 6889464182768467546703537516986049910576551282076245490090389328\
-                 9440758685084551339423045832369032229481658085593321233482747978e308");
-    assert_eq!(to_string(f, f64::MAX, Minus, 512, false),
-               "1.797693134862315708145274237317043567980705675258449965989174768\
-                 0315726078002853876058955863276687817154045895351438246423432132\
-                 6889464182768467546703537516986049910576551282076245490090389328\
-                 9440758685084551339423045832369032229481658085593321233482747978\
-                 2620414472316873817718091929988125040402618412485836800000000000\
-                 0000000000000000000000000000000000000000000000000000000000000000\
-                 0000000000000000000000000000000000000000000000000000000000000000\
-                 0000000000000000000000000000000000000000000000000000000000000000e308");
-
-    // okay, this is becoming tough. fortunately for us, this is almost the worst case.
-    let minf64 = ldexp_f64(1.0, -1074);
-    assert_eq!(to_string(f, minf64, Minus,    1, false), "5e-324");
-    assert_eq!(to_string(f, minf64, Minus,    2, false), "4.9e-324");
-    assert_eq!(to_string(f, minf64, Minus,    4, false), "4.941e-324");
-    assert_eq!(to_string(f, minf64, Minus,    8, false), "4.9406565e-324");
-    assert_eq!(to_string(f, minf64, Minus,   16, false), "4.940656458412465e-324");
-    assert_eq!(to_string(f, minf64, Minus,   32, false), "4.9406564584124654417656879286822e-324");
-    assert_eq!(to_string(f, minf64, Minus,   64, false),
-               "4.940656458412465441765687928682213723650598026143247644255856825e-324");
-    assert_eq!(to_string(f, minf64, Minus,  128, false),
-               "4.940656458412465441765687928682213723650598026143247644255856825\
-                 0067550727020875186529983636163599237979656469544571773092665671e-324");
-    assert_eq!(to_string(f, minf64, Minus,  256, false),
-               "4.940656458412465441765687928682213723650598026143247644255856825\
-                 0067550727020875186529983636163599237979656469544571773092665671\
-                 0355939796398774796010781878126300713190311404527845817167848982\
-                 1036887186360569987307230500063874091535649843873124733972731696e-324");
-    assert_eq!(to_string(f, minf64, Minus,  512, false),
-               "4.940656458412465441765687928682213723650598026143247644255856825\
-                 0067550727020875186529983636163599237979656469544571773092665671\
-                 0355939796398774796010781878126300713190311404527845817167848982\
-                 1036887186360569987307230500063874091535649843873124733972731696\
-                 1514003171538539807412623856559117102665855668676818703956031062\
-                 4931945271591492455329305456544401127480129709999541931989409080\
-                 4165633245247571478690147267801593552386115501348035264934720193\
-                 7902681071074917033322268447533357208324319360923828934583680601e-324");
-    assert_eq!(to_string(f, minf64, Minus, 1024, false),
-               "4.940656458412465441765687928682213723650598026143247644255856825\
-                 0067550727020875186529983636163599237979656469544571773092665671\
-                 0355939796398774796010781878126300713190311404527845817167848982\
-                 1036887186360569987307230500063874091535649843873124733972731696\
-                 1514003171538539807412623856559117102665855668676818703956031062\
-                 4931945271591492455329305456544401127480129709999541931989409080\
-                 4165633245247571478690147267801593552386115501348035264934720193\
-                 7902681071074917033322268447533357208324319360923828934583680601\
-                 0601150616980975307834227731832924790498252473077637592724787465\
-                 6084778203734469699533647017972677717585125660551199131504891101\
-                 4510378627381672509558373897335989936648099411642057026370902792\
-                 4276754456522908753868250641971826553344726562500000000000000000\
-                 0000000000000000000000000000000000000000000000000000000000000000\
-                 0000000000000000000000000000000000000000000000000000000000000000\
-                 0000000000000000000000000000000000000000000000000000000000000000\
-                 0000000000000000000000000000000000000000000000000000000000000000e-324");
-
-    // very large output
-    assert_eq!(to_string(f, 0.0,     Minus, 80000, false), format!("0.{:0>79999}e0", ""));
-    assert_eq!(to_string(f, 1.0e1,   Minus, 80000, false), format!("1.{:0>79999}e1", ""));
-    assert_eq!(to_string(f, 1.0e0,   Minus, 80000, false), format!("1.{:0>79999}e0", ""));
-    assert_eq!(to_string(f, 1.0e-1,  Minus, 80000, false),
-               format!("1.000000000000000055511151231257827021181583404541015625{:0>79945}\
-                        e-1", ""));
-    assert_eq!(to_string(f, 1.0e-20, Minus, 80000, false),
-               format!("9.999999999999999451532714542095716517295037027873924471077157760\
-                         66783064379706047475337982177734375{:0>79901}e-21", ""));
-}
-
-pub fn to_exact_fixed_str_test<F>(mut f_: F)
-        where F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
-    use core::num::flt2dec::Sign::*;
-
-    fn to_string<T, F>(f: &mut F, v: T, sign: Sign, frac_digits: usize, upper: bool) -> String
-            where T: DecodableFloat, F: FnMut(&Decoded, &mut [u8], i16) -> (usize, i16) {
-        to_string_with_parts(|buf, parts| to_exact_fixed_str(|d,b,l| f(d,b,l), v, sign,
-                                                             frac_digits, upper, buf, parts))
-    }
-
-    let f = &mut f_;
-
-    assert_eq!(to_string(f,  0.0, Minus,        0, false), "0");
-    assert_eq!(to_string(f,  0.0, MinusRaw,     0, false), "0");
-    assert_eq!(to_string(f,  0.0, MinusPlus,    0, false), "+0");
-    assert_eq!(to_string(f,  0.0, MinusPlusRaw, 0, false), "+0");
-    assert_eq!(to_string(f, -0.0, Minus,        0, false), "0");
-    assert_eq!(to_string(f, -0.0, MinusRaw,     0, false), "-0");
-    assert_eq!(to_string(f, -0.0, MinusPlus,    0, false), "+0");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 0, false), "-0");
-    assert_eq!(to_string(f,  0.0, Minus,        1,  true), "0.0");
-    assert_eq!(to_string(f,  0.0, MinusRaw,     1,  true), "0.0");
-    assert_eq!(to_string(f,  0.0, MinusPlus,    1,  true), "+0.0");
-    assert_eq!(to_string(f,  0.0, MinusPlusRaw, 1,  true), "+0.0");
-    assert_eq!(to_string(f, -0.0, Minus,        8,  true), "0.00000000");
-    assert_eq!(to_string(f, -0.0, MinusRaw,     8,  true), "-0.00000000");
-    assert_eq!(to_string(f, -0.0, MinusPlus,    8,  true), "+0.00000000");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8,  true), "-0.00000000");
-
-    assert_eq!(to_string(f,  1.0/0.0, Minus,         0, false), "inf");
-    assert_eq!(to_string(f,  1.0/0.0, MinusRaw,      1,  true), "inf");
-    assert_eq!(to_string(f,  1.0/0.0, MinusPlus,     8, false), "+inf");
-    assert_eq!(to_string(f,  1.0/0.0, MinusPlusRaw, 64,  true), "+inf");
-    assert_eq!(to_string(f,  0.0/0.0, Minus,         0, false), "NaN");
-    assert_eq!(to_string(f,  0.0/0.0, MinusRaw,      1,  true), "NaN");
-    assert_eq!(to_string(f,  0.0/0.0, MinusPlus,     8, false), "NaN");
-    assert_eq!(to_string(f,  0.0/0.0, MinusPlusRaw, 64,  true), "NaN");
-    assert_eq!(to_string(f, -1.0/0.0, Minus,         0, false), "-inf");
-    assert_eq!(to_string(f, -1.0/0.0, MinusRaw,      1,  true), "-inf");
-    assert_eq!(to_string(f, -1.0/0.0, MinusPlus,     8, false), "-inf");
-    assert_eq!(to_string(f, -1.0/0.0, MinusPlusRaw, 64,  true), "-inf");
-
-    assert_eq!(to_string(f,  3.14, Minus,        0, false), "3");
-    assert_eq!(to_string(f,  3.14, MinusRaw,     0, false), "3");
-    assert_eq!(to_string(f,  3.14, MinusPlus,    0, false), "+3");
-    assert_eq!(to_string(f,  3.14, MinusPlusRaw, 0, false), "+3");
-    assert_eq!(to_string(f, -3.14, Minus,        0, false), "-3");
-    assert_eq!(to_string(f, -3.14, MinusRaw,     0, false), "-3");
-    assert_eq!(to_string(f, -3.14, MinusPlus,    0, false), "-3");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 0, false), "-3");
-    assert_eq!(to_string(f,  3.14, Minus,        1,  true), "3.1");
-    assert_eq!(to_string(f,  3.14, MinusRaw,     2,  true), "3.14");
-    assert_eq!(to_string(f,  3.14, MinusPlus,    3,  true), "+3.140");
-    assert_eq!(to_string(f,  3.14, MinusPlusRaw, 4,  true), "+3.1400");
-    assert_eq!(to_string(f, -3.14, Minus,        8,  true), "-3.14000000");
-    assert_eq!(to_string(f, -3.14, MinusRaw,     8,  true), "-3.14000000");
-    assert_eq!(to_string(f, -3.14, MinusPlus,    8,  true), "-3.14000000");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 8,  true), "-3.14000000");
-
-    assert_eq!(to_string(f,  0.195, Minus,        0, false), "0");
-    assert_eq!(to_string(f,  0.195, MinusRaw,     0, false), "0");
-    assert_eq!(to_string(f,  0.195, MinusPlus,    0, false), "+0");
-    assert_eq!(to_string(f,  0.195, MinusPlusRaw, 0, false), "+0");
-    assert_eq!(to_string(f, -0.195, Minus,        0, false), "-0");
-    assert_eq!(to_string(f, -0.195, MinusRaw,     0, false), "-0");
-    assert_eq!(to_string(f, -0.195, MinusPlus,    0, false), "-0");
-    assert_eq!(to_string(f, -0.195, MinusPlusRaw, 0, false), "-0");
-    assert_eq!(to_string(f,  0.195, Minus,        1,  true), "0.2");
-    assert_eq!(to_string(f,  0.195, MinusRaw,     2,  true), "0.20");
-    assert_eq!(to_string(f,  0.195, MinusPlus,    3,  true), "+0.195");
-    assert_eq!(to_string(f,  0.195, MinusPlusRaw, 4,  true), "+0.1950");
-    assert_eq!(to_string(f, -0.195, Minus,        5,  true), "-0.19500");
-    assert_eq!(to_string(f, -0.195, MinusRaw,     6,  true), "-0.195000");
-    assert_eq!(to_string(f, -0.195, MinusPlus,    7,  true), "-0.1950000");
-    assert_eq!(to_string(f, -0.195, MinusPlusRaw, 8,  true), "-0.19500000");
-
-    assert_eq!(to_string(f, 999.5, Minus,  0, false), "1000");
-    assert_eq!(to_string(f, 999.5, Minus,  1, false), "999.5");
-    assert_eq!(to_string(f, 999.5, Minus,  2, false), "999.50");
-    assert_eq!(to_string(f, 999.5, Minus,  3, false), "999.500");
-    assert_eq!(to_string(f, 999.5, Minus, 30, false), "999.500000000000000000000000000000");
-
-    assert_eq!(to_string(f, 0.5, Minus, 0, false), "1");
-    assert_eq!(to_string(f, 0.5, Minus, 1, false), "0.5");
-    assert_eq!(to_string(f, 0.5, Minus, 2, false), "0.50");
-    assert_eq!(to_string(f, 0.5, Minus, 3, false), "0.500");
-
-    assert_eq!(to_string(f, 0.95, Minus,  0, false), "1");
-    assert_eq!(to_string(f, 0.95, Minus,  1, false), "0.9"); // because it really is less than 0.95
-    assert_eq!(to_string(f, 0.95, Minus,  2, false), "0.95");
-    assert_eq!(to_string(f, 0.95, Minus,  3, false), "0.950");
-    assert_eq!(to_string(f, 0.95, Minus, 10, false), "0.9500000000");
-    assert_eq!(to_string(f, 0.95, Minus, 30, false), "0.949999999999999955591079014994");
-
-    assert_eq!(to_string(f, 0.095, Minus,  0, false), "0");
-    assert_eq!(to_string(f, 0.095, Minus,  1, false), "0.1");
-    assert_eq!(to_string(f, 0.095, Minus,  2, false), "0.10");
-    assert_eq!(to_string(f, 0.095, Minus,  3, false), "0.095");
-    assert_eq!(to_string(f, 0.095, Minus,  4, false), "0.0950");
-    assert_eq!(to_string(f, 0.095, Minus, 10, false), "0.0950000000");
-    assert_eq!(to_string(f, 0.095, Minus, 30, false), "0.095000000000000001110223024625");
-
-    assert_eq!(to_string(f, 0.0095, Minus,  0, false), "0");
-    assert_eq!(to_string(f, 0.0095, Minus,  1, false), "0.0");
-    assert_eq!(to_string(f, 0.0095, Minus,  2, false), "0.01");
-    assert_eq!(to_string(f, 0.0095, Minus,  3, false), "0.009"); // really is less than 0.0095
-    assert_eq!(to_string(f, 0.0095, Minus,  4, false), "0.0095");
-    assert_eq!(to_string(f, 0.0095, Minus,  5, false), "0.00950");
-    assert_eq!(to_string(f, 0.0095, Minus, 10, false), "0.0095000000");
-    assert_eq!(to_string(f, 0.0095, Minus, 30, false), "0.009499999999999999764077607267");
-
-    assert_eq!(to_string(f, 7.5e-11, Minus,  0, false), "0");
-    assert_eq!(to_string(f, 7.5e-11, Minus,  3, false), "0.000");
-    assert_eq!(to_string(f, 7.5e-11, Minus, 10, false), "0.0000000001");
-    assert_eq!(to_string(f, 7.5e-11, Minus, 11, false), "0.00000000007"); // ditto
-    assert_eq!(to_string(f, 7.5e-11, Minus, 12, false), "0.000000000075");
-    assert_eq!(to_string(f, 7.5e-11, Minus, 13, false), "0.0000000000750");
-    assert_eq!(to_string(f, 7.5e-11, Minus, 20, false), "0.00000000007500000000");
-    assert_eq!(to_string(f, 7.5e-11, Minus, 30, false), "0.000000000074999999999999999501");
-
-    assert_eq!(to_string(f, 1.0e25, Minus, 0, false), "10000000000000000905969664");
-    assert_eq!(to_string(f, 1.0e25, Minus, 1, false), "10000000000000000905969664.0");
-    assert_eq!(to_string(f, 1.0e25, Minus, 3, false), "10000000000000000905969664.000");
-
-    assert_eq!(to_string(f, 1.0e-6, Minus,  0, false), "0");
-    assert_eq!(to_string(f, 1.0e-6, Minus,  3, false), "0.000");
-    assert_eq!(to_string(f, 1.0e-6, Minus,  6, false), "0.000001");
-    assert_eq!(to_string(f, 1.0e-6, Minus,  9, false), "0.000001000");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 12, false), "0.000001000000");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 22, false), "0.0000010000000000000000");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 23, false), "0.00000099999999999999995");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 24, false), "0.000000999999999999999955");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 25, false), "0.0000009999999999999999547");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 35, false), "0.00000099999999999999995474811182589");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 45, false),
-               "0.000000999999999999999954748111825886258685614");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 55, false),
-               "0.0000009999999999999999547481118258862586856139387236908");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 65, false),
-               "0.00000099999999999999995474811182588625868561393872369080781936646");
-    assert_eq!(to_string(f, 1.0e-6, Minus, 75, false),
-               "0.000000999999999999999954748111825886258685613938723690807819366455078125000");
-
-    assert_eq!(to_string(f, f32::MAX, Minus, 0, false),
-               "340282346638528859811704183484516925440");
-    assert_eq!(to_string(f, f32::MAX, Minus, 1, false),
-               "340282346638528859811704183484516925440.0");
-    assert_eq!(to_string(f, f32::MAX, Minus, 2, false),
-               "340282346638528859811704183484516925440.00");
-
-    let minf32 = ldexp_f32(1.0, -149);
-    assert_eq!(to_string(f, minf32, Minus,   0, false), "0");
-    assert_eq!(to_string(f, minf32, Minus,   1, false), "0.0");
-    assert_eq!(to_string(f, minf32, Minus,   2, false), "0.00");
-    assert_eq!(to_string(f, minf32, Minus,   4, false), "0.0000");
-    assert_eq!(to_string(f, minf32, Minus,   8, false), "0.00000000");
-    assert_eq!(to_string(f, minf32, Minus,  16, false), "0.0000000000000000");
-    assert_eq!(to_string(f, minf32, Minus,  32, false), "0.00000000000000000000000000000000");
-    assert_eq!(to_string(f, minf32, Minus,  64, false),
-               "0.0000000000000000000000000000000000000000000014012984643248170709");
-    assert_eq!(to_string(f, minf32, Minus, 128, false),
-               "0.0000000000000000000000000000000000000000000014012984643248170709\
-                  2372958328991613128026194187651577175706828388979108268586060149");
-    assert_eq!(to_string(f, minf32, Minus, 256, false),
-               "0.0000000000000000000000000000000000000000000014012984643248170709\
-                  2372958328991613128026194187651577175706828388979108268586060148\
-                  6638188362121582031250000000000000000000000000000000000000000000\
-                  0000000000000000000000000000000000000000000000000000000000000000");
-
-    assert_eq!(to_string(f, f64::MAX, Minus, 0, false),
-               "1797693134862315708145274237317043567980705675258449965989174768\
-                0315726078002853876058955863276687817154045895351438246423432132\
-                6889464182768467546703537516986049910576551282076245490090389328\
-                9440758685084551339423045832369032229481658085593321233482747978\
-                26204144723168738177180919299881250404026184124858368");
-    assert_eq!(to_string(f, f64::MAX, Minus, 10, false),
-               "1797693134862315708145274237317043567980705675258449965989174768\
-                0315726078002853876058955863276687817154045895351438246423432132\
-                6889464182768467546703537516986049910576551282076245490090389328\
-                9440758685084551339423045832369032229481658085593321233482747978\
-                26204144723168738177180919299881250404026184124858368.0000000000");
-
-    let minf64 = ldexp_f64(1.0, -1074);
-    assert_eq!(to_string(f, minf64, Minus, 0, false), "0");
-    assert_eq!(to_string(f, minf64, Minus, 1, false), "0.0");
-    assert_eq!(to_string(f, minf64, Minus, 10, false), "0.0000000000");
-    assert_eq!(to_string(f, minf64, Minus, 100, false),
-               "0.0000000000000000000000000000000000000000000000000000000000000000\
-                  000000000000000000000000000000000000");
-    assert_eq!(to_string(f, minf64, Minus, 1000, false),
-               "0.0000000000000000000000000000000000000000000000000000000000000000\
-                  0000000000000000000000000000000000000000000000000000000000000000\
-                  0000000000000000000000000000000000000000000000000000000000000000\
-                  0000000000000000000000000000000000000000000000000000000000000000\
-                  0000000000000000000000000000000000000000000000000000000000000000\
-                  0004940656458412465441765687928682213723650598026143247644255856\
-                  8250067550727020875186529983636163599237979656469544571773092665\
-                  6710355939796398774796010781878126300713190311404527845817167848\
-                  9821036887186360569987307230500063874091535649843873124733972731\
-                  6961514003171538539807412623856559117102665855668676818703956031\
-                  0624931945271591492455329305456544401127480129709999541931989409\
-                  0804165633245247571478690147267801593552386115501348035264934720\
-                  1937902681071074917033322268447533357208324319360923828934583680\
-                  6010601150616980975307834227731832924790498252473077637592724787\
-                  4656084778203734469699533647017972677717585125660551199131504891\
-                  1014510378627381672509558373897335989937");
-
-    // very large output
-    assert_eq!(to_string(f, 0.0,     Minus, 80000, false), format!("0.{:0>80000}", ""));
-    assert_eq!(to_string(f, 1.0e1,   Minus, 80000, false), format!("10.{:0>80000}", ""));
-    assert_eq!(to_string(f, 1.0e0,   Minus, 80000, false), format!("1.{:0>80000}", ""));
-    assert_eq!(to_string(f, 1.0e-1,  Minus, 80000, false),
-               format!("0.1000000000000000055511151231257827021181583404541015625{:0>79945}", ""));
-    assert_eq!(to_string(f, 1.0e-20, Minus, 80000, false),
-               format!("0.0000000000000000000099999999999999994515327145420957165172950370\
-                          2787392447107715776066783064379706047475337982177734375{:0>79881}", ""));
-}
-
diff --git a/src/libcoretest/num/flt2dec/strategy/dragon.rs b/src/libcoretest/num/flt2dec/strategy/dragon.rs
deleted file mode 100644 (file)
index 4edb0f3..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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::prelude::v1::*;
-use super::super::*;
-use core::num::bignum::Big32x40 as Big;
-use core::num::flt2dec::strategy::dragon::*;
-
-#[test]
-fn test_mul_pow10() {
-    let mut prevpow10 = Big::from_small(1);
-    for i in 1..340 {
-        let mut curpow10 = Big::from_small(1);
-        mul_pow10(&mut curpow10, i);
-        assert_eq!(curpow10, *prevpow10.clone().mul_small(10));
-        prevpow10 = curpow10;
-    }
-}
-
-#[test]
-fn shortest_sanity_test() {
-    f64_shortest_sanity_test(format_shortest);
-    f32_shortest_sanity_test(format_shortest);
-    more_shortest_sanity_test(format_shortest);
-}
-
-#[test]
-fn exact_sanity_test() {
-    // This test ends up running what I can only assume is some corner-ish case
-    // of the `exp2` library function, defined in whatever C runtime we're
-    // using. In VS 2013 this function apparently had a bug as this test fails
-    // when linked, but with VS 2015 the bug appears fixed as the test runs just
-    // fine.
-    //
-    // The bug seems to be a difference in return value of `exp2(-1057)`, where
-    // in VS 2013 it returns a double with the bit pattern 0x2 and in VS 2015 it
-    // returns 0x20000.
-    //
-    // For now just ignore this test entirely on MSVC as it's tested elsewhere
-    // anyway and we're not super interested in testing each platform's exp2
-    // implementation.
-    if !cfg!(target_env = "msvc") {
-        f64_exact_sanity_test(format_exact);
-    }
-    f32_exact_sanity_test(format_exact);
-}
-
-#[test]
-fn test_to_shortest_str() {
-    to_shortest_str_test(format_shortest);
-}
-
-#[test]
-fn test_to_shortest_exp_str() {
-    to_shortest_exp_str_test(format_shortest);
-}
-
-#[test]
-fn test_to_exact_exp_str() {
-    to_exact_exp_str_test(format_exact);
-}
-
-#[test]
-fn test_to_exact_fixed_str() {
-    to_exact_fixed_str_test(format_exact);
-}
-
diff --git a/src/libcoretest/num/flt2dec/strategy/grisu.rs b/src/libcoretest/num/flt2dec/strategy/grisu.rs
deleted file mode 100644 (file)
index 79e66ee..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-// 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::i16;
-use super::super::*;
-use core::num::flt2dec::strategy::grisu::*;
-
-#[test]
-fn test_cached_power() {
-    assert_eq!(CACHED_POW10.first().unwrap().1, CACHED_POW10_FIRST_E);
-    assert_eq!(CACHED_POW10.last().unwrap().1, CACHED_POW10_LAST_E);
-
-    for e in -1137..961 { // full range for f64
-        let low = ALPHA - e - 64;
-        let high = GAMMA - e - 64;
-        let (_k, cached) = cached_power(low, high);
-        assert!(low <= cached.e && cached.e <= high,
-                "cached_power({}, {}) = {:?} is incorrect", low, high, cached);
-    }
-}
-
-#[test]
-fn test_max_pow10_no_more_than() {
-    let mut prevtenk = 1;
-    for k in 1..10 {
-        let tenk = prevtenk * 10;
-        assert_eq!(max_pow10_no_more_than(tenk - 1), (k - 1, prevtenk));
-        assert_eq!(max_pow10_no_more_than(tenk), (k, tenk));
-        prevtenk = tenk;
-    }
-}
-
-
-#[test]
-fn shortest_sanity_test() {
-    f64_shortest_sanity_test(format_shortest);
-    f32_shortest_sanity_test(format_shortest);
-    more_shortest_sanity_test(format_shortest);
-}
-
-#[test]
-fn shortest_random_equivalence_test() {
-    use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
-    f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
-    f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
-}
-
-#[test] #[ignore] // it is too expensive
-fn shortest_f32_exhaustive_equivalence_test() {
-    // it is hard to directly test the optimality of the output, but we can at least test if
-    // two different algorithms agree to each other.
-    //
-    // this reports the progress and the number of f32 values returned `None`.
-    // with `--nocapture` (and plenty of time and appropriate rustc flags), this should print:
-    // `done, ignored=17643158 passed=2121451881 failed=0`.
-
-    use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
-    f32_exhaustive_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS);
-}
-
-#[test] #[ignore] // it is too expensive
-fn shortest_f64_hard_random_equivalence_test() {
-    // this again probably has to use appropriate rustc flags.
-
-    use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
-    f64_random_equivalence_test(format_shortest_opt, fallback,
-                                         MAX_SIG_DIGITS, 100_000_000);
-}
-
-#[test]
-fn exact_sanity_test() {
-    // See comments in dragon.rs's exact_sanity_test for why this test is
-    // ignored on MSVC
-    if !cfg!(target_env = "msvc") {
-        f64_exact_sanity_test(format_exact);
-    }
-    f32_exact_sanity_test(format_exact);
-}
-
-#[test]
-fn exact_f32_random_equivalence_test() {
-    use core::num::flt2dec::strategy::dragon::format_exact as fallback;
-    for k in 1..21 {
-        f32_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
-                                             |d, buf| fallback(d, buf, i16::MIN), k, 1_000);
-    }
-}
-
-#[test]
-fn exact_f64_random_equivalence_test() {
-    use core::num::flt2dec::strategy::dragon::format_exact as fallback;
-    for k in 1..21 {
-        f64_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
-                                             |d, buf| fallback(d, buf, i16::MIN), k, 1_000);
-    }
-}
-
-#[test]
-fn test_to_shortest_str() {
-    to_shortest_str_test(format_shortest);
-}
-
-#[test]
-fn test_to_shortest_exp_str() {
-    to_shortest_exp_str_test(format_shortest);
-}
-
-#[test]
-fn test_to_exact_exp_str() {
-    to_exact_exp_str_test(format_exact);
-}
-
-#[test]
-fn test_to_exact_fixed_str() {
-    to_exact_fixed_str_test(format_exact);
-}
-
diff --git a/src/libcoretest/num/i16.rs b/src/libcoretest/num/i16.rs
deleted file mode 100644 (file)
index 7435831..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-int_module!(i16, i16);
diff --git a/src/libcoretest/num/i32.rs b/src/libcoretest/num/i32.rs
deleted file mode 100644 (file)
index 3b3407e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-int_module!(i32, i32);
diff --git a/src/libcoretest/num/i64.rs b/src/libcoretest/num/i64.rs
deleted file mode 100644 (file)
index 9e1aec2..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-int_module!(i64, i64);
diff --git a/src/libcoretest/num/i8.rs b/src/libcoretest/num/i8.rs
deleted file mode 100644 (file)
index f722442..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-int_module!(i8, i8);
diff --git a/src/libcoretest/num/int_macros.rs b/src/libcoretest/num/int_macros.rs
deleted file mode 100644 (file)
index 8d79128..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-macro_rules! int_module { ($T:ident, $T_i:ident) => (
-#[cfg(test)]
-mod tests {
-    use core::$T_i::*;
-    use core::isize;
-    use core::ops::{Shl, Shr, Not, BitXor, BitAnd, BitOr};
-    use core::mem;
-
-    use num;
-
-    #[test]
-    fn test_overflows() {
-        assert!(MAX > 0);
-        assert!(MIN <= 0);
-        assert!(MIN + MAX + 1 == 0);
-    }
-
-    #[test]
-    fn test_num() {
-        num::test_num(10 as $T, 2 as $T);
-    }
-
-    #[test]
-    pub fn test_abs() {
-        assert!((1 as $T).abs() == 1 as $T);
-        assert!((0 as $T).abs() == 0 as $T);
-        assert!((-1 as $T).abs() == 1 as $T);
-    }
-
-    #[test]
-    fn test_signum() {
-        assert!((1 as $T).signum() == 1 as $T);
-        assert!((0 as $T).signum() == 0 as $T);
-        assert!((-0 as $T).signum() == 0 as $T);
-        assert!((-1 as $T).signum() == -1 as $T);
-    }
-
-    #[test]
-    fn test_is_positive() {
-        assert!((1 as $T).is_positive());
-        assert!(!(0 as $T).is_positive());
-        assert!(!(-0 as $T).is_positive());
-        assert!(!(-1 as $T).is_positive());
-    }
-
-    #[test]
-    fn test_is_negative() {
-        assert!(!(1 as $T).is_negative());
-        assert!(!(0 as $T).is_negative());
-        assert!(!(-0 as $T).is_negative());
-        assert!((-1 as $T).is_negative());
-    }
-
-    #[test]
-    fn test_bitwise_operators() {
-        assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T));
-        assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T));
-        assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T));
-        assert!(0b1110 as $T == (0b0111 as $T).shl(1));
-        assert!(0b0111 as $T == (0b1110 as $T).shr(1));
-        assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not());
-    }
-
-    const A: $T = 0b0101100;
-    const B: $T = 0b0100001;
-    const C: $T = 0b1111001;
-
-    const _0: $T = 0;
-    const _1: $T = !0;
-
-    #[test]
-    fn test_count_ones() {
-        assert!(A.count_ones() == 3);
-        assert!(B.count_ones() == 2);
-        assert!(C.count_ones() == 5);
-    }
-
-    #[test]
-    fn test_count_zeros() {
-        let bits = mem::size_of::<$T>() * 8;
-        assert!(A.count_zeros() == bits as u32 - 3);
-        assert!(B.count_zeros() == bits as u32 - 2);
-        assert!(C.count_zeros() == bits as u32 - 5);
-    }
-
-    #[test]
-    fn test_rotate() {
-        assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
-        assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
-        assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
-
-        // Rotating these should make no difference
-        //
-        // We test using 124 bits because to ensure that overlong bit shifts do
-        // not cause undefined behaviour. See #10183.
-        assert_eq!(_0.rotate_left(124), _0);
-        assert_eq!(_1.rotate_left(124), _1);
-        assert_eq!(_0.rotate_right(124), _0);
-        assert_eq!(_1.rotate_right(124), _1);
-
-        // Rotating by 0 should have no effect
-        assert_eq!(A.rotate_left(0), A);
-        assert_eq!(B.rotate_left(0), B);
-        assert_eq!(C.rotate_left(0), C);
-        // Rotating by a multiple of word size should also have no effect
-        assert_eq!(A.rotate_left(64), A);
-        assert_eq!(B.rotate_left(64), B);
-        assert_eq!(C.rotate_left(64), C);
-    }
-
-    #[test]
-    fn test_swap_bytes() {
-        assert_eq!(A.swap_bytes().swap_bytes(), A);
-        assert_eq!(B.swap_bytes().swap_bytes(), B);
-        assert_eq!(C.swap_bytes().swap_bytes(), C);
-
-        // Swapping these should make no difference
-        assert_eq!(_0.swap_bytes(), _0);
-        assert_eq!(_1.swap_bytes(), _1);
-    }
-
-    #[test]
-    fn test_le() {
-        assert_eq!($T::from_le(A.to_le()), A);
-        assert_eq!($T::from_le(B.to_le()), B);
-        assert_eq!($T::from_le(C.to_le()), C);
-        assert_eq!($T::from_le(_0), _0);
-        assert_eq!($T::from_le(_1), _1);
-        assert_eq!(_0.to_le(), _0);
-        assert_eq!(_1.to_le(), _1);
-    }
-
-    #[test]
-    fn test_be() {
-        assert_eq!($T::from_be(A.to_be()), A);
-        assert_eq!($T::from_be(B.to_be()), B);
-        assert_eq!($T::from_be(C.to_be()), C);
-        assert_eq!($T::from_be(_0), _0);
-        assert_eq!($T::from_be(_1), _1);
-        assert_eq!(_0.to_be(), _0);
-        assert_eq!(_1.to_be(), _1);
-    }
-
-    #[test]
-    fn test_signed_checked_div() {
-        assert!((10 as $T).checked_div(2) == Some(5));
-        assert!((5 as $T).checked_div(0) == None);
-        assert!(isize::MIN.checked_div(-1) == None);
-    }
-
-    #[test]
-    fn test_from_str() {
-        fn from_str<T: ::std::str::FromStr>(t: &str) -> Option<T> {
-            ::std::str::FromStr::from_str(t).ok()
-        }
-        assert_eq!(from_str::<$T>("0"), Some(0 as $T));
-        assert_eq!(from_str::<$T>("3"), Some(3 as $T));
-        assert_eq!(from_str::<$T>("10"), Some(10 as $T));
-        assert_eq!(from_str::<i32>("123456789"), Some(123456789 as i32));
-        assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
-
-        assert_eq!(from_str::<$T>("-1"), Some(-1 as $T));
-        assert_eq!(from_str::<$T>("-3"), Some(-3 as $T));
-        assert_eq!(from_str::<$T>("-10"), Some(-10 as $T));
-        assert_eq!(from_str::<i32>("-123456789"), Some(-123456789 as i32));
-        assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T));
-
-        assert_eq!(from_str::<$T>(""), None);
-        assert_eq!(from_str::<$T>(" "), None);
-        assert_eq!(from_str::<$T>("x"), None);
-    }
-
-    #[test]
-    fn test_from_str_radix() {
-        assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
-        assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
-        assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
-        assert_eq!(i32::from_str_radix("123", 16), Ok(291 as i32));
-        assert_eq!(i32::from_str_radix("ffff", 16), Ok(65535 as i32));
-        assert_eq!(i32::from_str_radix("FFFF", 16), Ok(65535 as i32));
-        assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
-        assert_eq!($T::from_str_radix("Z", 36), Ok(35 as $T));
-
-        assert_eq!($T::from_str_radix("-123", 10), Ok(-123 as $T));
-        assert_eq!($T::from_str_radix("-1001", 2), Ok(-9 as $T));
-        assert_eq!($T::from_str_radix("-123", 8), Ok(-83 as $T));
-        assert_eq!(i32::from_str_radix("-123", 16), Ok(-291 as i32));
-        assert_eq!(i32::from_str_radix("-ffff", 16), Ok(-65535 as i32));
-        assert_eq!(i32::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
-        assert_eq!($T::from_str_radix("-z", 36), Ok(-35 as $T));
-        assert_eq!($T::from_str_radix("-Z", 36), Ok(-35 as $T));
-
-        assert_eq!($T::from_str_radix("Z", 35).ok(), None::<$T>);
-        assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>);
-    }
-
-    #[test]
-    fn test_pow() {
-        let mut r = 2 as $T;
-
-        assert_eq!(r.pow(2), 4 as $T);
-        assert_eq!(r.pow(0), 1 as $T);
-        r = -2 as $T;
-        assert_eq!(r.pow(2), 4 as $T);
-        assert_eq!(r.pow(3), -8 as $T);
-    }
-}
-
-)}
diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs
deleted file mode 100644 (file)
index 51737c9..0000000
+++ /dev/null
@@ -1,400 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use core::convert::TryFrom;
-use core::cmp::PartialEq;
-use core::fmt::Debug;
-use core::marker::Copy;
-use core::ops::{Add, Sub, Mul, Div, Rem};
-use core::option::Option;
-use core::option::Option::{Some, None};
-
-#[macro_use]
-mod int_macros;
-
-mod i8;
-mod i16;
-mod i32;
-mod i64;
-
-#[macro_use]
-mod uint_macros;
-
-mod u8;
-mod u16;
-mod u32;
-mod u64;
-
-mod flt2dec;
-mod dec2flt;
-mod bignum;
-
-/// Helper function for testing numeric operations
-pub fn test_num<T>(ten: T, two: T) where
-    T: PartialEq
-     + Add<Output=T> + Sub<Output=T>
-     + Mul<Output=T> + Div<Output=T>
-     + Rem<Output=T> + Debug
-     + Copy
-{
-    assert_eq!(ten.add(two),  ten + two);
-    assert_eq!(ten.sub(two),  ten - two);
-    assert_eq!(ten.mul(two),  ten * two);
-    assert_eq!(ten.div(two),  ten / two);
-    assert_eq!(ten.rem(two),  ten % two);
-}
-
-#[test]
-fn from_str_issue7588() {
-    let u : Option<u8> = u8::from_str_radix("1000", 10).ok();
-    assert_eq!(u, None);
-    let s : Option<i16> = i16::from_str_radix("80000", 10).ok();
-    assert_eq!(s, None);
-}
-
-#[test]
-fn test_int_from_str_overflow() {
-    let mut i8_val: i8 = 127;
-    assert_eq!("127".parse::<i8>().ok(), Some(i8_val));
-    assert_eq!("128".parse::<i8>().ok(), None);
-
-    i8_val = i8_val.wrapping_add(1);
-    assert_eq!("-128".parse::<i8>().ok(), Some(i8_val));
-    assert_eq!("-129".parse::<i8>().ok(), None);
-
-    let mut i16_val: i16 = 32_767;
-    assert_eq!("32767".parse::<i16>().ok(), Some(i16_val));
-    assert_eq!("32768".parse::<i16>().ok(), None);
-
-    i16_val = i16_val.wrapping_add(1);
-    assert_eq!("-32768".parse::<i16>().ok(), Some(i16_val));
-    assert_eq!("-32769".parse::<i16>().ok(), None);
-
-    let mut i32_val: i32 = 2_147_483_647;
-    assert_eq!("2147483647".parse::<i32>().ok(), Some(i32_val));
-    assert_eq!("2147483648".parse::<i32>().ok(), None);
-
-    i32_val = i32_val.wrapping_add(1);
-    assert_eq!("-2147483648".parse::<i32>().ok(), Some(i32_val));
-    assert_eq!("-2147483649".parse::<i32>().ok(), None);
-
-    let mut i64_val: i64 = 9_223_372_036_854_775_807;
-    assert_eq!("9223372036854775807".parse::<i64>().ok(), Some(i64_val));
-    assert_eq!("9223372036854775808".parse::<i64>().ok(), None);
-
-    i64_val = i64_val.wrapping_add(1);
-    assert_eq!("-9223372036854775808".parse::<i64>().ok(), Some(i64_val));
-    assert_eq!("-9223372036854775809".parse::<i64>().ok(), None);
-}
-
-#[test]
-fn test_leading_plus() {
-    assert_eq!("+127".parse::<u8>().ok(), Some(127));
-    assert_eq!("+9223372036854775807".parse::<i64>().ok(), Some(9223372036854775807));
-}
-
-#[test]
-fn test_invalid() {
-    assert_eq!("--129".parse::<i8>().ok(), None);
-    assert_eq!("++129".parse::<i8>().ok(), None);
-    assert_eq!("Съешь".parse::<u8>().ok(), None);
-}
-
-#[test]
-fn test_empty() {
-    assert_eq!("-".parse::<i8>().ok(), None);
-    assert_eq!("+".parse::<i8>().ok(), None);
-    assert_eq!("".parse::<u8>().ok(), None);
-}
-
-macro_rules! test_impl_from {
-    ($fn_name: ident, $Small: ty, $Large: ty) => {
-        #[test]
-        fn $fn_name() {
-            let small_max = <$Small>::max_value();
-            let small_min = <$Small>::min_value();
-            let large_max: $Large = small_max.into();
-            let large_min: $Large = small_min.into();
-            assert_eq!(large_max as $Small, small_max);
-            assert_eq!(large_min as $Small, small_min);
-        }
-    }
-}
-
-// Unsigned -> Unsigned
-test_impl_from! { test_u8u16, u8, u16 }
-test_impl_from! { test_u8u32, u8, u32 }
-test_impl_from! { test_u8u64, u8, u64 }
-test_impl_from! { test_u8usize, u8, usize }
-test_impl_from! { test_u16u32, u16, u32 }
-test_impl_from! { test_u16u64, u16, u64 }
-test_impl_from! { test_u32u64, u32, u64 }
-
-// Signed -> Signed
-test_impl_from! { test_i8i16, i8, i16 }
-test_impl_from! { test_i8i32, i8, i32 }
-test_impl_from! { test_i8i64, i8, i64 }
-test_impl_from! { test_i8isize, i8, isize }
-test_impl_from! { test_i16i32, i16, i32 }
-test_impl_from! { test_i16i64, i16, i64 }
-test_impl_from! { test_i32i64, i32, i64 }
-
-// Unsigned -> Signed
-test_impl_from! { test_u8i16, u8, i16 }
-test_impl_from! { test_u8i32, u8, i32 }
-test_impl_from! { test_u8i64, u8, i64 }
-test_impl_from! { test_u16i32, u16, i32 }
-test_impl_from! { test_u16i64, u16, i64 }
-test_impl_from! { test_u32i64, u32, i64 }
-
-// Signed -> Float
-test_impl_from! { test_i8f32, i8, f32 }
-test_impl_from! { test_i8f64, i8, f64 }
-test_impl_from! { test_i16f32, i16, f32 }
-test_impl_from! { test_i16f64, i16, f64 }
-test_impl_from! { test_i32f64, i32, f64 }
-
-// Unsigned -> Float
-test_impl_from! { test_u8f32, u8, f32 }
-test_impl_from! { test_u8f64, u8, f64 }
-test_impl_from! { test_u16f32, u16, f32 }
-test_impl_from! { test_u16f64, u16, f64 }
-test_impl_from! { test_u32f64, u32, f64 }
-
-// Float -> Float
-#[test]
-fn test_f32f64() {
-    use core::f32;
-
-    let max: f64 = f32::MAX.into();
-    assert_eq!(max as f32, f32::MAX);
-    assert!(max.is_normal());
-
-    let min: f64 = f32::MIN.into();
-    assert_eq!(min as f32, f32::MIN);
-    assert!(min.is_normal());
-
-    let min_positive: f64 = f32::MIN_POSITIVE.into();
-    assert_eq!(min_positive as f32, f32::MIN_POSITIVE);
-    assert!(min_positive.is_normal());
-
-    let epsilon: f64 = f32::EPSILON.into();
-    assert_eq!(epsilon as f32, f32::EPSILON);
-    assert!(epsilon.is_normal());
-
-    let zero: f64 = (0.0f32).into();
-    assert_eq!(zero as f32, 0.0f32);
-    assert!(zero.is_sign_positive());
-
-    let neg_zero: f64 = (-0.0f32).into();
-    assert_eq!(neg_zero as f32, -0.0f32);
-    assert!(neg_zero.is_sign_negative());
-
-    let infinity: f64 = f32::INFINITY.into();
-    assert_eq!(infinity as f32, f32::INFINITY);
-    assert!(infinity.is_infinite());
-    assert!(infinity.is_sign_positive());
-
-    let neg_infinity: f64 = f32::NEG_INFINITY.into();
-    assert_eq!(neg_infinity as f32, f32::NEG_INFINITY);
-    assert!(neg_infinity.is_infinite());
-    assert!(neg_infinity.is_sign_negative());
-
-    let nan: f64 = f32::NAN.into();
-    assert!(nan.is_nan());
-}
-
-macro_rules! test_impl_try_from_always_ok {
-    ($fn_name:ident, $source:ty, $target: ty) => {
-        #[test]
-        fn $fn_name() {
-            let max = <$source>::max_value();
-            let min = <$source>::min_value();
-            let zero: $source = 0;
-            assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(),
-                       max as $target);
-            assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(),
-                       min as $target);
-            assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
-                       zero as $target);
-        }
-    }
-}
-
-test_impl_try_from_always_ok! { test_try_u8u8, u8, u8 }
-test_impl_try_from_always_ok! { test_try_u8u16, u8, u16 }
-test_impl_try_from_always_ok! { test_try_u8u32, u8, u32 }
-test_impl_try_from_always_ok! { test_try_u8u64, u8, u64 }
-test_impl_try_from_always_ok! { test_try_u8i16, u8, i16 }
-test_impl_try_from_always_ok! { test_try_u8i32, u8, i32 }
-test_impl_try_from_always_ok! { test_try_u8i64, u8, i64 }
-
-test_impl_try_from_always_ok! { test_try_u16u16, u16, u16 }
-test_impl_try_from_always_ok! { test_try_u16u32, u16, u32 }
-test_impl_try_from_always_ok! { test_try_u16u64, u16, u64 }
-test_impl_try_from_always_ok! { test_try_u16i32, u16, i32 }
-test_impl_try_from_always_ok! { test_try_u16i64, u16, i64 }
-
-test_impl_try_from_always_ok! { test_try_u32u32, u32, u32 }
-test_impl_try_from_always_ok! { test_try_u32u64, u32, u64 }
-test_impl_try_from_always_ok! { test_try_u32i64, u32, i64 }
-
-test_impl_try_from_always_ok! { test_try_u64u64, u64, u64 }
-
-test_impl_try_from_always_ok! { test_try_i8i8, i8, i8 }
-test_impl_try_from_always_ok! { test_try_i8i16, i8, i16 }
-test_impl_try_from_always_ok! { test_try_i8i32, i8, i32 }
-test_impl_try_from_always_ok! { test_try_i8i64, i8, i64 }
-
-test_impl_try_from_always_ok! { test_try_i16i16, i16, i16 }
-test_impl_try_from_always_ok! { test_try_i16i32, i16, i32 }
-test_impl_try_from_always_ok! { test_try_i16i64, i16, i64 }
-
-test_impl_try_from_always_ok! { test_try_i32i32, i32, i32 }
-test_impl_try_from_always_ok! { test_try_i32i64, i32, i64 }
-
-test_impl_try_from_always_ok! { test_try_i64i64, i64, i64 }
-
-macro_rules! test_impl_try_from_signed_to_unsigned_upper_ok {
-    ($fn_name:ident, $source:ty, $target:ty) => {
-        #[test]
-        fn $fn_name() {
-            let max = <$source>::max_value();
-            let min = <$source>::min_value();
-            let zero: $source = 0;
-            let neg_one: $source = -1;
-            assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(),
-                       max as $target);
-            assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
-            assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
-                       zero as $target);
-            assert!(<$target as TryFrom<$source>>::try_from(neg_one).is_err());
-        }
-    }
-}
-
-test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u8, i8, u8 }
-test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u16, i8, u16 }
-test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u32, i8, u32 }
-test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u64, i8, u64 }
-
-test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u16, i16, u16 }
-test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u32, i16, u32 }
-test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u64, i16, u64 }
-
-test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u32, i32, u32 }
-test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u64, i32, u64 }
-
-test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64u64, i64, u64 }
-
-macro_rules! test_impl_try_from_unsigned_to_signed_upper_err {
-    ($fn_name:ident, $source:ty, $target:ty) => {
-        #[test]
-        fn $fn_name() {
-            let max = <$source>::max_value();
-            let min = <$source>::min_value();
-            let zero: $source = 0;
-            assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
-            assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(),
-                       min as $target);
-            assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
-                       zero as $target);
-        }
-    }
-}
-
-test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u8i8, u8, i8 }
-
-test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16i8, u16, i8 }
-test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16i16, u16, i16 }
-
-test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i8, u32, i8 }
-test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i16, u32, i16 }
-test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i32, u32, i32 }
-
-test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i8, u64, i8 }
-test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i16, u64, i16 }
-test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i32, u64, i32 }
-test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i64, u64, i64 }
-
-macro_rules! test_impl_try_from_same_sign_err {
-    ($fn_name:ident, $source:ty, $target:ty) => {
-        #[test]
-        fn $fn_name() {
-            let max = <$source>::max_value();
-            let min = <$source>::min_value();
-            let zero: $source = 0;
-            let t_max = <$target>::max_value();
-            let t_min = <$target>::min_value();
-            assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
-            if min != 0 {
-                assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
-            }
-            assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
-                       zero as $target);
-            assert_eq!(<$target as TryFrom<$source>>::try_from(t_max as $source)
-                            .unwrap(),
-                       t_max as $target);
-            assert_eq!(<$target as TryFrom<$source>>::try_from(t_min as $source)
-                            .unwrap(),
-                       t_min as $target);
-        }
-    }
-}
-
-test_impl_try_from_same_sign_err! { test_try_u16u8, u16, u8 }
-
-test_impl_try_from_same_sign_err! { test_try_u32u8, u32, u8 }
-test_impl_try_from_same_sign_err! { test_try_u32u16, u32, u16 }
-
-test_impl_try_from_same_sign_err! { test_try_u64u8, u64, u8 }
-test_impl_try_from_same_sign_err! { test_try_u64u16, u64, u16 }
-test_impl_try_from_same_sign_err! { test_try_u64u32, u64, u32 }
-
-test_impl_try_from_same_sign_err! { test_try_i16i8, i16, i8 }
-
-test_impl_try_from_same_sign_err! { test_try_i32i8, i32, i8 }
-test_impl_try_from_same_sign_err! { test_try_i32i16, i32, i16 }
-
-test_impl_try_from_same_sign_err! { test_try_i64i8, i64, i8 }
-test_impl_try_from_same_sign_err! { test_try_i64i16, i64, i16 }
-test_impl_try_from_same_sign_err! { test_try_i64i32, i64, i32 }
-
-macro_rules! test_impl_try_from_signed_to_unsigned_err {
-    ($fn_name:ident, $source:ty, $target:ty) => {
-        #[test]
-        fn $fn_name() {
-            let max = <$source>::max_value();
-            let min = <$source>::min_value();
-            let zero: $source = 0;
-            let t_max = <$target>::max_value();
-            let t_min = <$target>::min_value();
-            assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
-            assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
-            assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
-                       zero as $target);
-            assert_eq!(<$target as TryFrom<$source>>::try_from(t_max as $source)
-                            .unwrap(),
-                       t_max as $target);
-            assert_eq!(<$target as TryFrom<$source>>::try_from(t_min as $source)
-                            .unwrap(),
-                       t_min as $target);
-        }
-    }
-}
-
-test_impl_try_from_signed_to_unsigned_err! { test_try_i16u8, i16, u8 }
-
-test_impl_try_from_signed_to_unsigned_err! { test_try_i32u8, i32, u8 }
-test_impl_try_from_signed_to_unsigned_err! { test_try_i32u16, i32, u16 }
-
-test_impl_try_from_signed_to_unsigned_err! { test_try_i64u8, i64, u8 }
-test_impl_try_from_signed_to_unsigned_err! { test_try_i64u16, i64, u16 }
-test_impl_try_from_signed_to_unsigned_err! { test_try_i64u32, i64, u32 }
diff --git a/src/libcoretest/num/u16.rs b/src/libcoretest/num/u16.rs
deleted file mode 100644 (file)
index 8455207..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-uint_module!(u16, u16);
diff --git a/src/libcoretest/num/u32.rs b/src/libcoretest/num/u32.rs
deleted file mode 100644 (file)
index b44e60f..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-uint_module!(u32, u32);
diff --git a/src/libcoretest/num/u64.rs b/src/libcoretest/num/u64.rs
deleted file mode 100644 (file)
index ffcd101..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-uint_module!(u64, u64);
diff --git a/src/libcoretest/num/u8.rs b/src/libcoretest/num/u8.rs
deleted file mode 100644 (file)
index 4ee14e2..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-uint_module!(u8, u8);
diff --git a/src/libcoretest/num/uint_macros.rs b/src/libcoretest/num/uint_macros.rs
deleted file mode 100644 (file)
index daa1cc3..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-macro_rules! uint_module { ($T:ident, $T_i:ident) => (
-#[cfg(test)]
-mod tests {
-    use core::$T_i::*;
-    use num;
-    use core::ops::{BitOr, BitAnd, BitXor, Shl, Shr, Not};
-    use std::str::FromStr;
-    use std::mem;
-
-    #[test]
-    fn test_overflows() {
-        assert!(MAX > 0);
-        assert!(MIN <= 0);
-        assert!((MIN + MAX).wrapping_add(1) == 0);
-    }
-
-    #[test]
-    fn test_num() {
-        num::test_num(10 as $T, 2 as $T);
-    }
-
-    #[test]
-    fn test_bitwise_operators() {
-        assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T));
-        assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T));
-        assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T));
-        assert!(0b1110 as $T == (0b0111 as $T).shl(1));
-        assert!(0b0111 as $T == (0b1110 as $T).shr(1));
-        assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
-    }
-
-    const A: $T = 0b0101100;
-    const B: $T = 0b0100001;
-    const C: $T = 0b1111001;
-
-    const _0: $T = 0;
-    const _1: $T = !0;
-
-    #[test]
-    fn test_count_ones() {
-        assert!(A.count_ones() == 3);
-        assert!(B.count_ones() == 2);
-        assert!(C.count_ones() == 5);
-    }
-
-    #[test]
-    fn test_count_zeros() {
-        let bits = mem::size_of::<$T>() * 8;
-        assert!(A.count_zeros() == bits as u32 - 3);
-        assert!(B.count_zeros() == bits as u32 - 2);
-        assert!(C.count_zeros() == bits as u32 - 5);
-    }
-
-    #[test]
-    fn test_rotate() {
-        assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
-        assert_eq!(B.rotate_left(3).rotate_left(2).rotate_right(5), B);
-        assert_eq!(C.rotate_left(6).rotate_right(2).rotate_right(4), C);
-
-        // Rotating these should make no difference
-        //
-        // We test using 124 bits because to ensure that overlong bit shifts do
-        // not cause undefined behaviour. See #10183.
-        assert_eq!(_0.rotate_left(124), _0);
-        assert_eq!(_1.rotate_left(124), _1);
-        assert_eq!(_0.rotate_right(124), _0);
-        assert_eq!(_1.rotate_right(124), _1);
-
-        // Rotating by 0 should have no effect
-        assert_eq!(A.rotate_left(0), A);
-        assert_eq!(B.rotate_left(0), B);
-        assert_eq!(C.rotate_left(0), C);
-        // Rotating by a multiple of word size should also have no effect
-        assert_eq!(A.rotate_left(64), A);
-        assert_eq!(B.rotate_left(64), B);
-        assert_eq!(C.rotate_left(64), C);
-    }
-
-    #[test]
-    fn test_swap_bytes() {
-        assert_eq!(A.swap_bytes().swap_bytes(), A);
-        assert_eq!(B.swap_bytes().swap_bytes(), B);
-        assert_eq!(C.swap_bytes().swap_bytes(), C);
-
-        // Swapping these should make no difference
-        assert_eq!(_0.swap_bytes(), _0);
-        assert_eq!(_1.swap_bytes(), _1);
-    }
-
-    #[test]
-    fn test_le() {
-        assert_eq!($T::from_le(A.to_le()), A);
-        assert_eq!($T::from_le(B.to_le()), B);
-        assert_eq!($T::from_le(C.to_le()), C);
-        assert_eq!($T::from_le(_0), _0);
-        assert_eq!($T::from_le(_1), _1);
-        assert_eq!(_0.to_le(), _0);
-        assert_eq!(_1.to_le(), _1);
-    }
-
-    #[test]
-    fn test_be() {
-        assert_eq!($T::from_be(A.to_be()), A);
-        assert_eq!($T::from_be(B.to_be()), B);
-        assert_eq!($T::from_be(C.to_be()), C);
-        assert_eq!($T::from_be(_0), _0);
-        assert_eq!($T::from_be(_1), _1);
-        assert_eq!(_0.to_be(), _0);
-        assert_eq!(_1.to_be(), _1);
-    }
-
-    #[test]
-    fn test_unsigned_checked_div() {
-        assert!((10 as $T).checked_div(2) == Some(5));
-        assert!((5 as $T).checked_div(0) == None);
-    }
-
-    fn from_str<T: FromStr>(t: &str) -> Option<T> {
-        FromStr::from_str(t).ok()
-    }
-
-    #[test]
-    pub fn test_from_str() {
-        assert_eq!(from_str::<$T>("0"), Some(0 as $T));
-        assert_eq!(from_str::<$T>("3"), Some(3 as $T));
-        assert_eq!(from_str::<$T>("10"), Some(10 as $T));
-        assert_eq!(from_str::<u32>("123456789"), Some(123456789 as u32));
-        assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
-
-        assert_eq!(from_str::<$T>(""), None);
-        assert_eq!(from_str::<$T>(" "), None);
-        assert_eq!(from_str::<$T>("x"), None);
-    }
-
-    #[test]
-    pub fn test_parse_bytes() {
-        assert_eq!($T::from_str_radix("123", 10), Ok(123 as $T));
-        assert_eq!($T::from_str_radix("1001", 2), Ok(9 as $T));
-        assert_eq!($T::from_str_radix("123", 8), Ok(83 as $T));
-        assert_eq!(u16::from_str_radix("123", 16), Ok(291 as u16));
-        assert_eq!(u16::from_str_radix("ffff", 16), Ok(65535 as u16));
-        assert_eq!($T::from_str_radix("z", 36), Ok(35 as $T));
-
-        assert_eq!($T::from_str_radix("Z", 10).ok(), None::<$T>);
-        assert_eq!($T::from_str_radix("_", 2).ok(), None::<$T>);
-    }
-}
-)}
diff --git a/src/libcoretest/ops.rs b/src/libcoretest/ops.rs
deleted file mode 100644 (file)
index 1c6c13b..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use core::ops::{Range, RangeFull, RangeFrom, RangeTo};
-
-// Test the Range structs without the syntactic sugar.
-
-#[test]
-fn test_range() {
-    let r = Range { start: 2, end: 10 };
-    let mut count = 0;
-    for (i, ri) in r.enumerate() {
-        assert!(ri == i + 2);
-        assert!(ri >= 2 && ri < 10);
-        count += 1;
-    }
-    assert!(count == 8);
-}
-
-#[test]
-fn test_range_from() {
-    let r = RangeFrom { start: 2 };
-    let mut count = 0;
-    for (i, ri) in r.take(10).enumerate() {
-        assert!(ri == i + 2);
-        assert!(ri >= 2 && ri < 12);
-        count += 1;
-    }
-    assert!(count == 10);
-}
-
-#[test]
-fn test_range_to() {
-    // Not much to test.
-    let _ = RangeTo { end: 42 };
-}
-
-#[test]
-fn test_full_range() {
-    // Not much to test.
-    let _ = RangeFull;
-}
diff --git a/src/libcoretest/option.rs b/src/libcoretest/option.rs
deleted file mode 100644 (file)
index 51b0655..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use core::option::*;
-use core::mem;
-use core::clone::Clone;
-
-#[test]
-fn test_get_ptr() {
-    unsafe {
-        let x: Box<_> = box 0;
-        let addr_x: *const isize = mem::transmute(&*x);
-        let opt = Some(x);
-        let y = opt.unwrap();
-        let addr_y: *const isize = mem::transmute(&*y);
-        assert_eq!(addr_x, addr_y);
-    }
-}
-
-#[test]
-fn test_get_str() {
-    let x = "test".to_string();
-    let addr_x = x.as_ptr();
-    let opt = Some(x);
-    let y = opt.unwrap();
-    let addr_y = y.as_ptr();
-    assert_eq!(addr_x, addr_y);
-}
-
-#[test]
-fn test_get_resource() {
-    use std::rc::Rc;
-    use core::cell::RefCell;
-
-    struct R {
-       i: Rc<RefCell<isize>>,
-    }
-
-        impl Drop for R {
-       fn drop(&mut self) {
-            let ii = &*self.i;
-            let i = *ii.borrow();
-            *ii.borrow_mut() = i + 1;
-        }
-    }
-
-    fn r(i: Rc<RefCell<isize>>) -> R {
-        R {
-            i: i
-        }
-    }
-
-    let i = Rc::new(RefCell::new(0));
-    {
-        let x = r(i.clone());
-        let opt = Some(x);
-        let _y = opt.unwrap();
-    }
-    assert_eq!(*i.borrow(), 1);
-}
-
-#[test]
-fn test_option_dance() {
-    let x = Some(());
-    let mut y = Some(5);
-    let mut y2 = 0;
-    for _x in x {
-        y2 = y.take().unwrap();
-    }
-    assert_eq!(y2, 5);
-    assert!(y.is_none());
-}
-
-#[test] #[should_panic]
-fn test_option_too_much_dance() {
-    struct A;
-    let mut y = Some(A);
-    let _y2 = y.take().unwrap();
-    let _y3 = y.take().unwrap();
-}
-
-#[test]
-fn test_and() {
-    let x: Option<isize> = Some(1);
-    assert_eq!(x.and(Some(2)), Some(2));
-    assert_eq!(x.and(None::<isize>), None);
-
-    let x: Option<isize> = None;
-    assert_eq!(x.and(Some(2)), None);
-    assert_eq!(x.and(None::<isize>), None);
-}
-
-#[test]
-fn test_and_then() {
-    let x: Option<isize> = Some(1);
-    assert_eq!(x.and_then(|x| Some(x + 1)), Some(2));
-    assert_eq!(x.and_then(|_| None::<isize>), None);
-
-    let x: Option<isize> = None;
-    assert_eq!(x.and_then(|x| Some(x + 1)), None);
-    assert_eq!(x.and_then(|_| None::<isize>), None);
-}
-
-#[test]
-fn test_or() {
-    let x: Option<isize> = Some(1);
-    assert_eq!(x.or(Some(2)), Some(1));
-    assert_eq!(x.or(None), Some(1));
-
-    let x: Option<isize> = None;
-    assert_eq!(x.or(Some(2)), Some(2));
-    assert_eq!(x.or(None), None);
-}
-
-#[test]
-fn test_or_else() {
-    let x: Option<isize> = Some(1);
-    assert_eq!(x.or_else(|| Some(2)), Some(1));
-    assert_eq!(x.or_else(|| None), Some(1));
-
-    let x: Option<isize> = None;
-    assert_eq!(x.or_else(|| Some(2)), Some(2));
-    assert_eq!(x.or_else(|| None), None);
-}
-
-#[test]
-fn test_unwrap() {
-    assert_eq!(Some(1).unwrap(), 1);
-    let s = Some("hello".to_string()).unwrap();
-    assert_eq!(s, "hello");
-}
-
-#[test]
-#[should_panic]
-fn test_unwrap_panic1() {
-    let x: Option<isize> = None;
-    x.unwrap();
-}
-
-#[test]
-#[should_panic]
-fn test_unwrap_panic2() {
-    let x: Option<String> = None;
-    x.unwrap();
-}
-
-#[test]
-fn test_unwrap_or() {
-    let x: Option<isize> = Some(1);
-    assert_eq!(x.unwrap_or(2), 1);
-
-    let x: Option<isize> = None;
-    assert_eq!(x.unwrap_or(2), 2);
-}
-
-#[test]
-fn test_unwrap_or_else() {
-    let x: Option<isize> = Some(1);
-    assert_eq!(x.unwrap_or_else(|| 2), 1);
-
-    let x: Option<isize> = None;
-    assert_eq!(x.unwrap_or_else(|| 2), 2);
-}
-
-#[test]
-fn test_iter() {
-    let val = 5;
-
-    let x = Some(val);
-    let mut it = x.iter();
-
-    assert_eq!(it.size_hint(), (1, Some(1)));
-    assert_eq!(it.next(), Some(&val));
-    assert_eq!(it.size_hint(), (0, Some(0)));
-    assert!(it.next().is_none());
-
-    let mut it = (&x).into_iter();
-    assert_eq!(it.next(), Some(&val));
-}
-
-#[test]
-fn test_mut_iter() {
-    let mut val = 5;
-    let new_val = 11;
-
-    let mut x = Some(val);
-    {
-        let mut it = x.iter_mut();
-
-        assert_eq!(it.size_hint(), (1, Some(1)));
-
-        match it.next() {
-            Some(interior) => {
-                assert_eq!(*interior, val);
-                *interior = new_val;
-            }
-            None => assert!(false),
-        }
-
-        assert_eq!(it.size_hint(), (0, Some(0)));
-        assert!(it.next().is_none());
-    }
-    assert_eq!(x, Some(new_val));
-
-    let mut y = Some(val);
-    let mut it = (&mut y).into_iter();
-    assert_eq!(it.next(), Some(&mut val));
-}
-
-#[test]
-fn test_ord() {
-    let small = Some(1.0f64);
-    let big = Some(5.0f64);
-    let nan = Some(0.0f64/0.0);
-    assert!(!(nan < big));
-    assert!(!(nan > big));
-    assert!(small < big);
-    assert!(None < big);
-    assert!(big > None);
-}
-
-#[test]
-fn test_collect() {
-    let v: Option<Vec<isize>> = (0..0).map(|_| Some(0)).collect();
-    assert!(v == Some(vec![]));
-
-    let v: Option<Vec<isize>> = (0..3).map(|x| Some(x)).collect();
-    assert!(v == Some(vec![0, 1, 2]));
-
-    let v: Option<Vec<isize>> = (0..3).map(|x| {
-        if x > 1 { None } else { Some(x) }
-    }).collect();
-    assert!(v == None);
-
-    // test that it does not take more elements than it needs
-    let mut functions: [Box<Fn() -> Option<()>>; 3] =
-        [box || Some(()), box || None, box || panic!()];
-
-    let v: Option<Vec<()>> = functions.iter_mut().map(|f| (*f)()).collect();
-
-    assert!(v == None);
-}
-
-
-#[test]
-fn test_cloned() {
-    let val = 1;
-    let val_ref = &val;
-    let opt_none: Option<&'static u32> = None;
-    let opt_ref = Some(&val);
-    let opt_ref_ref = Some(&val_ref);
-
-    // None works
-    assert_eq!(opt_none.clone(), None);
-    assert_eq!(opt_none.cloned(), None);
-
-    // Immutable ref works
-    assert_eq!(opt_ref.clone(), Some(&val));
-    assert_eq!(opt_ref.cloned(), Some(1));
-
-    // Double Immutable ref works
-    assert_eq!(opt_ref_ref.clone(), Some(&val_ref));
-    assert_eq!(opt_ref_ref.clone().cloned(), Some(&val));
-    assert_eq!(opt_ref_ref.cloned().cloned(), Some(1));
-}
diff --git a/src/libcoretest/ptr.rs b/src/libcoretest/ptr.rs
deleted file mode 100644 (file)
index 7f6f472..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use core::ptr::*;
-use core::cell::RefCell;
-
-#[test]
-fn test() {
-    unsafe {
-        struct Pair {
-            fst: isize,
-            snd: isize
-        };
-        let mut p = Pair {fst: 10, snd: 20};
-        let pptr: *mut Pair = &mut p;
-        let iptr: *mut isize = pptr as *mut isize;
-        assert_eq!(*iptr, 10);
-        *iptr = 30;
-        assert_eq!(*iptr, 30);
-        assert_eq!(p.fst, 30);
-
-        *pptr = Pair {fst: 50, snd: 60};
-        assert_eq!(*iptr, 50);
-        assert_eq!(p.fst, 50);
-        assert_eq!(p.snd, 60);
-
-        let v0 = vec![32000u16, 32001u16, 32002u16];
-        let mut v1 = vec![0u16, 0u16, 0u16];
-
-        copy(v0.as_ptr().offset(1), v1.as_mut_ptr().offset(1), 1);
-        assert!((v1[0] == 0u16 &&
-                 v1[1] == 32001u16 &&
-                 v1[2] == 0u16));
-        copy(v0.as_ptr().offset(2), v1.as_mut_ptr(), 1);
-        assert!((v1[0] == 32002u16 &&
-                 v1[1] == 32001u16 &&
-                 v1[2] == 0u16));
-        copy(v0.as_ptr(), v1.as_mut_ptr().offset(2), 1);
-        assert!((v1[0] == 32002u16 &&
-                 v1[1] == 32001u16 &&
-                 v1[2] == 32000u16));
-    }
-}
-
-#[test]
-fn test_is_null() {
-    let p: *const isize = null();
-    assert!(p.is_null());
-
-    let q = unsafe { p.offset(1) };
-    assert!(!q.is_null());
-
-    let mp: *mut isize = null_mut();
-    assert!(mp.is_null());
-
-    let mq = unsafe { mp.offset(1) };
-    assert!(!mq.is_null());
-}
-
-#[test]
-fn test_as_ref() {
-    unsafe {
-        let p: *const isize = null();
-        assert_eq!(p.as_ref(), None);
-
-        let q: *const isize = &2;
-        assert_eq!(q.as_ref().unwrap(), &2);
-
-        let p: *mut isize = null_mut();
-        assert_eq!(p.as_ref(), None);
-
-        let q: *mut isize = &mut 2;
-        assert_eq!(q.as_ref().unwrap(), &2);
-
-        // Lifetime inference
-        let u = 2isize;
-        {
-            let p = &u as *const isize;
-            assert_eq!(p.as_ref().unwrap(), &2);
-        }
-    }
-}
-
-#[test]
-fn test_as_mut() {
-    unsafe {
-        let p: *mut isize = null_mut();
-        assert!(p.as_mut() == None);
-
-        let q: *mut isize = &mut 2;
-        assert!(q.as_mut().unwrap() == &mut 2);
-
-        // Lifetime inference
-        let mut u = 2isize;
-        {
-            let p = &mut u as *mut isize;
-            assert!(p.as_mut().unwrap() == &mut 2);
-        }
-    }
-}
-
-#[test]
-fn test_ptr_addition() {
-    unsafe {
-        let xs = vec![5; 16];
-        let mut ptr = xs.as_ptr();
-        let end = ptr.offset(16);
-
-        while ptr < end {
-            assert_eq!(*ptr, 5);
-            ptr = ptr.offset(1);
-        }
-
-        let mut xs_mut = xs;
-        let mut m_ptr = xs_mut.as_mut_ptr();
-        let m_end = m_ptr.offset(16);
-
-        while m_ptr < m_end {
-            *m_ptr += 5;
-            m_ptr = m_ptr.offset(1);
-        }
-
-        assert!(xs_mut == vec![10; 16]);
-    }
-}
-
-#[test]
-fn test_ptr_subtraction() {
-    unsafe {
-        let xs = vec![0,1,2,3,4,5,6,7,8,9];
-        let mut idx = 9;
-        let ptr = xs.as_ptr();
-
-        while idx >= 0 {
-            assert_eq!(*(ptr.offset(idx as isize)), idx as isize);
-            idx = idx - 1;
-        }
-
-        let mut xs_mut = xs;
-        let m_start = xs_mut.as_mut_ptr();
-        let mut m_ptr = m_start.offset(9);
-
-        while m_ptr >= m_start {
-            *m_ptr += *m_ptr;
-            m_ptr = m_ptr.offset(-1);
-        }
-
-        assert_eq!(xs_mut, [0,2,4,6,8,10,12,14,16,18]);
-    }
-}
-
-#[test]
-fn test_set_memory() {
-    let mut xs = [0u8; 20];
-    let ptr = xs.as_mut_ptr();
-    unsafe { write_bytes(ptr, 5u8, xs.len()); }
-    assert!(xs == [5u8; 20]);
-}
-
-#[test]
-fn test_unsized_unique() {
-    let xs: &mut [i32] = &mut [1, 2, 3];
-    let ptr = unsafe { Unique::new(xs as *mut [i32]) };
-    let ys = unsafe { &mut **ptr };
-    let zs: &mut [i32] = &mut [1, 2, 3];
-    assert!(ys == zs);
-}
-
-#[test]
-#[allow(warnings)]
-// Have a symbol for the test below. It doesn’t need to be an actual variadic function, match the
-// ABI, or even point to an actual executable code, because the function itself is never invoked.
-#[no_mangle]
-pub fn test_variadic_fnptr() {
-    use core::hash::{Hash, SipHasher};
-    extern {
-        fn test_variadic_fnptr(_: u64, ...) -> f64;
-    }
-    let p: unsafe extern fn(u64, ...) -> f64 = test_variadic_fnptr;
-    let q = p.clone();
-    assert_eq!(p, q);
-    assert!(!(p < q));
-    let mut s = SipHasher::new();
-    assert_eq!(p.hash(&mut s), q.hash(&mut s));
-}
-
-#[test]
-fn write_unaligned_drop() {
-    thread_local! {
-        static DROPS: RefCell<Vec<u32>> = RefCell::new(Vec::new());
-    }
-
-    struct Dropper(u32);
-
-    impl Drop for Dropper {
-        fn drop(&mut self) {
-            DROPS.with(|d| d.borrow_mut().push(self.0));
-        }
-    }
-
-    {
-        let c = Dropper(0);
-        let mut t = Dropper(1);
-        unsafe { write_unaligned(&mut t, c); }
-    }
-    DROPS.with(|d| assert_eq!(*d.borrow(), [0]));
-}
diff --git a/src/libcoretest/result.rs b/src/libcoretest/result.rs
deleted file mode 100644 (file)
index 4c5f19d..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn op1() -> Result<isize, &'static str> { Ok(666) }
-fn op2() -> Result<isize, &'static str> { Err("sadface") }
-
-#[test]
-fn test_and() {
-    assert_eq!(op1().and(Ok(667)).unwrap(), 667);
-    assert_eq!(op1().and(Err::<i32, &'static str>("bad")).unwrap_err(),
-               "bad");
-
-    assert_eq!(op2().and(Ok(667)).unwrap_err(), "sadface");
-    assert_eq!(op2().and(Err::<i32,&'static str>("bad")).unwrap_err(),
-               "sadface");
-}
-
-#[test]
-fn test_and_then() {
-    assert_eq!(op1().and_then(|i| Ok::<isize, &'static str>(i + 1)).unwrap(), 667);
-    assert_eq!(op1().and_then(|_| Err::<isize, &'static str>("bad")).unwrap_err(),
-               "bad");
-
-    assert_eq!(op2().and_then(|i| Ok::<isize, &'static str>(i + 1)).unwrap_err(),
-               "sadface");
-    assert_eq!(op2().and_then(|_| Err::<isize, &'static str>("bad")).unwrap_err(),
-               "sadface");
-}
-
-#[test]
-fn test_or() {
-    assert_eq!(op1().or(Ok::<_, &'static str>(667)).unwrap(), 666);
-    assert_eq!(op1().or(Err("bad")).unwrap(), 666);
-
-    assert_eq!(op2().or(Ok::<_, &'static str>(667)).unwrap(), 667);
-    assert_eq!(op2().or(Err("bad")).unwrap_err(), "bad");
-}
-
-#[test]
-fn test_or_else() {
-    assert_eq!(op1().or_else(|_| Ok::<isize, &'static str>(667)).unwrap(), 666);
-    assert_eq!(op1().or_else(|e| Err::<isize, &'static str>(e)).unwrap(), 666);
-
-    assert_eq!(op2().or_else(|_| Ok::<isize, &'static str>(667)).unwrap(), 667);
-    assert_eq!(op2().or_else(|e| Err::<isize, &'static str>(e)).unwrap_err(),
-               "sadface");
-}
-
-#[test]
-fn test_impl_map() {
-    assert!(Ok::<isize, isize>(1).map(|x| x + 1) == Ok(2));
-    assert!(Err::<isize, isize>(1).map(|x| x + 1) == Err(1));
-}
-
-#[test]
-fn test_impl_map_err() {
-    assert!(Ok::<isize, isize>(1).map_err(|x| x + 1) == Ok(1));
-    assert!(Err::<isize, isize>(1).map_err(|x| x + 1) == Err(2));
-}
-
-#[test]
-fn test_collect() {
-    let v: Result<Vec<isize>, ()> = (0..0).map(|_| Ok::<isize, ()>(0)).collect();
-    assert!(v == Ok(vec![]));
-
-    let v: Result<Vec<isize>, ()> = (0..3).map(|x| Ok::<isize, ()>(x)).collect();
-    assert!(v == Ok(vec![0, 1, 2]));
-
-    let v: Result<Vec<isize>, isize> = (0..3).map(|x| {
-        if x > 1 { Err(x) } else { Ok(x) }
-    }).collect();
-    assert!(v == Err(2));
-
-    // test that it does not take more elements than it needs
-    let mut functions: [Box<Fn() -> Result<(), isize>>; 3] =
-        [box || Ok(()), box || Err(1), box || panic!()];
-
-    let v: Result<Vec<()>, isize> = functions.iter_mut().map(|f| (*f)()).collect();
-    assert!(v == Err(1));
-}
-
-#[test]
-fn test_fmt_default() {
-    let ok: Result<isize, &'static str> = Ok(100);
-    let err: Result<isize, &'static str> = Err("Err");
-
-    let s = format!("{:?}", ok);
-    assert_eq!(s, "Ok(100)");
-    let s = format!("{:?}", err);
-    assert_eq!(s, "Err(\"Err\")");
-}
-
-#[test]
-fn test_unwrap_or() {
-    let ok: Result<isize, &'static str> = Ok(100);
-    let ok_err: Result<isize, &'static str> = Err("Err");
-
-    assert_eq!(ok.unwrap_or(50), 100);
-    assert_eq!(ok_err.unwrap_or(50), 50);
-}
-
-#[test]
-fn test_unwrap_or_else() {
-    fn handler(msg: &'static str) -> isize {
-        if msg == "I got this." {
-            50
-        } else {
-            panic!("BadBad")
-        }
-    }
-
-    let ok: Result<isize, &'static str> = Ok(100);
-    let ok_err: Result<isize, &'static str> = Err("I got this.");
-
-    assert_eq!(ok.unwrap_or_else(handler), 100);
-    assert_eq!(ok_err.unwrap_or_else(handler), 50);
-}
-
-#[test]
-#[should_panic]
-pub fn test_unwrap_or_else_panic() {
-    fn handler(msg: &'static str) -> isize {
-        if msg == "I got this." {
-            50
-        } else {
-            panic!("BadBad")
-        }
-    }
-
-    let bad_err: Result<isize, &'static str> = Err("Unrecoverable mess.");
-    let _ : isize = bad_err.unwrap_or_else(handler);
-}
-
-
-#[test]
-pub fn test_expect_ok() {
-    let ok: Result<isize, &'static str> = Ok(100);
-    assert_eq!(ok.expect("Unexpected error"), 100);
-}
-#[test]
-#[should_panic(expected="Got expected error: \"All good\"")]
-pub fn test_expect_err() {
-    let err: Result<isize, &'static str> = Err("All good");
-    err.expect("Got expected error");
-}
-
-
-#[test]
-pub fn test_expect_err_err() {
-    let ok: Result<&'static str, isize> = Err(100);
-    assert_eq!(ok.expect_err("Unexpected ok"), 100);
-}
-#[test]
-#[should_panic(expected="Got expected ok: \"All good\"")]
-pub fn test_expect_err_ok() {
-    let err: Result<&'static str, isize> = Ok("All good");
-    err.expect_err("Got expected ok");
-}
-
-#[test]
-pub fn test_iter() {
-    let ok: Result<isize, &'static str> = Ok(100);
-    let mut it = ok.iter();
-    assert_eq!(it.size_hint(), (1, Some(1)));
-    assert_eq!(it.next(), Some(&100));
-    assert_eq!(it.size_hint(), (0, Some(0)));
-    assert!(it.next().is_none());
-    assert_eq!((&ok).into_iter().next(), Some(&100));
-
-    let err: Result<isize, &'static str> = Err("error");
-    assert_eq!(err.iter().next(), None);
-}
-
-#[test]
-pub fn test_iter_mut() {
-    let mut ok: Result<isize, &'static str> = Ok(100);
-    for loc in ok.iter_mut() {
-        *loc = 200;
-    }
-    assert_eq!(ok, Ok(200));
-    for loc in &mut ok {
-        *loc = 300;
-    }
-    assert_eq!(ok, Ok(300));
-
-    let mut err: Result<isize, &'static str> = Err("error");
-    for loc in err.iter_mut() {
-        *loc = 200;
-    }
-    assert_eq!(err, Err("error"));
-}
-
-#[test]
-pub fn test_unwrap_or_default() {
-    assert_eq!(op1().unwrap_or_default(), 666);
-    assert_eq!(op2().unwrap_or_default(), 0);
-}
diff --git a/src/libcoretest/slice.rs b/src/libcoretest/slice.rs
deleted file mode 100644 (file)
index ec38345..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use core::cmp::Ordering::{Equal, Greater, Less};
-use core::slice::heapsort;
-use core::result::Result::{Ok, Err};
-use rand::{Rng, XorShiftRng};
-
-#[test]
-fn test_binary_search() {
-    let b = [1, 2, 4, 6, 8, 9];
-    assert!(b.binary_search_by(|v| v.cmp(&6)) == Ok(3));
-    assert!(b.binary_search_by(|v| v.cmp(&5)) == Err(3));
-    let b = [1, 2, 4, 6, 7, 8, 9];
-    assert!(b.binary_search_by(|v| v.cmp(&6)) == Ok(3));
-    assert!(b.binary_search_by(|v| v.cmp(&5)) == Err(3));
-    let b = [1, 2, 4, 6, 8, 9];
-    assert!(b.binary_search_by(|v| v.cmp(&8)) == Ok(4));
-    assert!(b.binary_search_by(|v| v.cmp(&7)) == Err(4));
-    let b = [1, 2, 4, 6, 7, 8, 9];
-    assert!(b.binary_search_by(|v| v.cmp(&8)) == Ok(5));
-    let b = [1, 2, 4, 5, 6, 8, 9];
-    assert!(b.binary_search_by(|v| v.cmp(&7)) == Err(5));
-    assert!(b.binary_search_by(|v| v.cmp(&0)) == Err(0));
-    let b = [1, 2, 4, 5, 6, 8];
-    assert!(b.binary_search_by(|v| v.cmp(&9)) == Err(6));
-}
-
-#[test]
-fn test_iterator_nth() {
-    let v: &[_] = &[0, 1, 2, 3, 4];
-    for i in 0..v.len() {
-        assert_eq!(v.iter().nth(i).unwrap(), &v[i]);
-    }
-    assert_eq!(v.iter().nth(v.len()), None);
-
-    let mut iter = v.iter();
-    assert_eq!(iter.nth(2).unwrap(), &v[2]);
-    assert_eq!(iter.nth(1).unwrap(), &v[4]);
-}
-
-#[test]
-fn test_iterator_last() {
-    let v: &[_] = &[0, 1, 2, 3, 4];
-    assert_eq!(v.iter().last().unwrap(), &4);
-    assert_eq!(v[..1].iter().last().unwrap(), &0);
-}
-
-#[test]
-fn test_iterator_count() {
-    let v: &[_] = &[0, 1, 2, 3, 4];
-    assert_eq!(v.iter().count(), 5);
-
-    let mut iter2 = v.iter();
-    iter2.next();
-    iter2.next();
-    assert_eq!(iter2.count(), 3);
-}
-
-#[test]
-fn test_chunks_count() {
-    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
-    let c = v.chunks(3);
-    assert_eq!(c.count(), 2);
-
-    let v2: &[i32] = &[0, 1, 2, 3, 4];
-    let c2 = v2.chunks(2);
-    assert_eq!(c2.count(), 3);
-
-    let v3: &[i32] = &[];
-    let c3 = v3.chunks(2);
-    assert_eq!(c3.count(), 0);
-}
-
-#[test]
-fn test_chunks_nth() {
-    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
-    let mut c = v.chunks(2);
-    assert_eq!(c.nth(1).unwrap()[1], 3);
-    assert_eq!(c.next().unwrap()[0], 4);
-
-    let v2: &[i32] = &[0, 1, 2, 3, 4];
-    let mut c2 = v2.chunks(3);
-    assert_eq!(c2.nth(1).unwrap()[1], 4);
-    assert_eq!(c2.next(), None);
-}
-
-#[test]
-fn test_chunks_last() {
-    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
-    let c = v.chunks(2);
-    assert_eq!(c.last().unwrap()[1], 5);
-
-    let v2: &[i32] = &[0, 1, 2, 3, 4];
-    let c2 = v2.chunks(2);
-    assert_eq!(c2.last().unwrap()[0], 4);
-}
-
-#[test]
-fn test_chunks_mut_count() {
-    let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
-    let c = v.chunks_mut(3);
-    assert_eq!(c.count(), 2);
-
-    let mut v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
-    let c2 = v2.chunks_mut(2);
-    assert_eq!(c2.count(), 3);
-
-    let mut v3: &mut [i32] = &mut [];
-    let c3 = v3.chunks_mut(2);
-    assert_eq!(c3.count(), 0);
-}
-
-#[test]
-fn test_chunks_mut_nth() {
-    let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
-    let mut c = v.chunks_mut(2);
-    assert_eq!(c.nth(1).unwrap()[1], 3);
-    assert_eq!(c.next().unwrap()[0], 4);
-
-    let mut v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
-    let mut c2 = v2.chunks_mut(3);
-    assert_eq!(c2.nth(1).unwrap()[1], 4);
-    assert_eq!(c2.next(), None);
-}
-
-#[test]
-fn test_chunks_mut_last() {
-    let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
-    let c = v.chunks_mut(2);
-    assert_eq!(c.last().unwrap()[1], 5);
-
-    let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
-    let c2 = v2.chunks_mut(2);
-    assert_eq!(c2.last().unwrap()[0], 4);
-}
-
-#[test]
-fn test_windows_count() {
-    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
-    let c = v.windows(3);
-    assert_eq!(c.count(), 4);
-
-    let v2: &[i32] = &[0, 1, 2, 3, 4];
-    let c2 = v2.windows(6);
-    assert_eq!(c2.count(), 0);
-
-    let v3: &[i32] = &[];
-    let c3 = v3.windows(2);
-    assert_eq!(c3.count(), 0);
-}
-
-#[test]
-fn test_windows_nth() {
-    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
-    let mut c = v.windows(2);
-    assert_eq!(c.nth(2).unwrap()[1], 3);
-    assert_eq!(c.next().unwrap()[0], 3);
-
-    let v2: &[i32] = &[0, 1, 2, 3, 4];
-    let mut c2 = v2.windows(4);
-    assert_eq!(c2.nth(1).unwrap()[1], 2);
-    assert_eq!(c2.next(), None);
-}
-
-#[test]
-fn test_windows_last() {
-    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
-    let c = v.windows(2);
-    assert_eq!(c.last().unwrap()[1], 5);
-
-    let v2: &[i32] = &[0, 1, 2, 3, 4];
-    let c2 = v2.windows(2);
-    assert_eq!(c2.last().unwrap()[0], 3);
-}
-
-#[test]
-fn get_range() {
-    let v: &[i32] = &[0, 1, 2, 3, 4, 5];
-    assert_eq!(v.get(..), Some(&[0, 1, 2, 3, 4, 5][..]));
-    assert_eq!(v.get(..2), Some(&[0, 1][..]));
-    assert_eq!(v.get(2..), Some(&[2, 3, 4, 5][..]));
-    assert_eq!(v.get(1..4), Some(&[1, 2, 3][..]));
-    assert_eq!(v.get(7..), None);
-    assert_eq!(v.get(7..10), None);
-}
-
-#[test]
-fn get_mut_range() {
-    let mut v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
-    assert_eq!(v.get_mut(..), Some(&mut [0, 1, 2, 3, 4, 5][..]));
-    assert_eq!(v.get_mut(..2), Some(&mut [0, 1][..]));
-    assert_eq!(v.get_mut(2..), Some(&mut [2, 3, 4, 5][..]));
-    assert_eq!(v.get_mut(1..4), Some(&mut [1, 2, 3][..]));
-    assert_eq!(v.get_mut(7..), None);
-    assert_eq!(v.get_mut(7..10), None);
-}
-
-#[test]
-fn get_unchecked_range() {
-    unsafe {
-        let v: &[i32] = &[0, 1, 2, 3, 4, 5];
-        assert_eq!(v.get_unchecked(..), &[0, 1, 2, 3, 4, 5][..]);
-        assert_eq!(v.get_unchecked(..2), &[0, 1][..]);
-        assert_eq!(v.get_unchecked(2..), &[2, 3, 4, 5][..]);
-        assert_eq!(v.get_unchecked(1..4), &[1, 2, 3][..]);
-    }
-}
-
-#[test]
-fn get_unchecked_mut_range() {
-    unsafe {
-        let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
-        assert_eq!(v.get_unchecked_mut(..), &mut [0, 1, 2, 3, 4, 5][..]);
-        assert_eq!(v.get_unchecked_mut(..2), &mut [0, 1][..]);
-        assert_eq!(v.get_unchecked_mut(2..), &mut[2, 3, 4, 5][..]);
-        assert_eq!(v.get_unchecked_mut(1..4), &mut [1, 2, 3][..]);
-    }
-}
-
-#[test]
-fn sort_unstable() {
-    let mut v = [0; 600];
-    let mut tmp = [0; 600];
-    let mut rng = XorShiftRng::new_unseeded();
-
-    for len in (2..25).chain(500..510) {
-        let v = &mut v[0..len];
-        let tmp = &mut tmp[0..len];
-
-        for &modulus in &[5, 10, 100, 1000] {
-            for _ in 0..100 {
-                for i in 0..len {
-                    v[i] = rng.gen::<i32>() % modulus;
-                }
-
-                // Sort in default order.
-                tmp.copy_from_slice(v);
-                tmp.sort_unstable();
-                assert!(tmp.windows(2).all(|w| w[0] <= w[1]));
-
-                // Sort in ascending order.
-                tmp.copy_from_slice(v);
-                tmp.sort_unstable_by(|a, b| a.cmp(b));
-                assert!(tmp.windows(2).all(|w| w[0] <= w[1]));
-
-                // Sort in descending order.
-                tmp.copy_from_slice(v);
-                tmp.sort_unstable_by(|a, b| b.cmp(a));
-                assert!(tmp.windows(2).all(|w| w[0] >= w[1]));
-
-                // Test heapsort using `<` operator.
-                tmp.copy_from_slice(v);
-                heapsort(tmp, |a, b| a < b);
-                assert!(tmp.windows(2).all(|w| w[0] <= w[1]));
-
-                // Test heapsort using `>` operator.
-                tmp.copy_from_slice(v);
-                heapsort(tmp, |a, b| a > b);
-                assert!(tmp.windows(2).all(|w| w[0] >= w[1]));
-            }
-        }
-    }
-
-    // Sort using a completely random comparison function.
-    // This will reorder the elements *somehow*, but won't panic.
-    for i in 0..v.len() {
-        v[i] = i as i32;
-    }
-    v.sort_unstable_by(|_, _| *rng.choose(&[Less, Equal, Greater]).unwrap());
-    v.sort_unstable();
-    for i in 0..v.len() {
-        assert_eq!(v[i], i as i32);
-    }
-
-    // Should not panic.
-    [0i32; 0].sort_unstable();
-    [(); 10].sort_unstable();
-    [(); 100].sort_unstable();
-
-    let mut v = [0xDEADBEEFu64];
-    v.sort_unstable();
-    assert!(v == [0xDEADBEEF]);
-}
diff --git a/src/libcoretest/str.rs b/src/libcoretest/str.rs
deleted file mode 100644 (file)
index b7d9ba4..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014-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.
-
-// All `str` tests live in libcollectiontest::str
diff --git a/src/libcoretest/tuple.rs b/src/libcoretest/tuple.rs
deleted file mode 100644 (file)
index 4fe5e0a..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::cmp::Ordering::{Equal, Less, Greater};
-
-#[test]
-fn test_clone() {
-    let a = (1, "2");
-    let b = a.clone();
-    assert_eq!(a, b);
-}
-
-#[test]
-fn test_tuple_cmp() {
-    let (small, big) = ((1, 2, 3), (3, 2, 1));
-
-    let nan = 0.0f64/0.0;
-
-    // PartialEq
-    assert_eq!(small, small);
-    assert_eq!(big, big);
-    assert!(small != big);
-    assert!(big != small);
-
-    // PartialOrd
-    assert!(small < big);
-    assert!(!(small < small));
-    assert!(!(big < small));
-    assert!(!(big < big));
-
-    assert!(small <= small);
-    assert!(big <= big);
-
-    assert!(big > small);
-    assert!(small >= small);
-    assert!(big >= small);
-    assert!(big >= big);
-
-    assert!(!((1.0f64, 2.0f64) < (nan, 3.0)));
-    assert!(!((1.0f64, 2.0f64) <= (nan, 3.0)));
-    assert!(!((1.0f64, 2.0f64) > (nan, 3.0)));
-    assert!(!((1.0f64, 2.0f64) >= (nan, 3.0)));
-    assert!(((1.0f64, 2.0f64) < (2.0, nan)));
-    assert!(!((2.0f64, 2.0f64) < (2.0, nan)));
-
-    // Ord
-    assert!(small.cmp(&small) == Equal);
-    assert!(big.cmp(&big) == Equal);
-    assert!(small.cmp(&big) == Less);
-    assert!(big.cmp(&small) == Greater);
-}
-
-#[test]
-fn test_show() {
-    let s = format!("{:?}", (1,));
-    assert_eq!(s, "(1,)");
-    let s = format!("{:?}", (1, true));
-    assert_eq!(s, "(1, true)");
-    let s = format!("{:?}", (1, "hi", true));
-    assert_eq!(s, "(1, \"hi\", true)");
-}
index 809d5db3071d7be75607974035a056b28ef3c377..dca9ebb3397a62b547b831f931ae172231df6f5b 100644 (file)
@@ -394,6 +394,10 @@ pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
         }
     }
 
+    pub fn node_to_hir_id(&self, node_id: ast::NodeId) -> hir::HirId {
+        self.node_to_hir_id[node_id]
+    }
+
     /// Add a definition with a parent definition.
     pub fn create_def_with_parent(&mut self,
                                   parent: Option<DefIndex>,
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
new file mode 100644 (file)
index 0000000..73d8121
--- /dev/null
@@ -0,0 +1,300 @@
+// Copyright 2017 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 hir;
+use hir::def_id::DefId;
+use ich::{self, CachingCodemapView, DefPathHashes};
+use session::config::DebugInfoLevel::NoDebugInfo;
+use ty;
+
+use std::hash as std_hash;
+
+use syntax::ast;
+use syntax::attr;
+use syntax::ext::hygiene::SyntaxContext;
+use syntax::symbol::Symbol;
+use syntax_pos::Span;
+
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
+                                           StableHasherResult};
+use rustc_data_structures::accumulate_vec::AccumulateVec;
+
+/// This is the context state available during incr. comp. hashing. It contains
+/// enough information to transform DefIds and HirIds into stable DefPaths (i.e.
+/// a reference to the TyCtxt) and it holds a few caches for speeding up various
+/// things (e.g. each DefId/DefPath is only hashed once).
+pub struct StableHashingContext<'a, 'tcx: 'a> {
+    tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
+    def_path_hashes: DefPathHashes<'a, 'tcx>,
+    codemap: CachingCodemapView<'tcx>,
+    hash_spans: bool,
+    hash_bodies: bool,
+    overflow_checks_enabled: bool,
+    node_id_hashing_mode: NodeIdHashingMode,
+    // A sorted array of symbol keys for fast lookup.
+    ignored_attr_names: Vec<Symbol>,
+}
+
+#[derive(PartialEq, Eq, Clone, Copy)]
+pub enum NodeIdHashingMode {
+    Ignore,
+    HashDefPath,
+    HashTraitsInScope,
+}
+
+impl<'a, 'tcx: 'a> StableHashingContext<'a, 'tcx> {
+
+    pub fn new(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> Self {
+        let hash_spans_initial = tcx.sess.opts.debuginfo != NoDebugInfo;
+        let check_overflow_initial = tcx.sess.overflow_checks();
+
+        let mut ignored_attr_names: Vec<_> = ich::IGNORED_ATTRIBUTES
+            .iter()
+            .map(|&s| Symbol::intern(s))
+            .collect();
+
+        ignored_attr_names.sort();
+
+        StableHashingContext {
+            tcx: tcx,
+            def_path_hashes: DefPathHashes::new(tcx),
+            codemap: CachingCodemapView::new(tcx),
+            hash_spans: hash_spans_initial,
+            hash_bodies: true,
+            overflow_checks_enabled: check_overflow_initial,
+            node_id_hashing_mode: NodeIdHashingMode::HashDefPath,
+            ignored_attr_names: ignored_attr_names,
+        }
+    }
+
+    #[inline]
+    pub fn while_hashing_hir_bodies<F: FnOnce(&mut Self)>(&mut self,
+                                                          hash_bodies: bool,
+                                                          f: F) {
+        let prev_hash_bodies = self.hash_bodies;
+        self.hash_bodies = hash_bodies;
+        f(self);
+        self.hash_bodies = prev_hash_bodies;
+    }
+
+    #[inline]
+    pub fn while_hashing_spans<F: FnOnce(&mut Self)>(&mut self,
+                                                     hash_spans: bool,
+                                                     f: F) {
+        let prev_hash_spans = self.hash_spans;
+        self.hash_spans = hash_spans;
+        f(self);
+        self.hash_spans = prev_hash_spans;
+    }
+
+    #[inline]
+    pub fn with_node_id_hashing_mode<F: FnOnce(&mut Self)>(&mut self,
+                                                           mode: NodeIdHashingMode,
+                                                           f: F) {
+        let prev = self.node_id_hashing_mode;
+        self.node_id_hashing_mode = mode;
+        f(self);
+        self.node_id_hashing_mode = prev;
+    }
+
+    #[inline]
+    pub fn tcx(&self) -> ty::TyCtxt<'a, 'tcx, 'tcx> {
+        self.tcx
+    }
+
+    #[inline]
+    pub fn def_path_hash(&mut self, def_id: DefId) -> u64 {
+        self.def_path_hashes.hash(def_id)
+    }
+
+    #[inline]
+    pub fn hash_spans(&self) -> bool {
+        self.hash_spans
+    }
+
+    #[inline]
+    pub fn hash_bodies(&self) -> bool {
+        self.hash_bodies
+    }
+
+    #[inline]
+    pub fn codemap(&mut self) -> &mut CachingCodemapView<'tcx> {
+        &mut self.codemap
+    }
+
+    #[inline]
+    pub fn is_ignored_attr(&self, name: Symbol) -> bool {
+        self.ignored_attr_names.binary_search(&name).is_ok()
+    }
+
+    pub fn hash_hir_item_like<F: FnOnce(&mut Self)>(&mut self,
+                                                    item_attrs: &[ast::Attribute],
+                                                    f: F) {
+        let prev_overflow_checks = self.overflow_checks_enabled;
+        if attr::contains_name(item_attrs, "rustc_inherit_overflow_checks") {
+            self.overflow_checks_enabled = true;
+        }
+        let prev_hash_node_ids = self.node_id_hashing_mode;
+        self.node_id_hashing_mode = NodeIdHashingMode::Ignore;
+
+        f(self);
+
+        self.node_id_hashing_mode = prev_hash_node_ids;
+        self.overflow_checks_enabled = prev_overflow_checks;
+    }
+
+    #[inline]
+    pub fn binop_can_panic_at_runtime(&self, binop: hir::BinOp_) -> bool
+    {
+        match binop {
+            hir::BiAdd |
+            hir::BiSub |
+            hir::BiMul => self.overflow_checks_enabled,
+
+            hir::BiDiv |
+            hir::BiRem => true,
+
+            hir::BiAnd |
+            hir::BiOr |
+            hir::BiBitXor |
+            hir::BiBitAnd |
+            hir::BiBitOr |
+            hir::BiShl |
+            hir::BiShr |
+            hir::BiEq |
+            hir::BiLt |
+            hir::BiLe |
+            hir::BiNe |
+            hir::BiGe |
+            hir::BiGt => false
+        }
+    }
+
+    #[inline]
+    pub fn unop_can_panic_at_runtime(&self, unop: hir::UnOp) -> bool
+    {
+        match unop {
+            hir::UnDeref |
+            hir::UnNot => false,
+            hir::UnNeg => self.overflow_checks_enabled,
+        }
+    }
+}
+
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ast::NodeId {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        match hcx.node_id_hashing_mode {
+            NodeIdHashingMode::Ignore => {
+                // Most NodeIds in the HIR can be ignored, but if there is a
+                // corresponding entry in the `trait_map` we need to hash that.
+                // Make sure we don't ignore too much by checking that there is
+                // no entry in a debug_assert!().
+                debug_assert!(hcx.tcx.trait_map.get(self).is_none());
+            }
+            NodeIdHashingMode::HashDefPath => {
+                hcx.tcx.hir.definitions().node_to_hir_id(*self).hash_stable(hcx, hasher);
+            }
+            NodeIdHashingMode::HashTraitsInScope => {
+                if let Some(traits) = hcx.tcx.trait_map.get(self) {
+                    // The ordering of the candidates is not fixed. So we hash
+                    // the def-ids and then sort them and hash the collection.
+                    let mut candidates: AccumulateVec<[_; 8]> =
+                        traits.iter()
+                              .map(|&hir::TraitCandidate { def_id, import_id: _ }| {
+                                  hcx.def_path_hash(def_id)
+                              })
+                              .collect();
+                    if traits.len() > 1 {
+                        candidates.sort();
+                    }
+                    candidates.hash_stable(hcx, hasher);
+                }
+            }
+        }
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for Span {
+
+    // Hash a span in a stable way. We can't directly hash the span's BytePos
+    // fields (that would be similar to hashing pointers, since those are just
+    // offsets into the CodeMap). Instead, we hash the (file name, line, column)
+    // triple, which stays the same even if the containing FileMap has moved
+    // within the CodeMap.
+    // Also note that we are hashing byte offsets for the column, not unicode
+    // codepoint offsets. For the purpose of the hash that's sufficient.
+    // Also, hashing filenames is expensive so we avoid doing it twice when the
+    // span starts and ends in the same file, which is almost always the case.
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        use syntax_pos::Pos;
+
+        if !hcx.hash_spans {
+            return
+        }
+
+        // If this is not an empty or invalid span, we want to hash the last
+        // position that belongs to it, as opposed to hashing the first
+        // position past it.
+        let span_hi = if self.hi > self.lo {
+            // We might end up in the middle of a multibyte character here,
+            // but that's OK, since we are not trying to decode anything at
+            // this position.
+            self.hi - ::syntax_pos::BytePos(1)
+        } else {
+            self.hi
+        };
+
+        {
+            let loc1 = hcx.codemap().byte_pos_to_line_and_col(self.lo);
+            let loc1 = loc1.as_ref()
+                           .map(|&(ref fm, line, col)| (&fm.name[..], line, col.to_usize()))
+                           .unwrap_or(("???", 0, 0));
+
+            let loc2 = hcx.codemap().byte_pos_to_line_and_col(span_hi);
+            let loc2 = loc2.as_ref()
+                           .map(|&(ref fm, line, col)| (&fm.name[..], line, col.to_usize()))
+                           .unwrap_or(("???", 0, 0));
+
+            if loc1.0 == loc2.0 {
+                std_hash::Hash::hash(&0u8, hasher);
+
+                std_hash::Hash::hash(loc1.0, hasher);
+                std_hash::Hash::hash(&loc1.1, hasher);
+                std_hash::Hash::hash(&loc1.2, hasher);
+
+                // Do not hash the file name twice
+                std_hash::Hash::hash(&loc2.1, hasher);
+                std_hash::Hash::hash(&loc2.2, hasher);
+            } else {
+                std_hash::Hash::hash(&1u8, hasher);
+
+                std_hash::Hash::hash(loc1.0, hasher);
+                std_hash::Hash::hash(&loc1.1, hasher);
+                std_hash::Hash::hash(&loc1.2, hasher);
+
+                std_hash::Hash::hash(loc2.0, hasher);
+                std_hash::Hash::hash(&loc2.1, hasher);
+                std_hash::Hash::hash(&loc2.2, hasher);
+            }
+        }
+
+        if self.ctxt == SyntaxContext::empty() {
+            0u8.hash_stable(hcx, hasher);
+        } else {
+            1u8.hash_stable(hcx, hasher);
+            self.source_callsite().hash_stable(hcx, hasher);
+        }
+    }
+}
diff --git a/src/librustc/ich/impls_const_math.rs b/src/librustc/ich/impls_const_math.rs
new file mode 100644 (file)
index 0000000..6d11f2a
--- /dev/null
@@ -0,0 +1,71 @@
+// Copyright 2017 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.
+
+//! This module contains `HashStable` implementations for various data types
+//! from `rustc_const_math` in no particular order.
+
+impl_stable_hash_for!(enum ::rustc_const_math::ConstFloat {
+    F32(val),
+    F64(val)
+});
+
+impl_stable_hash_for!(enum ::rustc_const_math::ConstInt {
+    I8(val),
+    I16(val),
+    I32(val),
+    I64(val),
+    I128(val),
+    Isize(val),
+    U8(val),
+    U16(val),
+    U32(val),
+    U64(val),
+    U128(val),
+    Usize(val)
+});
+
+impl_stable_hash_for!(enum ::rustc_const_math::ConstIsize {
+    Is16(i16),
+    Is32(i32),
+    Is64(i64)
+});
+
+impl_stable_hash_for!(enum ::rustc_const_math::ConstUsize {
+    Us16(i16),
+    Us32(i32),
+    Us64(i64)
+});
+
+impl_stable_hash_for!(enum ::rustc_const_math::ConstMathErr {
+    NotInRange,
+    CmpBetweenUnequalTypes,
+    UnequalTypes(op),
+    Overflow(op),
+    ShiftNegative,
+    DivisionByZero,
+    RemainderByZero,
+    UnsignedNegation,
+    ULitOutOfRange(int_ty),
+    LitOutOfRange(int_ty)
+});
+
+impl_stable_hash_for!(enum ::rustc_const_math::Op {
+    Add,
+    Sub,
+    Mul,
+    Div,
+    Rem,
+    Shr,
+    Shl,
+    Neg,
+    BitAnd,
+    BitOr,
+    BitXor
+});
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
new file mode 100644 (file)
index 0000000..fb18f50
--- /dev/null
@@ -0,0 +1,1104 @@
+// Copyright 2017 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.
+
+//! This module contains `HashStable` implementations for various HIR data
+//! types in no particular order.
+
+use hir;
+use hir::def_id::DefId;
+use ich::{StableHashingContext, NodeIdHashingMode};
+use std::mem;
+
+use syntax::ast;
+
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
+                                           StableHasherResult};
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for DefId {
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        hcx.def_path_hash(*self).hash_stable(hcx, hasher);
+    }
+}
+
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::HirId {
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let hir::HirId {
+            owner,
+            local_id,
+        } = *self;
+
+        hcx.def_path_hash(DefId::local(owner)).hash_stable(hcx, hasher);
+        local_id.hash_stable(hcx, hasher);
+    }
+}
+
+impl_stable_hash_for!(tuple_struct hir::ItemLocalId { index });
+
+// The following implementations of HashStable for ItemId, TraitItemId, and
+// ImplItemId deserve special attention. Normally we do not hash NodeIds within
+// the HIR, since they just signify a HIR nodes own path. But ItemId et al
+// are used when another item in the HIR is *referenced* and we certainly
+// want to pick up on a reference changing its target, so we hash the NodeIds
+// in "DefPath Mode".
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::ItemId {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let hir::ItemId {
+            id
+        } = *self;
+
+        hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
+            id.hash_stable(hcx, hasher);
+        })
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::TraitItemId {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let hir::TraitItemId {
+            node_id
+        } = * self;
+
+        hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
+            node_id.hash_stable(hcx, hasher);
+        })
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::ImplItemId {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let hir::ImplItemId {
+            node_id
+        } = * self;
+
+        hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
+            node_id.hash_stable(hcx, hasher);
+        })
+    }
+}
+
+impl_stable_hash_for!(struct hir::Lifetime {
+    id,
+    span,
+    name
+});
+
+impl_stable_hash_for!(struct hir::LifetimeDef {
+    lifetime,
+    bounds,
+    pure_wrt_drop
+});
+
+impl_stable_hash_for!(struct hir::Path {
+    span,
+    def,
+    segments
+});
+
+impl_stable_hash_for!(struct hir::PathSegment {
+    name,
+    parameters
+});
+
+impl_stable_hash_for!(enum hir::PathParameters {
+    AngleBracketedParameters(data),
+    ParenthesizedParameters(data)
+});
+
+impl_stable_hash_for!(struct hir::AngleBracketedParameterData {
+    lifetimes,
+    types,
+    infer_types,
+    bindings
+});
+
+impl_stable_hash_for!(struct hir::ParenthesizedParameterData {
+    span,
+    inputs,
+    output
+});
+
+impl_stable_hash_for!(enum hir::TyParamBound {
+    TraitTyParamBound(poly_trait_ref, trait_bound_modifier),
+    RegionTyParamBound(lifetime)
+});
+
+impl_stable_hash_for!(enum hir::TraitBoundModifier {
+    None,
+    Maybe
+});
+
+impl_stable_hash_for!(struct hir::TyParam {
+    name,
+    id,
+    bounds,
+    default,
+    span,
+    pure_wrt_drop
+});
+
+impl_stable_hash_for!(struct hir::Generics {
+    lifetimes,
+    ty_params,
+    where_clause,
+    span
+});
+
+impl_stable_hash_for!(struct hir::WhereClause {
+    id,
+    predicates
+});
+
+impl_stable_hash_for!(enum hir::WherePredicate {
+    BoundPredicate(pred),
+    RegionPredicate(pred),
+    EqPredicate(pred)
+});
+
+impl_stable_hash_for!(struct hir::WhereBoundPredicate {
+    span,
+    bound_lifetimes,
+    bounded_ty,
+    bounds
+});
+
+impl_stable_hash_for!(struct hir::WhereRegionPredicate {
+    span,
+    lifetime,
+    bounds
+});
+
+impl_stable_hash_for!(struct hir::WhereEqPredicate {
+    id,
+    span,
+    lhs_ty,
+    rhs_ty
+});
+
+impl_stable_hash_for!(struct hir::MutTy {
+    ty,
+    mutbl
+});
+
+impl_stable_hash_for!(struct hir::MethodSig {
+    unsafety,
+    constness,
+    abi,
+    decl,
+    generics
+});
+
+impl_stable_hash_for!(struct hir::TypeBinding {
+    id,
+    name,
+    ty,
+    span
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Ty {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let node_id_hashing_mode = match self.node {
+            hir::TySlice(..)       |
+            hir::TyArray(..)       |
+            hir::TyPtr(..)         |
+            hir::TyRptr(..)        |
+            hir::TyBareFn(..)      |
+            hir::TyNever           |
+            hir::TyTup(..)         |
+            hir::TyTraitObject(..) |
+            hir::TyImplTrait(..)   |
+            hir::TyTypeof(..)      |
+            hir::TyInfer           => {
+                NodeIdHashingMode::Ignore
+            }
+            hir::TyPath(..) => {
+                NodeIdHashingMode::HashTraitsInScope
+            }
+        };
+
+        hcx.while_hashing_hir_bodies(true, |hcx| {
+            let hir::Ty {
+                id,
+                ref node,
+                ref span,
+            } = *self;
+
+            hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| {
+                id.hash_stable(hcx, hasher);
+            });
+            node.hash_stable(hcx, hasher);
+            span.hash_stable(hcx, hasher);
+        })
+    }
+}
+
+impl_stable_hash_for!(enum hir::PrimTy {
+    TyInt(int_ty),
+    TyUint(uint_ty),
+    TyFloat(float_ty),
+    TyStr,
+    TyBool,
+    TyChar
+});
+
+impl_stable_hash_for!(struct hir::BareFnTy {
+    unsafety,
+    abi,
+    lifetimes,
+    decl
+});
+
+impl_stable_hash_for!(enum hir::Ty_ {
+    TySlice(t),
+    TyArray(t, body_id),
+    TyPtr(t),
+    TyRptr(lifetime, t),
+    TyBareFn(t),
+    TyNever,
+    TyTup(ts),
+    TyPath(qpath),
+    TyTraitObject(trait_refs, lifetime),
+    TyImplTrait(bounds),
+    TyTypeof(body_id),
+    TyInfer
+});
+
+impl_stable_hash_for!(struct hir::FnDecl {
+    inputs,
+    output,
+    variadic,
+    has_implicit_self
+});
+
+impl_stable_hash_for!(enum hir::FunctionRetTy {
+    DefaultReturn(span),
+    Return(t)
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::TraitRef {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let hir::TraitRef {
+            ref path,
+            ref_id,
+        } = *self;
+
+        path.hash_stable(hcx, hasher);
+        hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashTraitsInScope, |hcx| {
+            ref_id.hash_stable(hcx, hasher);
+        });
+    }
+}
+
+
+impl_stable_hash_for!(struct hir::PolyTraitRef {
+    bound_lifetimes,
+    trait_ref,
+    span
+});
+
+impl_stable_hash_for!(enum hir::QPath {
+    Resolved(t, path),
+    TypeRelative(t, path_segment)
+});
+
+impl_stable_hash_for!(struct hir::MacroDef {
+    name,
+    attrs,
+    id,
+    span,
+    body
+});
+
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Block {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let hir::Block {
+            ref stmts,
+            ref expr,
+            id,
+            rules,
+            span,
+            targeted_by_break,
+        } = *self;
+
+        let non_item_stmts = || stmts.iter().filter(|stmt| {
+            match stmt.node {
+                hir::StmtDecl(ref decl, _) => {
+                    match decl.node {
+                        // If this is a declaration of a nested item, we don't
+                        // want to leave any trace of it in the hash value, not
+                        // even that it exists. Otherwise changing the position
+                        // of nested items would invalidate the containing item
+                        // even though that does not constitute a semantic
+                        // change.
+                        hir::DeclItem(_) => false,
+                        hir::DeclLocal(_) => true
+                    }
+                }
+                hir::StmtExpr(..) |
+                hir::StmtSemi(..) => true
+            }
+        });
+
+        let count = non_item_stmts().count();
+
+        count.hash_stable(hcx, hasher);
+
+        for stmt in non_item_stmts() {
+            stmt.hash_stable(hcx, hasher);
+        }
+
+        expr.hash_stable(hcx, hasher);
+        id.hash_stable(hcx, hasher);
+        rules.hash_stable(hcx, hasher);
+        span.hash_stable(hcx, hasher);
+        targeted_by_break.hash_stable(hcx, hasher);
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Pat {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let node_id_hashing_mode = match self.node {
+            hir::PatKind::Wild        |
+            hir::PatKind::Binding(..) |
+            hir::PatKind::Tuple(..)   |
+            hir::PatKind::Box(..)     |
+            hir::PatKind::Ref(..)     |
+            hir::PatKind::Lit(..)     |
+            hir::PatKind::Range(..)   |
+            hir::PatKind::Slice(..)   => {
+                NodeIdHashingMode::Ignore
+            }
+            hir::PatKind::Path(..)        |
+            hir::PatKind::Struct(..)      |
+            hir::PatKind::TupleStruct(..) => {
+                NodeIdHashingMode::HashTraitsInScope
+            }
+        };
+
+        let hir::Pat {
+            id,
+            ref node,
+            ref span
+        } = *self;
+
+        hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| {
+            id.hash_stable(hcx, hasher);
+        });
+        node.hash_stable(hcx, hasher);
+        span.hash_stable(hcx, hasher);
+    }
+}
+
+impl_stable_hash_for_spanned!(hir::FieldPat);
+impl_stable_hash_for!(struct hir::FieldPat {
+    name,
+    pat,
+    is_shorthand
+});
+
+impl_stable_hash_for!(enum hir::BindingMode {
+    BindByRef(mutability),
+    BindByValue(mutability)
+});
+
+impl_stable_hash_for!(enum hir::RangeEnd {
+    Included,
+    Excluded
+});
+
+impl_stable_hash_for!(enum hir::PatKind {
+    Wild,
+    Binding(binding_mode, var, name, sub),
+    Struct(path, field_pats, dotdot),
+    TupleStruct(path, field_pats, dotdot),
+    Path(path),
+    Tuple(field_pats, dotdot),
+    Box(sub),
+    Ref(sub, mutability),
+    Lit(expr),
+    Range(start, end, end_kind),
+    Slice(one, two, three)
+});
+
+impl_stable_hash_for!(enum hir::BinOp_ {
+    BiAdd,
+    BiSub,
+    BiMul,
+    BiDiv,
+    BiRem,
+    BiAnd,
+    BiOr,
+    BiBitXor,
+    BiBitAnd,
+    BiBitOr,
+    BiShl,
+    BiShr,
+    BiEq,
+    BiLt,
+    BiLe,
+    BiNe,
+    BiGe,
+    BiGt
+});
+
+impl_stable_hash_for_spanned!(hir::BinOp_);
+
+impl_stable_hash_for!(enum hir::UnOp {
+    UnDeref,
+    UnNot,
+    UnNeg
+});
+
+impl_stable_hash_for_spanned!(hir::Stmt_);
+
+impl_stable_hash_for!(struct hir::Local {
+    pat,
+    ty,
+    init,
+    id,
+    span,
+    attrs
+});
+
+impl_stable_hash_for_spanned!(hir::Decl_);
+impl_stable_hash_for!(enum hir::Decl_ {
+    DeclLocal(local),
+    DeclItem(item_id)
+});
+
+impl_stable_hash_for!(struct hir::Arm {
+    attrs,
+    pats,
+    guard,
+    body
+});
+
+impl_stable_hash_for!(struct hir::Field {
+    name,
+    expr,
+    span,
+    is_shorthand
+});
+
+impl_stable_hash_for_spanned!(ast::Name);
+
+
+impl_stable_hash_for!(enum hir::BlockCheckMode {
+    DefaultBlock,
+    UnsafeBlock(src),
+    PushUnsafeBlock(src),
+    PopUnsafeBlock(src)
+});
+
+impl_stable_hash_for!(enum hir::UnsafeSource {
+    CompilerGenerated,
+    UserProvided
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Expr {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        hcx.while_hashing_hir_bodies(true, |hcx| {
+            let hir::Expr {
+                id,
+                ref span,
+                ref node,
+                ref attrs
+            } = *self;
+
+            let (spans_always_on, node_id_hashing_mode) = match *node {
+                hir::ExprBox(..)        |
+                hir::ExprArray(..)      |
+                hir::ExprCall(..)       |
+                hir::ExprLit(..)        |
+                hir::ExprCast(..)       |
+                hir::ExprType(..)       |
+                hir::ExprIf(..)         |
+                hir::ExprWhile(..)      |
+                hir::ExprLoop(..)       |
+                hir::ExprMatch(..)      |
+                hir::ExprClosure(..)    |
+                hir::ExprBlock(..)      |
+                hir::ExprAssign(..)     |
+                hir::ExprTupField(..)   |
+                hir::ExprAddrOf(..)     |
+                hir::ExprBreak(..)      |
+                hir::ExprAgain(..)      |
+                hir::ExprRet(..)        |
+                hir::ExprInlineAsm(..)  |
+                hir::ExprRepeat(..)     |
+                hir::ExprTup(..)        => {
+                    // For these we only hash the span when debuginfo is on.
+                    (false, NodeIdHashingMode::Ignore)
+                }
+                // For the following, spans might be significant because of
+                // panic messages indicating the source location.
+                hir::ExprBinary(op, ..) => {
+                    (hcx.binop_can_panic_at_runtime(op.node), NodeIdHashingMode::Ignore)
+                }
+                hir::ExprUnary(op, _) => {
+                    (hcx.unop_can_panic_at_runtime(op), NodeIdHashingMode::Ignore)
+                }
+                hir::ExprAssignOp(op, ..) => {
+                    (hcx.binop_can_panic_at_runtime(op.node), NodeIdHashingMode::Ignore)
+                }
+                hir::ExprIndex(..) => {
+                    (true, NodeIdHashingMode::Ignore)
+                }
+                // For these we don't care about the span, but want to hash the
+                // trait in scope
+                hir::ExprMethodCall(..) |
+                hir::ExprPath(..)       |
+                hir::ExprStruct(..)     |
+                hir::ExprField(..)      => {
+                    (false, NodeIdHashingMode::HashTraitsInScope)
+                }
+            };
+
+            hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| {
+                id.hash_stable(hcx, hasher);
+            });
+
+            if spans_always_on {
+                hcx.while_hashing_spans(true, |hcx| {
+                    span.hash_stable(hcx, hasher);
+                    node.hash_stable(hcx, hasher);
+                    attrs.hash_stable(hcx, hasher);
+                });
+            } else {
+                span.hash_stable(hcx, hasher);
+                node.hash_stable(hcx, hasher);
+                attrs.hash_stable(hcx, hasher);
+            }
+        })
+    }
+}
+
+impl_stable_hash_for!(enum hir::Expr_ {
+    ExprBox(sub),
+    ExprArray(subs),
+    ExprCall(callee, args),
+    ExprMethodCall(name, ts, args),
+    ExprTup(fields),
+    ExprBinary(op, lhs, rhs),
+    ExprUnary(op, operand),
+    ExprLit(value),
+    ExprCast(expr, t),
+    ExprType(expr, t),
+    ExprIf(cond, then, els),
+    ExprWhile(cond, body, label),
+    ExprLoop(body, label, loop_src),
+    ExprMatch(matchee, arms, match_src),
+    ExprClosure(capture_clause, decl, body_id, span),
+    ExprBlock(blk),
+    ExprAssign(lhs, rhs),
+    ExprAssignOp(op, lhs, rhs),
+    ExprField(owner, field_name),
+    ExprTupField(owner, idx),
+    ExprIndex(lhs, rhs),
+    ExprPath(path),
+    ExprAddrOf(mutability, sub),
+    ExprBreak(destination, sub),
+    ExprAgain(destination),
+    ExprRet(val),
+    ExprInlineAsm(asm, inputs, outputs),
+    ExprStruct(path, fields, base),
+    ExprRepeat(val, times)
+});
+
+impl_stable_hash_for!(enum hir::LoopSource {
+    Loop,
+    WhileLet,
+    ForLoop
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::MatchSource {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        use hir::MatchSource;
+
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            MatchSource::Normal |
+            MatchSource::WhileLetDesugar |
+            MatchSource::ForLoopDesugar |
+            MatchSource::TryDesugar => {
+                // No fields to hash.
+            }
+            MatchSource::IfLetDesugar { contains_else_clause } => {
+                contains_else_clause.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl_stable_hash_for!(enum hir::CaptureClause {
+    CaptureByValue,
+    CaptureByRef
+});
+
+impl_stable_hash_for_spanned!(usize);
+
+impl_stable_hash_for!(struct hir::Destination {
+    ident,
+    target_id
+});
+
+impl_stable_hash_for_spanned!(ast::Ident);
+
+impl_stable_hash_for!(enum hir::LoopIdResult {
+    Ok(node_id),
+    Err(loop_id_error)
+});
+
+impl_stable_hash_for!(enum hir::LoopIdError {
+    OutsideLoopScope,
+    UnlabeledCfInWhileCondition,
+    UnresolvedLabel
+});
+
+impl_stable_hash_for!(enum hir::ScopeTarget {
+    Block(node_id),
+    Loop(loop_id_result)
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ast::Ident {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let ast::Ident {
+            ref name,
+            ctxt: _ // Ignore this
+        } = *self;
+
+        name.hash_stable(hcx, hasher);
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::TraitItem {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let hir::TraitItem {
+            id,
+            name,
+            ref attrs,
+            ref node,
+            span
+        } = *self;
+
+        hcx.hash_hir_item_like(attrs, |hcx| {
+            id.hash_stable(hcx, hasher);
+            name.hash_stable(hcx, hasher);
+            attrs.hash_stable(hcx, hasher);
+            node.hash_stable(hcx, hasher);
+            span.hash_stable(hcx, hasher);
+        });
+    }
+}
+
+impl_stable_hash_for!(enum hir::TraitMethod {
+    Required(name),
+    Provided(body)
+});
+
+impl_stable_hash_for!(enum hir::TraitItemKind {
+    Const(t, body),
+    Method(sig, method),
+    Type(bounds, rhs)
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::ImplItem {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let hir::ImplItem {
+            id,
+            name,
+            ref vis,
+            defaultness,
+            ref attrs,
+            ref node,
+            span
+        } = *self;
+
+        hcx.hash_hir_item_like(attrs, |hcx| {
+            id.hash_stable(hcx, hasher);
+            name.hash_stable(hcx, hasher);
+            vis.hash_stable(hcx, hasher);
+            defaultness.hash_stable(hcx, hasher);
+            attrs.hash_stable(hcx, hasher);
+            node.hash_stable(hcx, hasher);
+            span.hash_stable(hcx, hasher);
+        });
+    }
+}
+
+impl_stable_hash_for!(enum hir::ImplItemKind {
+    Const(t, body),
+    Method(sig, body),
+    Type(t)
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Visibility {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            hir::Visibility::Public |
+            hir::Visibility::Crate |
+            hir::Visibility::Inherited => {
+                // No fields to hash.
+            }
+            hir::Visibility::Restricted { ref path, id } => {
+                hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashTraitsInScope, |hcx| {
+                    id.hash_stable(hcx, hasher);
+                });
+                path.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Defaultness {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            hir::Defaultness::Final => {
+                // No fields to hash.
+            }
+            hir::Defaultness::Default { has_value } => {
+                has_value.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl_stable_hash_for!(enum hir::ImplPolarity {
+    Positive,
+    Negative
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Mod {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let hir::Mod {
+            inner,
+            // We are not hashing the IDs of the items contained in the module.
+            // This is harmless and matches the current behavior but it's not
+            // actually correct. See issue #40876.
+            item_ids: _,
+        } = *self;
+
+        inner.hash_stable(hcx, hasher);
+    }
+}
+
+impl_stable_hash_for!(struct hir::ForeignMod {
+    abi,
+    items
+});
+
+impl_stable_hash_for!(struct hir::EnumDef {
+    variants
+});
+
+impl_stable_hash_for!(struct hir::Variant_ {
+    name,
+    attrs,
+    data,
+    disr_expr
+});
+
+impl_stable_hash_for_spanned!(hir::Variant_);
+
+impl_stable_hash_for!(enum hir::UseKind {
+    Single,
+    Glob,
+    ListStem
+});
+
+impl_stable_hash_for!(struct hir::StructField {
+    span,
+    name,
+    vis,
+    id,
+    ty,
+    attrs
+});
+
+impl_stable_hash_for!(enum hir::VariantData {
+    Struct(fields, id),
+    Tuple(fields, id),
+    Unit(id)
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::Item {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let node_id_hashing_mode = match self.node {
+            hir::ItemExternCrate(..) |
+            hir::ItemStatic(..)      |
+            hir::ItemConst(..)       |
+            hir::ItemFn(..)          |
+            hir::ItemMod(..)         |
+            hir::ItemForeignMod(..)  |
+            hir::ItemTy(..)          |
+            hir::ItemEnum(..)        |
+            hir::ItemStruct(..)      |
+            hir::ItemUnion(..)       |
+            hir::ItemTrait(..)       |
+            hir::ItemDefaultImpl(..) |
+            hir::ItemImpl(..)        => {
+                NodeIdHashingMode::Ignore
+            }
+            hir::ItemUse(..) => {
+                NodeIdHashingMode::HashTraitsInScope
+            }
+        };
+
+        let hir::Item {
+            name,
+            ref attrs,
+            id,
+            ref node,
+            ref vis,
+            span
+        } = *self;
+
+        hcx.hash_hir_item_like(attrs, |hcx| {
+            hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| {
+                id.hash_stable(hcx, hasher);
+            });
+            name.hash_stable(hcx, hasher);
+            attrs.hash_stable(hcx, hasher);
+            node.hash_stable(hcx, hasher);
+            vis.hash_stable(hcx, hasher);
+            span.hash_stable(hcx, hasher);
+        });
+    }
+}
+
+impl_stable_hash_for!(enum hir::Item_ {
+    ItemExternCrate(name),
+    ItemUse(path, use_kind),
+    ItemStatic(ty, mutability, body_id),
+    ItemConst(ty, body_id),
+    ItemFn(fn_decl, unsafety, constness, abi, generics, body_id),
+    ItemMod(module),
+    ItemForeignMod(foreign_mod),
+    ItemTy(ty, generics),
+    ItemEnum(enum_def, generics),
+    ItemStruct(variant_data, generics),
+    ItemUnion(variant_data, generics),
+    ItemTrait(unsafety, generics, bounds, item_refs),
+    ItemDefaultImpl(unsafety, trait_ref),
+    ItemImpl(unsafety, impl_polarity, generics, trait_ref, ty, impl_item_refs)
+});
+
+impl_stable_hash_for!(struct hir::TraitItemRef {
+    id,
+    name,
+    kind,
+    span,
+    defaultness
+});
+
+impl_stable_hash_for!(struct hir::ImplItemRef {
+    id,
+    name,
+    kind,
+    span,
+    vis,
+    defaultness
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::AssociatedItemKind {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            hir::AssociatedItemKind::Const |
+            hir::AssociatedItemKind::Type => {
+                // No fields to hash.
+            }
+            hir::AssociatedItemKind::Method { has_self } => {
+                has_self.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl_stable_hash_for!(struct hir::ForeignItem {
+    name,
+    attrs,
+    node,
+    id,
+    span,
+    vis
+});
+
+impl_stable_hash_for!(enum hir::ForeignItem_ {
+    ForeignItemFn(fn_decl, arg_names, generics),
+    ForeignItemStatic(ty, is_mutbl)
+});
+
+impl_stable_hash_for!(enum hir::Stmt_ {
+    StmtDecl(decl, id),
+    StmtExpr(expr, id),
+    StmtSemi(expr, id)
+});
+
+impl_stable_hash_for!(struct hir::Arg {
+    pat,
+    id
+});
+
+impl_stable_hash_for!(struct hir::Body {
+    arguments,
+    value
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::BodyId {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        if hcx.hash_bodies() {
+            hcx.tcx().hir.body(*self).hash_stable(hcx, hasher);
+        }
+    }
+}
+
+impl_stable_hash_for!(struct hir::InlineAsmOutput {
+    constraint,
+    is_rw,
+    is_indirect
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::InlineAsm {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let hir::InlineAsm {
+            asm,
+            asm_str_style,
+            ref outputs,
+            ref inputs,
+            ref clobbers,
+            volatile,
+            alignstack,
+            dialect,
+            ctxt: _, // This is used for error reporting
+        } = *self;
+
+        asm.hash_stable(hcx, hasher);
+        asm_str_style.hash_stable(hcx, hasher);
+        outputs.hash_stable(hcx, hasher);
+        inputs.hash_stable(hcx, hasher);
+        clobbers.hash_stable(hcx, hasher);
+        volatile.hash_stable(hcx, hasher);
+        alignstack.hash_stable(hcx, hasher);
+        dialect.hash_stable(hcx, hasher);
+    }
+}
+
+impl_stable_hash_for!(enum hir::def::CtorKind {
+    Fn,
+    Const,
+    Fictive
+});
+
+impl_stable_hash_for!(enum hir::def::Def {
+    Mod(def_id),
+    Struct(def_id),
+    Union(def_id),
+    Enum(def_id),
+    Variant(def_id),
+    Trait(def_id),
+    TyAlias(def_id),
+    AssociatedTy(def_id),
+    PrimTy(prim_ty),
+    TyParam(def_id),
+    SelfTy(trait_def_id, impl_def_id),
+    Fn(def_id),
+    Const(def_id),
+    Static(def_id, is_mutbl),
+    StructCtor(def_id, ctor_kind),
+    VariantCtor(def_id, ctor_kind),
+    Method(def_id),
+    AssociatedConst(def_id),
+    Local(def_id),
+    Upvar(def_id, index, expr_id),
+    Label(node_id),
+    Macro(def_id, macro_kind),
+    Err
+});
+
+impl_stable_hash_for!(enum hir::Mutability {
+    MutMutable,
+    MutImmutable
+});
+
+
+impl_stable_hash_for!(enum hir::Unsafety {
+    Unsafe,
+    Normal
+});
+
+
+impl_stable_hash_for!(enum hir::Constness {
+    Const,
+    NotConst
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for hir::def_id::DefIndex {
+
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        DefId::local(*self).hash_stable(hcx, hasher);
+    }
+}
+
+impl_stable_hash_for!(struct hir::def::Export {
+    name,
+    def,
+    span
+});
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs
new file mode 100644 (file)
index 0000000..401f7e1
--- /dev/null
@@ -0,0 +1,407 @@
+// Copyright 2017 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.
+
+//! This module contains `HashStable` implementations for various MIR data
+//! types in no particular order.
+
+use ich::StableHashingContext;
+use mir;
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
+                                           StableHasherResult};
+use std::mem;
+
+
+impl_stable_hash_for!(struct mir::SourceInfo { span, scope });
+impl_stable_hash_for!(enum mir::Mutability { Mut, Not });
+impl_stable_hash_for!(enum mir::BorrowKind { Shared, Unique, Mut });
+impl_stable_hash_for!(enum mir::LocalKind { Var, Temp, Arg, ReturnPointer });
+impl_stable_hash_for!(struct mir::LocalDecl<'tcx> { mutability, ty, name, source_info });
+impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref });
+impl_stable_hash_for!(struct mir::BasicBlockData<'tcx> { statements, terminator, is_cleanup });
+impl_stable_hash_for!(struct mir::Terminator<'tcx> { source_info, kind });
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Local {
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        use rustc_data_structures::indexed_vec::Idx;
+        self.index().hash_stable(hcx, hasher);
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::BasicBlock {
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        use rustc_data_structures::indexed_vec::Idx;
+        self.index().hash_stable(hcx, hasher);
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Field {
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        use rustc_data_structures::indexed_vec::Idx;
+        self.index().hash_stable(hcx, hasher);
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::VisibilityScope {
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        use rustc_data_structures::indexed_vec::Idx;
+        self.index().hash_stable(hcx, hasher);
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Promoted {
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        use rustc_data_structures::indexed_vec::Idx;
+        self.index().hash_stable(hcx, hasher);
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::TerminatorKind<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+
+        match *self {
+            mir::TerminatorKind::Goto { ref target } => {
+                target.hash_stable(hcx, hasher);
+            }
+            mir::TerminatorKind::SwitchInt { ref discr,
+                                             switch_ty,
+                                             ref values,
+                                             ref targets } => {
+                discr.hash_stable(hcx, hasher);
+                switch_ty.hash_stable(hcx, hasher);
+                values.hash_stable(hcx, hasher);
+                targets.hash_stable(hcx, hasher);
+            }
+            mir::TerminatorKind::Resume |
+            mir::TerminatorKind::Return |
+            mir::TerminatorKind::Unreachable => {}
+            mir::TerminatorKind::Drop { ref location, target, unwind } => {
+                location.hash_stable(hcx, hasher);
+                target.hash_stable(hcx, hasher);
+                unwind.hash_stable(hcx, hasher);
+            }
+            mir::TerminatorKind::DropAndReplace { ref location,
+                                                  ref value,
+                                                  target,
+                                                  unwind, } => {
+                location.hash_stable(hcx, hasher);
+                value.hash_stable(hcx, hasher);
+                target.hash_stable(hcx, hasher);
+                unwind.hash_stable(hcx, hasher);
+            }
+            mir::TerminatorKind::Call { ref func,
+                                        ref args,
+                                        ref destination,
+                                        cleanup } => {
+                func.hash_stable(hcx, hasher);
+                args.hash_stable(hcx, hasher);
+                destination.hash_stable(hcx, hasher);
+                cleanup.hash_stable(hcx, hasher);
+            }
+            mir::TerminatorKind::Assert { ref cond,
+                                          expected,
+                                          ref msg,
+                                          target,
+                                          cleanup } => {
+                cond.hash_stable(hcx, hasher);
+                expected.hash_stable(hcx, hasher);
+                msg.hash_stable(hcx, hasher);
+                target.hash_stable(hcx, hasher);
+                cleanup.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::AssertMessage<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+
+        match *self {
+            mir::AssertMessage::BoundsCheck { ref len, ref index } => {
+                len.hash_stable(hcx, hasher);
+                index.hash_stable(hcx, hasher);
+            }
+            mir::AssertMessage::Math(ref const_math_err) => {
+                const_math_err.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl_stable_hash_for!(struct mir::Statement<'tcx> { source_info, kind });
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::StatementKind<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+
+        match *self {
+            mir::StatementKind::Assign(ref lvalue, ref rvalue) => {
+                lvalue.hash_stable(hcx, hasher);
+                rvalue.hash_stable(hcx, hasher);
+            }
+            mir::StatementKind::SetDiscriminant { ref lvalue, variant_index } => {
+                lvalue.hash_stable(hcx, hasher);
+                variant_index.hash_stable(hcx, hasher);
+            }
+            mir::StatementKind::StorageLive(ref lvalue) |
+            mir::StatementKind::StorageDead(ref lvalue) => {
+                lvalue.hash_stable(hcx, hasher);
+            }
+            mir::StatementKind::Nop => {}
+            mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
+                asm.hash_stable(hcx, hasher);
+                outputs.hash_stable(hcx, hasher);
+                inputs.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Lvalue<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            mir::Lvalue::Local(ref local) => {
+                local.hash_stable(hcx, hasher);
+            }
+            mir::Lvalue::Static(ref statik) => {
+                statik.hash_stable(hcx, hasher);
+            }
+            mir::Lvalue::Projection(ref lvalue_projection) => {
+                lvalue_projection.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl<'a, 'tcx, B, V> HashStable<StableHashingContext<'a, 'tcx>> for mir::Projection<'tcx, B, V>
+    where B: HashStable<StableHashingContext<'a, 'tcx>>,
+          V: HashStable<StableHashingContext<'a, 'tcx>>
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let mir::Projection {
+            ref base,
+            ref elem,
+        } = *self;
+
+        base.hash_stable(hcx, hasher);
+        elem.hash_stable(hcx, hasher);
+    }
+}
+
+impl<'a, 'tcx, V> HashStable<StableHashingContext<'a, 'tcx>> for mir::ProjectionElem<'tcx, V>
+    where V: HashStable<StableHashingContext<'a, 'tcx>>
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            mir::ProjectionElem::Deref => {}
+            mir::ProjectionElem::Field(field, ty) => {
+                field.hash_stable(hcx, hasher);
+                ty.hash_stable(hcx, hasher);
+            }
+            mir::ProjectionElem::Index(ref value) => {
+                value.hash_stable(hcx, hasher);
+            }
+            mir::ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
+                offset.hash_stable(hcx, hasher);
+                min_length.hash_stable(hcx, hasher);
+                from_end.hash_stable(hcx, hasher);
+            }
+            mir::ProjectionElem::Subslice { from, to } => {
+                from.hash_stable(hcx, hasher);
+                to.hash_stable(hcx, hasher);
+            }
+            mir::ProjectionElem::Downcast(adt_def, variant) => {
+                adt_def.hash_stable(hcx, hasher);
+                variant.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope });
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Operand<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+
+        match *self {
+            mir::Operand::Consume(ref lvalue) => {
+                lvalue.hash_stable(hcx, hasher);
+            }
+            mir::Operand::Constant(ref constant) => {
+                constant.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Rvalue<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+
+        match *self {
+            mir::Rvalue::Use(ref operand) => {
+                operand.hash_stable(hcx, hasher);
+            }
+            mir::Rvalue::Repeat(ref operand, ref val) => {
+                operand.hash_stable(hcx, hasher);
+                val.hash_stable(hcx, hasher);
+            }
+            mir::Rvalue::Ref(region, borrow_kind, ref lvalue) => {
+                region.hash_stable(hcx, hasher);
+                borrow_kind.hash_stable(hcx, hasher);
+                lvalue.hash_stable(hcx, hasher);
+            }
+            mir::Rvalue::Len(ref lvalue) => {
+                lvalue.hash_stable(hcx, hasher);
+            }
+            mir::Rvalue::Cast(cast_kind, ref operand, ty) => {
+                cast_kind.hash_stable(hcx, hasher);
+                operand.hash_stable(hcx, hasher);
+                ty.hash_stable(hcx, hasher);
+            }
+            mir::Rvalue::BinaryOp(op, ref operand1, ref operand2) |
+            mir::Rvalue::CheckedBinaryOp(op, ref operand1, ref operand2) => {
+                op.hash_stable(hcx, hasher);
+                operand1.hash_stable(hcx, hasher);
+                operand2.hash_stable(hcx, hasher);
+            }
+            mir::Rvalue::UnaryOp(op, ref operand) => {
+                op.hash_stable(hcx, hasher);
+                operand.hash_stable(hcx, hasher);
+            }
+            mir::Rvalue::Discriminant(ref lvalue) => {
+                lvalue.hash_stable(hcx, hasher);
+            }
+            mir::Rvalue::Box(ty) => {
+                ty.hash_stable(hcx, hasher);
+            }
+            mir::Rvalue::Aggregate(ref kind, ref operands) => {
+                kind.hash_stable(hcx, hasher);
+                operands.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl_stable_hash_for!(enum mir::CastKind {
+    Misc,
+    ReifyFnPointer,
+    ClosureFnPointer,
+    UnsafeFnPointer,
+    Unsize
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::AggregateKind<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            mir::AggregateKind::Tuple => {}
+            mir::AggregateKind::Array(t) => {
+                t.hash_stable(hcx, hasher);
+            }
+            mir::AggregateKind::Adt(adt_def, idx, substs, active_field) => {
+                adt_def.hash_stable(hcx, hasher);
+                idx.hash_stable(hcx, hasher);
+                substs.hash_stable(hcx, hasher);
+                active_field.hash_stable(hcx, hasher);
+            }
+            mir::AggregateKind::Closure(def_id, ref substs) => {
+                def_id.hash_stable(hcx, hasher);
+                substs.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl_stable_hash_for!(enum mir::BinOp {
+    Add,
+    Sub,
+    Mul,
+    Div,
+    Rem,
+    BitXor,
+    BitAnd,
+    BitOr,
+    Shl,
+    Shr,
+    Eq,
+    Lt,
+    Le,
+    Ne,
+    Ge,
+    Gt
+});
+
+impl_stable_hash_for!(enum mir::UnOp {
+    Not,
+    Neg
+});
+
+
+impl_stable_hash_for!(struct mir::Constant<'tcx> { span, ty, literal });
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for mir::Literal<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            mir::Literal::Item { def_id, substs } => {
+                def_id.hash_stable(hcx, hasher);
+                substs.hash_stable(hcx, hasher);
+            }
+            mir::Literal::Value { ref value } => {
+                value.hash_stable(hcx, hasher);
+            }
+            mir::Literal::Promoted { index } => {
+                index.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl_stable_hash_for!(struct mir::Location { block, statement_index });
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
new file mode 100644 (file)
index 0000000..2673450
--- /dev/null
@@ -0,0 +1,301 @@
+// Copyright 2017 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.
+
+//! This module contains `HashStable` implementations for various data types
+//! from libsyntax in no particular order.
+
+use ich::StableHashingContext;
+
+use std::hash as std_hash;
+use std::mem;
+
+use syntax::ast;
+use syntax::parse::token;
+use syntax::tokenstream;
+use syntax_pos::Span;
+
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
+                                           StableHasherResult};
+use rustc_data_structures::accumulate_vec::AccumulateVec;
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::syntax::symbol::InternedString {
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let s: &str = &**self;
+        s.hash_stable(hcx, hasher);
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ast::Name {
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        self.as_str().hash_stable(hcx, hasher);
+    }
+}
+
+impl_stable_hash_for!(enum ::syntax::ast::AsmDialect {
+    Att,
+    Intel
+});
+
+impl_stable_hash_for!(enum ::syntax::ext::base::MacroKind {
+    Bang,
+    Attr,
+    Derive
+});
+
+
+impl_stable_hash_for!(enum ::syntax::abi::Abi {
+    Cdecl,
+    Stdcall,
+    Fastcall,
+    Vectorcall,
+    Aapcs,
+    Win64,
+    SysV64,
+    PtxKernel,
+    Msp430Interrupt,
+    X86Interrupt,
+    Rust,
+    C,
+    System,
+    RustIntrinsic,
+    RustCall,
+    PlatformIntrinsic,
+    Unadjusted
+});
+
+impl_stable_hash_for!(struct ::syntax::attr::Deprecation { since, note });
+impl_stable_hash_for!(struct ::syntax::attr::Stability { level, feature, rustc_depr });
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::syntax::attr::StabilityLevel {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue } => {
+                reason.hash_stable(hcx, hasher);
+                issue.hash_stable(hcx, hasher);
+            }
+            ::syntax::attr::StabilityLevel::Stable { ref since } => {
+                since.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl_stable_hash_for!(struct ::syntax::attr::RustcDeprecation { since, reason });
+
+
+impl_stable_hash_for!(enum ::syntax::attr::IntType {
+    SignedInt(int_ty),
+    UnsignedInt(uint_ty)
+});
+
+impl_stable_hash_for!(enum ::syntax::ast::LitIntType {
+    Signed(int_ty),
+    Unsigned(int_ty),
+    Unsuffixed
+});
+
+impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
+impl_stable_hash_for!(enum ::syntax::ast::LitKind {
+    Str(value, style),
+    ByteStr(value),
+    Byte(value),
+    Char(value),
+    Int(value, lit_int_type),
+    Float(value, float_ty),
+    FloatUnsuffixed(value),
+    Bool(value)
+});
+
+impl_stable_hash_for!(enum ::syntax::ast::IntTy { Is, I8, I16, I32, I64, I128 });
+impl_stable_hash_for!(enum ::syntax::ast::UintTy { Us, U8, U16, U32, U64, U128 });
+impl_stable_hash_for!(enum ::syntax::ast::FloatTy { F32, F64 });
+impl_stable_hash_for!(enum ::syntax::ast::Unsafety { Unsafe, Normal });
+impl_stable_hash_for!(enum ::syntax::ast::Constness { Const, NotConst });
+impl_stable_hash_for!(enum ::syntax::ast::Defaultness { Default, Final });
+impl_stable_hash_for!(struct ::syntax::ast::Lifetime { id, span, name });
+impl_stable_hash_for!(enum ::syntax::ast::StrStyle { Cooked, Raw(pounds) });
+impl_stable_hash_for!(enum ::syntax::ast::AttrStyle { Outer, Inner });
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for [ast::Attribute] {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        // Some attributes are always ignored during hashing.
+        let filtered: AccumulateVec<[&ast::Attribute; 8]> = self
+            .iter()
+            .filter(|attr| {
+                !attr.is_sugared_doc &&
+                attr.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true)
+            })
+            .collect();
+
+        filtered.len().hash_stable(hcx, hasher);
+        for attr in filtered {
+            attr.hash_stable(hcx, hasher);
+        }
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ast::Attribute {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        // Make sure that these have been filtered out.
+        debug_assert!(self.name().map(|name| !hcx.is_ignored_attr(name)).unwrap_or(true));
+        debug_assert!(!self.is_sugared_doc);
+
+        let ast::Attribute {
+            id: _,
+            style,
+            ref path,
+            ref tokens,
+            is_sugared_doc: _,
+            span,
+        } = *self;
+
+        style.hash_stable(hcx, hasher);
+        path.segments.len().hash_stable(hcx, hasher);
+        for segment in &path.segments {
+            segment.identifier.name.hash_stable(hcx, hasher);
+        }
+        for tt in tokens.trees() {
+            tt.hash_stable(hcx, hasher);
+        }
+        span.hash_stable(hcx, hasher);
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for tokenstream::TokenTree {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            tokenstream::TokenTree::Token(span, ref token) => {
+                span.hash_stable(hcx, hasher);
+                hash_token(token, hcx, hasher, span);
+            }
+            tokenstream::TokenTree::Delimited(span, ref delimited) => {
+                span.hash_stable(hcx, hasher);
+                std_hash::Hash::hash(&delimited.delim, hasher);
+                for sub_tt in delimited.stream().trees() {
+                    sub_tt.hash_stable(hcx, hasher);
+                }
+            }
+        }
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for tokenstream::TokenStream {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        for sub_tt in self.trees() {
+            sub_tt.hash_stable(hcx, hasher);
+        }
+    }
+}
+
+fn hash_token<'a, 'tcx, W: StableHasherResult>(token: &token::Token,
+                                               hcx: &mut StableHashingContext<'a, 'tcx>,
+                                               hasher: &mut StableHasher<W>,
+                                               error_reporting_span: Span) {
+    mem::discriminant(token).hash_stable(hcx, hasher);
+    match *token {
+        token::Token::Eq |
+        token::Token::Lt |
+        token::Token::Le |
+        token::Token::EqEq |
+        token::Token::Ne |
+        token::Token::Ge |
+        token::Token::Gt |
+        token::Token::AndAnd |
+        token::Token::OrOr |
+        token::Token::Not |
+        token::Token::Tilde |
+        token::Token::At |
+        token::Token::Dot |
+        token::Token::DotDot |
+        token::Token::DotDotDot |
+        token::Token::Comma |
+        token::Token::Semi |
+        token::Token::Colon |
+        token::Token::ModSep |
+        token::Token::RArrow |
+        token::Token::LArrow |
+        token::Token::FatArrow |
+        token::Token::Pound |
+        token::Token::Dollar |
+        token::Token::Question |
+        token::Token::Underscore |
+        token::Token::Whitespace |
+        token::Token::Comment |
+        token::Token::Eof => {}
+
+        token::Token::BinOp(bin_op_token) |
+        token::Token::BinOpEq(bin_op_token) => {
+            std_hash::Hash::hash(&bin_op_token, hasher);
+        }
+
+        token::Token::OpenDelim(delim_token) |
+        token::Token::CloseDelim(delim_token) => {
+            std_hash::Hash::hash(&delim_token, hasher);
+        }
+        token::Token::Literal(ref lit, ref opt_name) => {
+            mem::discriminant(lit).hash_stable(hcx, hasher);
+            match *lit {
+                token::Lit::Byte(val) |
+                token::Lit::Char(val) |
+                token::Lit::Integer(val) |
+                token::Lit::Float(val) |
+                token::Lit::Str_(val) |
+                token::Lit::ByteStr(val) => val.hash_stable(hcx, hasher),
+                token::Lit::StrRaw(val, n) |
+                token::Lit::ByteStrRaw(val, n) => {
+                    val.hash_stable(hcx, hasher);
+                    n.hash_stable(hcx, hasher);
+                }
+            };
+            opt_name.hash_stable(hcx, hasher);
+        }
+
+        token::Token::Ident(ident) |
+        token::Token::Lifetime(ident) |
+        token::Token::SubstNt(ident) => ident.name.hash_stable(hcx, hasher),
+
+        token::Token::Interpolated(ref non_terminal) => {
+            // FIXME(mw): This could be implemented properly. It's just a
+            //            lot of work, since we would need to hash the AST
+            //            in a stable way, in addition to the HIR.
+            //            Since this is hardly used anywhere, just emit a
+            //            warning for now.
+            if hcx.tcx().sess.opts.debugging_opts.incremental.is_some() {
+                let msg = format!("Quasi-quoting might make incremental \
+                                   compilation very inefficient: {:?}",
+                                  non_terminal);
+                hcx.tcx().sess.span_warn(error_reporting_span, &msg[..]);
+            }
+
+            std_hash::Hash::hash(non_terminal, hasher);
+        }
+
+        token::Token::DocComment(val) |
+        token::Token::Shebang(val) => val.hash_stable(hcx, hasher),
+    }
+}
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
new file mode 100644 (file)
index 0000000..7b6f3af
--- /dev/null
@@ -0,0 +1,415 @@
+// Copyright 2017 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.
+
+//! This module contains `HashStable` implementations for various data types
+//! from rustc::ty in no particular order.
+
+use ich::StableHashingContext;
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
+                                           StableHasherResult};
+use std::hash as std_hash;
+use std::mem;
+use ty;
+
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Ty<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let type_hash = hcx.tcx().type_id_hash(*self);
+        type_hash.hash_stable(hcx, hasher);
+    }
+}
+
+impl_stable_hash_for!(struct ty::ItemSubsts<'tcx> { substs });
+
+impl<'a, 'tcx, T> HashStable<StableHashingContext<'a, 'tcx>> for ty::Slice<T>
+    where T: HashStable<StableHashingContext<'a, 'tcx>> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        (&**self).hash_stable(hcx, hasher);
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::subst::Kind<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        self.as_type().hash_stable(hcx, hasher);
+        self.as_region().hash_stable(hcx, hasher);
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Region {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            ty::ReErased |
+            ty::ReStatic |
+            ty::ReEmpty => {
+                // No variant fields to hash for these ...
+            }
+            ty::ReLateBound(db, ty::BrAnon(i)) => {
+                db.depth.hash_stable(hcx, hasher);
+                i.hash_stable(hcx, hasher);
+            }
+            ty::ReEarlyBound(ty::EarlyBoundRegion { index, name }) => {
+                index.hash_stable(hcx, hasher);
+                name.hash_stable(hcx, hasher);
+            }
+            ty::ReLateBound(..) |
+            ty::ReFree(..) |
+            ty::ReScope(..) |
+            ty::ReVar(..) |
+            ty::ReSkolemized(..) => {
+                bug!("TypeIdHasher: unexpected region {:?}", *self)
+            }
+        }
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::adjustment::AutoBorrow<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            ty::adjustment::AutoBorrow::Ref(ref region, mutability) => {
+                region.hash_stable(hcx, hasher);
+                mutability.hash_stable(hcx, hasher);
+            }
+            ty::adjustment::AutoBorrow::RawPtr(mutability) => {
+                mutability.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::adjustment::Adjust<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            ty::adjustment::Adjust::NeverToAny |
+            ty::adjustment::Adjust::ReifyFnPointer |
+            ty::adjustment::Adjust::UnsafeFnPointer |
+            ty::adjustment::Adjust::ClosureFnPointer |
+            ty::adjustment::Adjust::MutToConstPointer => {}
+            ty::adjustment::Adjust::DerefRef { autoderefs, ref autoref, unsize } => {
+                autoderefs.hash_stable(hcx, hasher);
+                autoref.hash_stable(hcx, hasher);
+                unsize.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl_stable_hash_for!(struct ty::adjustment::Adjustment<'tcx> { kind, target });
+impl_stable_hash_for!(struct ty::MethodCall { expr_id, autoderef });
+impl_stable_hash_for!(struct ty::MethodCallee<'tcx> { def_id, ty, substs });
+impl_stable_hash_for!(struct ty::UpvarId { var_id, closure_expr_id });
+impl_stable_hash_for!(struct ty::UpvarBorrow<'tcx> { kind, region });
+
+impl_stable_hash_for!(enum ty::BorrowKind {
+    ImmBorrow,
+    UniqueImmBorrow,
+    MutBorrow
+});
+
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::UpvarCapture<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            ty::UpvarCapture::ByValue => {}
+            ty::UpvarCapture::ByRef(ref up_var_borrow) => {
+                up_var_borrow.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl_stable_hash_for!(struct ty::FnSig<'tcx> {
+    inputs_and_output,
+    variadic,
+    unsafety,
+    abi
+});
+
+impl<'a, 'tcx, T> HashStable<StableHashingContext<'a, 'tcx>> for ty::Binder<T>
+    where T: HashStable<StableHashingContext<'a, 'tcx>> + ty::fold::TypeFoldable<'tcx>
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        hcx.tcx().anonymize_late_bound_regions(self).0.hash_stable(hcx, hasher);
+    }
+}
+
+impl_stable_hash_for!(enum ty::ClosureKind { Fn, FnMut, FnOnce });
+
+impl_stable_hash_for!(enum ty::Visibility {
+    Public,
+    Restricted(def_id),
+    Invisible
+});
+
+impl_stable_hash_for!(struct ty::TraitRef<'tcx> { def_id, substs });
+impl_stable_hash_for!(struct ty::TraitPredicate<'tcx> { trait_ref });
+impl_stable_hash_for!(tuple_struct ty::EquatePredicate<'tcx> { t1, t2 });
+
+impl<'a, 'tcx, A, B> HashStable<StableHashingContext<'a, 'tcx>> for ty::OutlivesPredicate<A, B>
+    where A: HashStable<StableHashingContext<'a, 'tcx>>,
+          B: HashStable<StableHashingContext<'a, 'tcx>>,
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let ty::OutlivesPredicate(ref a, ref b) = *self;
+        a.hash_stable(hcx, hasher);
+        b.hash_stable(hcx, hasher);
+    }
+}
+
+impl_stable_hash_for!(struct ty::ProjectionPredicate<'tcx> { projection_ty, ty });
+impl_stable_hash_for!(struct ty::ProjectionTy<'tcx> { trait_ref, item_name });
+
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Predicate<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            ty::Predicate::Trait(ref pred) => {
+                pred.hash_stable(hcx, hasher);
+            }
+            ty::Predicate::Equate(ref pred) => {
+                pred.hash_stable(hcx, hasher);
+            }
+            ty::Predicate::RegionOutlives(ref pred) => {
+                pred.hash_stable(hcx, hasher);
+            }
+            ty::Predicate::TypeOutlives(ref pred) => {
+                pred.hash_stable(hcx, hasher);
+            }
+            ty::Predicate::Projection(ref pred) => {
+                pred.hash_stable(hcx, hasher);
+            }
+            ty::Predicate::WellFormed(ty) => {
+                ty.hash_stable(hcx, hasher);
+            }
+            ty::Predicate::ObjectSafe(def_id) => {
+                def_id.hash_stable(hcx, hasher);
+            }
+            ty::Predicate::ClosureKind(def_id, closure_kind) => {
+                def_id.hash_stable(hcx, hasher);
+                closure_kind.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::AdtFlags {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          _: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        std_hash::Hash::hash(self, hasher);
+    }
+}
+
+impl_stable_hash_for!(struct ty::VariantDef {
+    did,
+    name,
+    discr,
+    fields,
+    ctor_kind
+});
+
+impl_stable_hash_for!(enum ty::VariantDiscr {
+    Explicit(def_id),
+    Relative(distance)
+});
+
+impl_stable_hash_for!(struct ty::FieldDef {
+    did,
+    name,
+    vis
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>>
+for ::middle::const_val::ConstVal<'tcx> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        use middle::const_val::ConstVal;
+
+        mem::discriminant(self).hash_stable(hcx, hasher);
+
+        match *self {
+            ConstVal::Float(ref value) => {
+                value.hash_stable(hcx, hasher);
+            }
+            ConstVal::Integral(ref value) => {
+                value.hash_stable(hcx, hasher);
+            }
+            ConstVal::Str(ref value) => {
+                value.hash_stable(hcx, hasher);
+            }
+            ConstVal::ByteStr(ref value) => {
+                value.hash_stable(hcx, hasher);
+            }
+            ConstVal::Bool(value) => {
+                value.hash_stable(hcx, hasher);
+            }
+            ConstVal::Function(def_id, substs) => {
+                def_id.hash_stable(hcx, hasher);
+                substs.hash_stable(hcx, hasher);
+            }
+            ConstVal::Struct(ref _name_value_map) => {
+                // BTreeMap<ast::Name, ConstVal<'tcx>>),
+                panic!("Ordering still unstable")
+            }
+            ConstVal::Tuple(ref value) => {
+                value.hash_stable(hcx, hasher);
+            }
+            ConstVal::Array(ref value) => {
+                value.hash_stable(hcx, hasher);
+            }
+            ConstVal::Repeat(ref value, times) => {
+                value.hash_stable(hcx, hasher);
+                times.hash_stable(hcx, hasher);
+            }
+            ConstVal::Char(value) => {
+                value.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
+
+
+impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
+    parent,
+    predicates
+});
+
+impl_stable_hash_for!(enum ty::Variance {
+    Covariant,
+    Invariant,
+    Contravariant,
+    Bivariant
+});
+
+impl_stable_hash_for!(enum ty::adjustment::CustomCoerceUnsized {
+    Struct(index)
+});
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::Generics {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let ty::Generics {
+            parent,
+            parent_regions,
+            parent_types,
+            ref regions,
+            ref types,
+
+            // Reverse map to each `TypeParameterDef`'s `index` field, from
+            // `def_id.index` (`def_id.krate` is the same as the item's).
+            type_param_to_index: _, // Don't hash this
+            has_self,
+        } = *self;
+
+        parent.hash_stable(hcx, hasher);
+        parent_regions.hash_stable(hcx, hasher);
+        parent_types.hash_stable(hcx, hasher);
+        regions.hash_stable(hcx, hasher);
+        types.hash_stable(hcx, hasher);
+        has_self.hash_stable(hcx, hasher);
+    }
+}
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ty::RegionParameterDef {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let ty::RegionParameterDef {
+            name,
+            def_id,
+            index,
+            issue_32330: _,
+            pure_wrt_drop
+        } = *self;
+
+        name.hash_stable(hcx, hasher);
+        def_id.hash_stable(hcx, hasher);
+        index.hash_stable(hcx, hasher);
+        pure_wrt_drop.hash_stable(hcx, hasher);
+    }
+}
+
+impl_stable_hash_for!(struct ty::TypeParameterDef {
+    name,
+    def_id,
+    index,
+    has_default,
+    object_lifetime_default,
+    pure_wrt_drop
+});
+
+
+impl<'a, 'tcx, T> HashStable<StableHashingContext<'a, 'tcx>>
+for ::middle::resolve_lifetime::Set1<T>
+    where T: HashStable<StableHashingContext<'a, 'tcx>>
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        use middle::resolve_lifetime::Set1;
+
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            Set1::Empty |
+            Set1::Many => {
+                // Nothing to do.
+            }
+            Set1::One(ref value) => {
+                value.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
+
+impl_stable_hash_for!(enum ::middle::resolve_lifetime::Region {
+    Static,
+    EarlyBound(index, decl),
+    LateBound(db_index, decl),
+    LateBoundAnon(db_index, anon_index),
+    Free(call_site_scope_data, decl)
+});
+
+impl_stable_hash_for!(struct ::middle::region::CallSiteScopeData {
+    fn_id,
+    body_id
+});
+
+impl_stable_hash_for!(struct ty::DebruijnIndex {
+    depth
+});
index 209953f3c686b85b99c1f136d90a1bf6def1924c..f0601a0efabf89e87390c67498c3e6c436d6a48d 100644 (file)
@@ -8,13 +8,23 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! ICH - Incremental Compilation Hash
+
 pub use self::fingerprint::Fingerprint;
 pub use self::def_path_hash::DefPathHashes;
 pub use self::caching_codemap_view::CachingCodemapView;
+pub use self::hcx::{StableHashingContext, NodeIdHashingMode};
 
 mod fingerprint;
 mod def_path_hash;
 mod caching_codemap_view;
+mod hcx;
+
+mod impls_const_math;
+mod impls_hir;
+mod impls_mir;
+mod impls_ty;
+mod impls_syntax;
 
 pub const ATTR_DIRTY: &'static str = "rustc_dirty";
 pub const ATTR_CLEAN: &'static str = "rustc_clean";
 pub const ATTR_CLEAN_METADATA: &'static str = "rustc_metadata_clean";
 pub const ATTR_IF_THIS_CHANGED: &'static str = "rustc_if_this_changed";
 pub const ATTR_THEN_THIS_WOULD_NEED: &'static str = "rustc_then_this_would_need";
+pub const ATTR_PARTITION_REUSED: &'static str = "rustc_partition_reused";
+pub const ATTR_PARTITION_TRANSLATED: &'static str = "rustc_partition_translated";
+
+
+pub const DEP_GRAPH_ASSERT_ATTRS: &'static [&'static str] = &[
+    ATTR_IF_THIS_CHANGED,
+    ATTR_THEN_THIS_WOULD_NEED,
+    ATTR_DIRTY,
+    ATTR_CLEAN,
+    ATTR_DIRTY_METADATA,
+    ATTR_CLEAN_METADATA,
+    ATTR_PARTITION_REUSED,
+    ATTR_PARTITION_TRANSLATED,
+];
 
 pub const IGNORED_ATTRIBUTES: &'static [&'static str] = &[
     "cfg",
@@ -30,5 +54,7 @@
     ATTR_DIRTY,
     ATTR_CLEAN,
     ATTR_DIRTY_METADATA,
-    ATTR_CLEAN_METADATA
+    ATTR_CLEAN_METADATA,
+    ATTR_PARTITION_REUSED,
+    ATTR_PARTITION_TRANSLATED,
 ];
index 294f80d7d2301b570787e74cb5b6db3cbf4ccc96..3b002fd4dfc1a210e8445eb9e2cd8469beac0c68 100644 (file)
@@ -41,6 +41,7 @@
 #![feature(specialization)]
 #![feature(staged_api)]
 #![feature(unboxed_closures)]
+#![feature(discriminant_value)]
 
 extern crate arena;
 extern crate core;
index 76dca1bb5b64941b61d989de99b18515c84c47dd..c18e585f79553bd1791ca22614efb51701389829 100644 (file)
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-tidy-linelength
+
 macro_rules! enum_from_u32 {
     ($(#[$attr:meta])* pub enum $name:ident {
         $($variant:ident = $e:expr,)*
@@ -59,3 +61,80 @@ macro_rules! span_bug {
         $crate::session::span_bug_fmt(file!(), line!(), $span, format_args!($($message)*))
     })
 }
+
+#[macro_export]
+macro_rules! __impl_stable_hash_field {
+    (DECL IGNORED) => (_);
+    (DECL $name:ident) => (ref $name);
+    (USE IGNORED $ctx:expr, $hasher:expr) => ({});
+    (USE $name:ident, $ctx:expr, $hasher:expr) => ($name.hash_stable($ctx, $hasher));
+}
+
+#[macro_export]
+macro_rules! impl_stable_hash_for {
+    (enum $enum_name:path { $( $variant:ident $( ( $($arg:ident),* ) )* ),* }) => {
+        impl<'a, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'tcx>> for $enum_name {
+            #[inline]
+            fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
+                                                  __ctx: &mut $crate::ich::StableHashingContext<'a, 'tcx>,
+                                                  __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
+                use $enum_name::*;
+                ::std::mem::discriminant(self).hash_stable(__ctx, __hasher);
+
+                match *self {
+                    $(
+                        $variant $( ( $( __impl_stable_hash_field!(DECL $arg) ),* ) )* => {
+                            $($( __impl_stable_hash_field!(USE $arg, __ctx, __hasher) );*)*
+                        }
+                    )*
+                }
+            }
+        }
+    };
+    (struct $struct_name:path { $($field:ident),* }) => {
+        impl<'a, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'tcx>> for $struct_name {
+            #[inline]
+            fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
+                                                  __ctx: &mut $crate::ich::StableHashingContext<'a, 'tcx>,
+                                                  __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
+                let $struct_name {
+                    $(ref $field),*
+                } = *self;
+
+                $( $field.hash_stable(__ctx, __hasher));*
+            }
+        }
+    };
+    (tuple_struct $struct_name:path { $($field:ident),* }) => {
+        impl<'a, 'tcx> ::rustc_data_structures::stable_hasher::HashStable<$crate::ich::StableHashingContext<'a, 'tcx>> for $struct_name {
+            #[inline]
+            fn hash_stable<W: ::rustc_data_structures::stable_hasher::StableHasherResult>(&self,
+                                                  __ctx: &mut $crate::ich::StableHashingContext<'a, 'tcx>,
+                                                  __hasher: &mut ::rustc_data_structures::stable_hasher::StableHasher<W>) {
+                let $struct_name (
+                    $(ref $field),*
+                ) = *self;
+
+                $( $field.hash_stable(__ctx, __hasher));*
+            }
+        }
+    };
+}
+
+#[macro_export]
+macro_rules! impl_stable_hash_for_spanned {
+    ($T:path) => (
+
+        impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for ::syntax::codemap::Spanned<$T>
+        {
+            #[inline]
+            fn hash_stable<W: StableHasherResult>(&self,
+                                                  hcx: &mut StableHashingContext<'a, 'tcx>,
+                                                  hasher: &mut StableHasher<W>) {
+                self.node.hash_stable(hcx, hasher);
+                self.span.hash_stable(hcx, hasher);
+            }
+        }
+    );
+}
+
index bc9bbebb1796a83627c3fe418ce934e395df3335..799686ceca4a0ec97021d7ed5343d0d24c417b7f 100644 (file)
@@ -10,7 +10,9 @@
 
 use std::cell::{Ref, RefCell};
 use rustc_data_structures::indexed_vec::IndexVec;
-
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
+                                           StableHasherResult};
+use ich::StableHashingContext;
 use mir::{Mir, BasicBlock};
 
 use rustc_serialize as serialize;
@@ -33,6 +35,13 @@ fn decode<D: serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> {
     }
 }
 
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for Cache {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          _: &mut StableHashingContext<'a, 'tcx>,
+                                          _: &mut StableHasher<W>) {
+        // do nothing
+    }
+}
 
 impl Cache {
     pub fn new() -> Self {
index 01dc7f51e29d9938c2b63e36086094414dd2dad8..aea4684e526ce3a04c454a23bb93075c0b8ebf9d 100644 (file)
@@ -243,6 +243,19 @@ pub fn make_statement_nop(&mut self, location: Location) {
     }
 }
 
+impl_stable_hash_for!(struct Mir<'tcx> {
+    basic_blocks,
+    visibility_scopes,
+    promoted,
+    return_ty,
+    local_decls,
+    arg_count,
+    upvar_decls,
+    spread_arg,
+    span,
+    cache
+});
+
 impl<'tcx> Index<BasicBlock> for Mir<'tcx> {
     type Output = BasicBlockData<'tcx>;
 
@@ -830,6 +843,11 @@ pub struct Static<'tcx> {
     pub ty: Ty<'tcx>,
 }
 
+impl_stable_hash_for!(struct Static<'tcx> {
+    def_id,
+    ty
+});
+
 /// The `Projection` data structure defines things of the form `B.x`
 /// or `*B` or `B[index]`. Note that it is parameterized because it is
 /// shared between `Constant` and `Lvalue`. See the aliases
index 123db6e89476c52c0418ad4c3db34cdd8839da8d..571ef30b6b9096356a0f92b216088c5d6571d036 100644 (file)
@@ -267,7 +267,7 @@ pub fn checked_mul(self, count: u64, dl: &TargetDataLayout) -> Option<Size> {
 
 /// Alignment of a type in bytes, both ABI-mandated and preferred.
 /// Since alignments are always powers of 2, we can pack both in one byte,
-/// giving each a nibble (4 bits) for a maximum alignment of 2^15 = 32768.
+/// giving each a nibble (4 bits) for a maximum alignment of 2<sup>15</sup> = 32768.
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct Align {
     raw: u8
index 6a4e7db21dd127d2d20bf57cb32a2517e4b1d0d1..3c529a69820427052525d8fc999fc79ba552b3df 100644 (file)
@@ -19,6 +19,7 @@
 use hir::{map as hir_map, FreevarMap, TraitMap};
 use hir::def::{Def, CtorKind, ExportMap};
 use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
+use ich::StableHashingContext;
 use middle::const_val::ConstVal;
 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
 use middle::privacy::AccessLevels;
@@ -50,6 +51,8 @@
 use rustc_const_math::ConstInt;
 
 use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter;
+use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
+                                           HashStable};
 
 use hir;
 use hir::itemlikevisit::ItemLikeVisitor;
@@ -1379,6 +1382,25 @@ fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
 
 impl<'tcx> serialize::UseSpecializedDecodable for &'tcx AdtDef {}
 
+
+impl<'a, 'tcx> HashStable<StableHashingContext<'a, 'tcx>> for AdtDef {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a, 'tcx>,
+                                          hasher: &mut StableHasher<W>) {
+        let ty::AdtDef {
+            did,
+            ref variants,
+            ref flags,
+            ref repr,
+        } = *self;
+
+        did.hash_stable(hcx, hasher);
+        variants.hash_stable(hcx, hasher);
+        flags.hash_stable(hcx, hasher);
+        repr.hash_stable(hcx, hasher);
+    }
+}
+
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum AdtKind { Struct, Union, Enum }
 
@@ -1391,6 +1413,13 @@ pub struct ReprOptions {
     pub int: Option<attr::IntType>,
 }
 
+impl_stable_hash_for!(struct ReprOptions {
+    c,
+    packed,
+    simd,
+    int
+});
+
 impl ReprOptions {
     pub fn new(tcx: TyCtxt, did: DefId) -> ReprOptions {
         let mut ret = ReprOptions::default();
index c5d577ce571d40aceb664dd8d190a19f4efb709d..54f5cff16ed6cb584b888d46983820938f5e9d1e 100644 (file)
@@ -490,6 +490,17 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
               _ => span_bug!(e.span, "typeck error"),
              })
           }
+          (Char(a), Char(b)) => {
+            Bool(match op.node {
+              hir::BiEq => a == b,
+              hir::BiNe => a != b,
+              hir::BiLt => a < b,
+              hir::BiLe => a <= b,
+              hir::BiGe => a >= b,
+              hir::BiGt => a > b,
+              _ => span_bug!(e.span, "typeck error"),
+             })
+          }
 
           _ => signal!(e, MiscBinaryOp),
         }
index 9ccd95dd8d805966060a3dc81c3a379115bd73f7..c1735b4a4ec9a588156757293152deb775fa1129 100644 (file)
@@ -37,6 +37,8 @@
 #![feature(unsize)]
 #![feature(i128_type)]
 #![feature(conservative_impl_trait)]
+#![feature(discriminant_value)]
+#![feature(specialization)]
 
 #![cfg_attr(unix, feature(libc))]
 #![cfg_attr(test, feature(test))]
index 231c01c9ab78d8d99b55fccfddd9d29b152de220..dc412a0763ef70f196eed9134bfa930f21a40570 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::hash::Hasher;
+use std::hash::{Hash, Hasher};
 use std::marker::PhantomData;
 use std::mem;
 use blake2b::Blake2bHasher;
@@ -174,3 +174,193 @@ fn write_isize(&mut self, i: isize) {
         self.write_ileb128(i as i64);
     }
 }
+
+
+/// Something that implements `HashStable<CTX>` can be hashed in a way that is
+/// stable across multiple compiliation sessions.
+pub trait HashStable<CTX> {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut CTX,
+                                          hasher: &mut StableHasher<W>);
+}
+
+// Implement HashStable by just calling `Hash::hash()`. This works fine for
+// self-contained values that don't depend on the hashing context `CTX`.
+macro_rules! impl_stable_hash_via_hash {
+    ($t:ty) => (
+        impl<CTX> HashStable<CTX> for $t {
+            #[inline]
+            fn hash_stable<W: StableHasherResult>(&self,
+                                                  _: &mut CTX,
+                                                  hasher: &mut StableHasher<W>) {
+                ::std::hash::Hash::hash(self, hasher);
+            }
+        }
+    );
+}
+
+impl_stable_hash_via_hash!(i8);
+impl_stable_hash_via_hash!(i16);
+impl_stable_hash_via_hash!(i32);
+impl_stable_hash_via_hash!(i64);
+impl_stable_hash_via_hash!(isize);
+
+impl_stable_hash_via_hash!(u8);
+impl_stable_hash_via_hash!(u16);
+impl_stable_hash_via_hash!(u32);
+impl_stable_hash_via_hash!(u64);
+impl_stable_hash_via_hash!(usize);
+
+impl_stable_hash_via_hash!(u128);
+impl_stable_hash_via_hash!(i128);
+
+impl_stable_hash_via_hash!(char);
+impl_stable_hash_via_hash!(());
+
+impl<CTX> HashStable<CTX> for f32 {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          ctx: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        let val: u32 = unsafe {
+            ::std::mem::transmute(*self)
+        };
+        val.hash_stable(ctx, hasher);
+    }
+}
+
+impl<CTX> HashStable<CTX> for f64 {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          ctx: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        let val: u64 = unsafe {
+            ::std::mem::transmute(*self)
+        };
+        val.hash_stable(ctx, hasher);
+    }
+}
+
+impl<T1: HashStable<CTX>, T2: HashStable<CTX>, CTX> HashStable<CTX> for (T1, T2) {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          ctx: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        self.0.hash_stable(ctx, hasher);
+        self.1.hash_stable(ctx, hasher);
+    }
+}
+
+impl<T: HashStable<CTX>, CTX> HashStable<CTX> for [T] {
+    default fn hash_stable<W: StableHasherResult>(&self,
+                                                  ctx: &mut CTX,
+                                                  hasher: &mut StableHasher<W>) {
+        self.len().hash_stable(ctx, hasher);
+        for item in self {
+            item.hash_stable(ctx, hasher);
+        }
+    }
+}
+
+impl<T: HashStable<CTX>, CTX> HashStable<CTX> for Vec<T> {
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          ctx: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        (&self[..]).hash_stable(ctx, hasher);
+    }
+}
+
+impl<CTX> HashStable<CTX> for str {
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          _: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        self.len().hash(hasher);
+        self.as_bytes().hash(hasher);
+    }
+}
+
+impl<CTX> HashStable<CTX> for bool {
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          ctx: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        (if *self { 1u8 } else { 0u8 }).hash_stable(ctx, hasher);
+    }
+}
+
+
+impl<T, CTX> HashStable<CTX> for Option<T>
+    where T: HashStable<CTX>
+{
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          ctx: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        if let Some(ref value) = *self {
+            1u8.hash_stable(ctx, hasher);
+            value.hash_stable(ctx, hasher);
+        } else {
+            0u8.hash_stable(ctx, hasher);
+        }
+    }
+}
+
+impl<'a, T, CTX> HashStable<CTX> for &'a T
+    where T: HashStable<CTX>
+{
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          ctx: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        (**self).hash_stable(ctx, hasher);
+    }
+}
+
+impl<T, CTX> HashStable<CTX> for ::std::mem::Discriminant<T> {
+    #[inline]
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          _: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        ::std::hash::Hash::hash(self, hasher);
+    }
+}
+
+impl<K, V, CTX> HashStable<CTX> for ::std::collections::BTreeMap<K, V>
+    where K: Ord + HashStable<CTX>,
+          V: HashStable<CTX>,
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          ctx: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        self.len().hash_stable(ctx, hasher);
+        for (k, v) in self {
+            k.hash_stable(ctx, hasher);
+            v.hash_stable(ctx, hasher);
+        }
+    }
+}
+
+impl<T, CTX> HashStable<CTX> for ::std::collections::BTreeSet<T>
+    where T: Ord + HashStable<CTX>,
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          ctx: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        self.len().hash_stable(ctx, hasher);
+        for v in self {
+            v.hash_stable(ctx, hasher);
+        }
+    }
+}
+
+impl<I: ::indexed_vec::Idx, T, CTX> HashStable<CTX> for ::indexed_vec::IndexVec<I, T>
+    where T: HashStable<CTX>,
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          ctx: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        self.len().hash_stable(ctx, hasher);
+        for v in &self.raw {
+            v.hash_stable(ctx, hasher);
+        }
+    }
+}
index 977382b33adf75a429eb566390c9471f3793d65c..96eb5dd602f514470b006aab390a80cacef04ede 100644 (file)
@@ -1358,10 +1358,9 @@ pub fn build_output_filenames(input: &Input,
                                            .values()
                                            .filter(|a| a.is_none())
                                            .count();
-            let ofile = if unnamed_output_types > 1 &&
-                            sess.opts.output_types.contains_key(&OutputType::Exe) {
-                sess.warn("ignoring specified output filename for 'link' output because multiple \
-                           outputs were requested");
+            let ofile = if unnamed_output_types > 1 {
+                sess.warn("due to multiple output types requested, the explicitly specified \
+                           output file name will be adapted for each output type");
                 None
             } else {
                 Some(out_file.clone())
index c9496a4deb8eb84293b3834cf67f20a3f33912f3..c80a5a1627797bfbae1448530bd649f99ca9b55d 100644 (file)
 //! at the end of compilation would be different from those computed
 //! at the beginning.
 
-use syntax::ast;
 use std::cell::RefCell;
 use std::hash::Hash;
 use rustc::dep_graph::DepNode;
 use rustc::hir;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
-use rustc::hir::intravisit as visit;
-use rustc::hir::intravisit::{Visitor, NestedVisitorMap};
-use rustc::ich::{Fingerprint, DefPathHashes, CachingCodemapView};
+use rustc::hir::itemlikevisit::ItemLikeVisitor;
+use rustc::ich::{Fingerprint, StableHashingContext};
 use rustc::ty::TyCtxt;
-use rustc_data_structures::stable_hasher::StableHasher;
+use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
 use rustc_data_structures::fx::FxHashMap;
 use rustc::util::common::record_time;
-use rustc::session::config::DebugInfoLevel::NoDebugInfo;
-
-use self::svh_visitor::StrictVersionHashVisitor;
-
-mod svh_visitor;
 
 pub type IchHasher = StableHasher<Fingerprint>;
 
@@ -94,91 +87,42 @@ fn index(&self, index: &'a DepNode<DefId>) -> &Fingerprint {
     }
 }
 
-
-pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
-                                                    -> IncrementalHashesMap {
-    let _ignore = tcx.dep_graph.in_ignore();
-    let krate = tcx.hir.krate();
-    let hash_spans = tcx.sess.opts.debuginfo != NoDebugInfo;
-    let mut visitor = HashItemsVisitor {
-        tcx: tcx,
-        hashes: IncrementalHashesMap::new(),
-        def_path_hashes: DefPathHashes::new(tcx),
-        codemap: CachingCodemapView::new(tcx),
-        hash_spans: hash_spans,
-    };
-    record_time(&tcx.sess.perf_stats.incr_comp_hashes_time, || {
-        visitor.calculate_def_id(DefId::local(CRATE_DEF_INDEX), |v| {
-            v.hash_crate_root_module(krate);
-        });
-        krate.visit_all_item_likes(&mut visitor.as_deep_visitor());
-
-        for macro_def in krate.exported_macros.iter() {
-            visitor.calculate_node_id(macro_def.id,
-                                      |v| v.visit_macro_def(macro_def));
-        }
-    });
-
-    tcx.sess.perf_stats.incr_comp_hashes_count.set(visitor.hashes.len() as u64);
-
-    record_time(&tcx.sess.perf_stats.svh_time, || visitor.compute_crate_hash());
-    visitor.hashes
-}
-
-struct HashItemsVisitor<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    def_path_hashes: DefPathHashes<'a, 'tcx>,
-    codemap: CachingCodemapView<'tcx>,
+struct ComputeItemHashesVisitor<'a, 'tcx: 'a> {
+    hcx: StableHashingContext<'a, 'tcx>,
     hashes: IncrementalHashesMap,
-    hash_spans: bool,
 }
 
-impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> {
-    fn calculate_node_id<W>(&mut self, id: ast::NodeId, walk_op: W)
-        where W: for<'v> FnMut(&mut StrictVersionHashVisitor<'v, 'a, 'tcx>)
-    {
-        let def_id = self.tcx.hir.local_def_id(id);
-        self.calculate_def_id(def_id, walk_op)
-    }
-
-    fn calculate_def_id<W>(&mut self, def_id: DefId, mut walk_op: W)
-        where W: for<'v> FnMut(&mut StrictVersionHashVisitor<'v, 'a, 'tcx>)
+impl<'a, 'tcx: 'a> ComputeItemHashesVisitor<'a, 'tcx> {
+    fn compute_and_store_ich_for_item_like<T>(&mut self,
+                                              dep_node: DepNode<DefId>,
+                                              hash_bodies: bool,
+                                              item_like: T)
+        where T: HashStable<StableHashingContext<'a, 'tcx>>
     {
-        assert!(def_id.is_local());
-        debug!("HashItemsVisitor::calculate(def_id={:?})", def_id);
-        self.calculate_def_hash(DepNode::Hir(def_id), false, &mut walk_op);
-        self.calculate_def_hash(DepNode::HirBody(def_id), true, &mut walk_op);
-    }
+        let mut hasher = IchHasher::new();
+        self.hcx.while_hashing_hir_bodies(hash_bodies, |hcx| {
+            item_like.hash_stable(hcx, &mut hasher);
+        });
 
-    fn calculate_def_hash<W>(&mut self,
-                             dep_node: DepNode<DefId>,
-                             hash_bodies: bool,
-                             walk_op: &mut W)
-        where W: for<'v> FnMut(&mut StrictVersionHashVisitor<'v, 'a, 'tcx>)
-    {
-        let mut state = IchHasher::new();
-        walk_op(&mut StrictVersionHashVisitor::new(&mut state,
-                                                   self.tcx,
-                                                   &mut self.def_path_hashes,
-                                                   &mut self.codemap,
-                                                   self.hash_spans,
-                                                   hash_bodies));
-        let bytes_hashed = state.bytes_hashed();
-        let item_hash = state.finish();
+        let bytes_hashed = hasher.bytes_hashed();
+        let item_hash = hasher.finish();
         debug!("calculate_def_hash: dep_node={:?} hash={:?}", dep_node, item_hash);
         self.hashes.insert(dep_node, item_hash);
 
-        let bytes_hashed = self.tcx.sess.perf_stats.incr_comp_bytes_hashed.get() +
+        let tcx = self.hcx.tcx();
+        let bytes_hashed =
+            tcx.sess.perf_stats.incr_comp_bytes_hashed.get() +
             bytes_hashed;
-        self.tcx.sess.perf_stats.incr_comp_bytes_hashed.set(bytes_hashed);
+        tcx.sess.perf_stats.incr_comp_bytes_hashed.set(bytes_hashed);
     }
 
     fn compute_crate_hash(&mut self) {
-        let krate = self.tcx.hir.krate();
+        let tcx = self.hcx.tcx();
+        let krate = tcx.hir.krate();
 
         let mut crate_state = IchHasher::new();
 
-        let crate_disambiguator = self.tcx.sess.local_crate_disambiguator();
+        let crate_disambiguator = tcx.sess.local_crate_disambiguator();
         "crate_disambiguator".hash(&mut crate_state);
         crate_disambiguator.as_str().len().hash(&mut crate_state);
         crate_disambiguator.as_str().hash(&mut crate_state);
@@ -186,7 +130,7 @@ fn compute_crate_hash(&mut self) {
         // add each item (in some deterministic order) to the overall
         // crate hash.
         {
-            let def_path_hashes = &mut self.def_path_hashes;
+            let hcx = &mut self.hcx;
             let mut item_hashes: Vec<_> =
                 self.hashes.iter()
                            .map(|(item_dep_node, &item_hash)| {
@@ -194,7 +138,7 @@ fn compute_crate_hash(&mut self) {
                                // DepNode<u64> where the u64 is the
                                // hash of the def-id's def-path:
                                let item_dep_node =
-                                   item_dep_node.map_def(|&did| Some(def_path_hashes.hash(did)))
+                                   item_dep_node.map_def(|&did| Some(hcx.def_path_hash(did)))
                                                 .unwrap();
                                (item_dep_node, item_hash)
                            })
@@ -203,40 +147,85 @@ fn compute_crate_hash(&mut self) {
             item_hashes.hash(&mut crate_state);
         }
 
-        {
-            let mut visitor = StrictVersionHashVisitor::new(&mut crate_state,
-                                                            self.tcx,
-                                                            &mut self.def_path_hashes,
-                                                            &mut self.codemap,
-                                                            self.hash_spans,
-                                                            false);
-            visitor.hash_attributes(&krate.attrs);
-        }
+        krate.attrs.hash_stable(&mut self.hcx, &mut crate_state);
 
         let crate_hash = crate_state.finish();
         self.hashes.insert(DepNode::Krate, crate_hash);
         debug!("calculate_crate_hash: crate_hash={:?}", crate_hash);
     }
-}
 
-
-impl<'a, 'tcx> Visitor<'tcx> for HashItemsVisitor<'a, 'tcx> {
-    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::None
+    fn hash_crate_root_module(&mut self, krate: &'tcx hir::Crate) {
+        let hir::Crate {
+            ref module,
+            // Crate attributes are not copied over to the root `Mod`, so hash
+            // them explicitly here.
+            ref attrs,
+            span,
+
+            // These fields are handled separately:
+            exported_macros: _,
+            items: _,
+            trait_items: _,
+            impl_items: _,
+            bodies: _,
+            trait_impls: _,
+            trait_default_impl: _,
+            body_ids: _,
+        } = *krate;
+
+        let def_id = DefId::local(CRATE_DEF_INDEX);
+        self.compute_and_store_ich_for_item_like(DepNode::Hir(def_id),
+                                                 false,
+                                                 (module, (span, attrs)));
+        self.compute_and_store_ich_for_item_like(DepNode::HirBody(def_id),
+                                                 true,
+                                                 (module, (span, attrs)));
     }
+}
 
+impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for ComputeItemHashesVisitor<'a, 'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item) {
-        self.calculate_node_id(item.id, |v| v.visit_item(item));
-        visit::walk_item(self, item);
+        let def_id = self.hcx.tcx().hir.local_def_id(item.id);
+        self.compute_and_store_ich_for_item_like(DepNode::Hir(def_id), false, item);
+        self.compute_and_store_ich_for_item_like(DepNode::HirBody(def_id), true, item);
     }
 
-    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) {
-        self.calculate_node_id(trait_item.id, |v| v.visit_trait_item(trait_item));
-        visit::walk_trait_item(self, trait_item);
+    fn visit_trait_item(&mut self, item: &'tcx hir::TraitItem) {
+        let def_id = self.hcx.tcx().hir.local_def_id(item.id);
+        self.compute_and_store_ich_for_item_like(DepNode::Hir(def_id), false, item);
+        self.compute_and_store_ich_for_item_like(DepNode::HirBody(def_id), true, item);
     }
 
-    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
-        self.calculate_node_id(impl_item.id, |v| v.visit_impl_item(impl_item));
-        visit::walk_impl_item(self, impl_item);
+    fn visit_impl_item(&mut self, item: &'tcx hir::ImplItem) {
+        let def_id = self.hcx.tcx().hir.local_def_id(item.id);
+        self.compute_and_store_ich_for_item_like(DepNode::Hir(def_id), false, item);
+        self.compute_and_store_ich_for_item_like(DepNode::HirBody(def_id), true, item);
     }
 }
+
+pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
+                                                    -> IncrementalHashesMap {
+    let _ignore = tcx.dep_graph.in_ignore();
+    let krate = tcx.hir.krate();
+
+    let mut visitor = ComputeItemHashesVisitor {
+        hcx: StableHashingContext::new(tcx),
+        hashes: IncrementalHashesMap::new(),
+    };
+
+    record_time(&tcx.sess.perf_stats.incr_comp_hashes_time, || {
+        visitor.hash_crate_root_module(krate);
+        krate.visit_all_item_likes(&mut visitor);
+
+        for macro_def in krate.exported_macros.iter() {
+            let def_id = tcx.hir.local_def_id(macro_def.id);
+            visitor.compute_and_store_ich_for_item_like(DepNode::Hir(def_id), false, macro_def);
+            visitor.compute_and_store_ich_for_item_like(DepNode::HirBody(def_id), true, macro_def);
+        }
+    });
+
+    tcx.sess.perf_stats.incr_comp_hashes_count.set(visitor.hashes.len() as u64);
+
+    record_time(&tcx.sess.perf_stats.svh_time, || visitor.compute_crate_hash());
+    visitor.hashes
+}
diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs
deleted file mode 100644 (file)
index 5401b37..0000000
+++ /dev/null
@@ -1,1111 +0,0 @@
-// 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 self::SawExprComponent::*;
-use self::SawAbiComponent::*;
-use self::SawItemComponent::*;
-use self::SawPatComponent::*;
-use self::SawTyComponent::*;
-use self::SawTraitOrImplItemComponent::*;
-use syntax::abi::Abi;
-use syntax::ast::{self, Name, NodeId};
-use syntax::attr;
-use syntax::ext::hygiene::SyntaxContext;
-use syntax::parse::token;
-use syntax::symbol::InternedString;
-use syntax_pos::{Span, BytePos};
-use syntax::tokenstream;
-use rustc::hir;
-use rustc::hir::*;
-use rustc::hir::def::Def;
-use rustc::hir::def_id::DefId;
-use rustc::hir::intravisit::{self as visit, Visitor};
-use rustc::ich::{DefPathHashes, CachingCodemapView, IGNORED_ATTRIBUTES};
-use rustc::ty::TyCtxt;
-use std::hash::{Hash, Hasher};
-
-use super::IchHasher;
-
-pub struct StrictVersionHashVisitor<'a, 'hash: 'a, 'tcx: 'hash> {
-    pub tcx: TyCtxt<'hash, 'tcx, 'tcx>,
-    pub st: &'a mut IchHasher,
-    // collect a deterministic hash of def-ids that we have seen
-    def_path_hashes: &'a mut DefPathHashes<'hash, 'tcx>,
-    hash_spans: bool,
-    codemap: &'a mut CachingCodemapView<'tcx>,
-    overflow_checks_enabled: bool,
-    hash_bodies: bool,
-}
-
-impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
-    pub fn new(st: &'a mut IchHasher,
-               tcx: TyCtxt<'hash, 'tcx, 'tcx>,
-               def_path_hashes: &'a mut DefPathHashes<'hash, 'tcx>,
-               codemap: &'a mut CachingCodemapView<'tcx>,
-               hash_spans: bool,
-               hash_bodies: bool)
-               -> Self {
-        let check_overflow = tcx.sess.overflow_checks();
-
-        StrictVersionHashVisitor {
-            st: st,
-            tcx: tcx,
-            def_path_hashes: def_path_hashes,
-            hash_spans: hash_spans,
-            codemap: codemap,
-            overflow_checks_enabled: check_overflow,
-            hash_bodies: hash_bodies,
-        }
-    }
-
-    fn compute_def_id_hash(&mut self, def_id: DefId) -> u64 {
-        self.def_path_hashes.hash(def_id)
-    }
-
-    // Hash a span in a stable way. We can't directly hash the span's BytePos
-    // fields (that would be similar to hashing pointers, since those are just
-    // offsets into the CodeMap). Instead, we hash the (file name, line, column)
-    // triple, which stays the same even if the containing FileMap has moved
-    // within the CodeMap.
-    // Also note that we are hashing byte offsets for the column, not unicode
-    // codepoint offsets. For the purpose of the hash that's sufficient.
-    // Also, hashing filenames is expensive so we avoid doing it twice when the
-    // span starts and ends in the same file, which is almost always the case.
-    fn hash_span(&mut self, span: Span) {
-        debug!("hash_span: st={:?}", self.st);
-
-        // If this is not an empty or invalid span, we want to hash the last
-        // position that belongs to it, as opposed to hashing the first
-        // position past it.
-        let span_hi = if span.hi > span.lo {
-            // We might end up in the middle of a multibyte character here,
-            // but that's OK, since we are not trying to decode anything at
-            // this position.
-            span.hi - BytePos(1)
-        } else {
-            span.hi
-        };
-
-        let expn_kind = if span.ctxt == SyntaxContext::empty() {
-            SawSpanExpnKind::NoExpansion
-        } else {
-            SawSpanExpnKind::SomeExpansion
-        };
-
-        let loc1 = self.codemap.byte_pos_to_line_and_col(span.lo);
-        let loc1 = loc1.as_ref()
-                       .map(|&(ref fm, line, col)| (&fm.name[..], line, col))
-                       .unwrap_or(("???", 0, BytePos(0)));
-
-        let loc2 = self.codemap.byte_pos_to_line_and_col(span_hi);
-        let loc2 = loc2.as_ref()
-                       .map(|&(ref fm, line, col)| (&fm.name[..], line, col))
-                       .unwrap_or(("???", 0, BytePos(0)));
-
-        let saw = if loc1.0 == loc2.0 {
-            SawSpan(loc1.0,
-                    loc1.1, loc1.2,
-                    loc2.1, loc2.2,
-                    expn_kind)
-        } else {
-            SawSpanTwoFiles(loc1.0, loc1.1, loc1.2,
-                            loc2.0, loc2.1, loc2.2,
-                            expn_kind)
-        };
-        saw.hash(self.st);
-
-        if expn_kind == SawSpanExpnKind::SomeExpansion {
-            self.hash_span(span.source_callsite());
-        }
-    }
-
-    fn hash_discriminant<T>(&mut self, v: &T) {
-        unsafe {
-            let disr = ::std::intrinsics::discriminant_value(v);
-            debug!("hash_discriminant: disr={}, st={:?}", disr, self.st);
-            disr.hash(self.st);
-        }
-    }
-}
-
-// To off-load the bulk of the hash-computation on #[derive(Hash)],
-// we define a set of enums corresponding to the content that our
-// crate visitor will encounter as it traverses the ast.
-//
-// The important invariant is that all of the Saw*Component enums
-// do not carry any Spans, Names, or Idents.
-//
-// Not carrying any Names/Idents is the important fix for problem
-// noted on PR #13948: using the ident.name as the basis for a
-// hash leads to unstable SVH, because ident.name is just an index
-// into intern table (i.e. essentially a random address), not
-// computed from the name content.
-//
-// With the below enums, the SVH computation is not sensitive to
-// artifacts of how rustc was invoked nor of how the source code
-// was laid out.  (Or at least it is *less* sensitive.)
-
-// This enum represents the different potential bits of code the
-// visitor could encounter that could affect the ABI for the crate,
-// and assigns each a distinct tag to feed into the hash computation.
-#[derive(Hash)]
-enum SawAbiComponent<'a> {
-
-    // FIXME (#14132): should we include (some function of)
-    // ident.ctxt as well?
-    SawIdent(InternedString),
-    SawStructDef(InternedString),
-
-    SawLifetime,
-    SawLifetimeDef(usize),
-
-    SawMod,
-    SawForeignItem(SawForeignItemComponent),
-    SawItem(SawItemComponent),
-    SawTy(SawTyComponent),
-    SawFnDecl(bool),
-    SawGenerics,
-    SawTraitItem(SawTraitOrImplItemComponent),
-    SawImplItem(SawTraitOrImplItemComponent),
-    SawStructField,
-    SawVariant(bool),
-    SawQPath,
-    SawPathSegment,
-    SawPathParameters,
-    SawBlock,
-    SawPat(SawPatComponent),
-    SawLocal,
-    SawArm,
-    SawExpr(SawExprComponent<'a>),
-    SawStmt,
-    SawVis,
-    SawAssociatedItemKind(hir::AssociatedItemKind),
-    SawDefaultness(hir::Defaultness),
-    SawWherePredicate,
-    SawTyParamBound,
-    SawPolyTraitRef,
-    SawAssocTypeBinding,
-    SawAttribute(ast::AttrStyle),
-    SawMacroDef,
-    SawSpan(&'a str,
-            usize, BytePos,
-            usize, BytePos,
-            SawSpanExpnKind),
-    SawSpanTwoFiles(&'a str, usize, BytePos,
-                    &'a str, usize, BytePos,
-                    SawSpanExpnKind),
-}
-
-/// SawExprComponent carries all of the information that we want
-/// to include in the hash that *won't* be covered by the
-/// subsequent recursive traversal of the expression's
-/// substructure by the visitor.
-///
-/// We know every Expr_ variant is covered by a variant because
-/// `fn saw_expr` maps each to some case below.  Ensuring that
-/// each variant carries an appropriate payload has to be verified
-/// by hand.
-///
-/// (However, getting that *exactly* right is not so important
-/// because the SVH is just a developer convenience; there is no
-/// guarantee of collision-freedom, hash collisions are just
-/// (hopefully) unlikely.)
-///
-/// The xxxComponent enums and saw_xxx functions for Item, Pat,
-/// Ty, TraitItem and ImplItem follow the same methodology.
-#[derive(Hash)]
-enum SawExprComponent<'a> {
-
-    SawExprLoop(Option<InternedString>),
-    SawExprField(InternedString),
-    SawExprTupField(usize),
-    SawExprBreak(Option<InternedString>),
-    SawExprAgain(Option<InternedString>),
-
-    SawExprBox,
-    SawExprArray,
-    SawExprCall,
-    SawExprMethodCall,
-    SawExprTup,
-    SawExprBinary(hir::BinOp_),
-    SawExprUnary(hir::UnOp),
-    SawExprLit(ast::LitKind),
-    SawExprLitStr(InternedString, ast::StrStyle),
-    SawExprLitFloat(InternedString, Option<ast::FloatTy>),
-    SawExprCast,
-    SawExprType,
-    SawExprIf,
-    SawExprWhile,
-    SawExprMatch,
-    SawExprClosure(CaptureClause),
-    SawExprBlock,
-    SawExprAssign,
-    SawExprAssignOp(hir::BinOp_),
-    SawExprIndex,
-    SawExprPath,
-    SawExprAddrOf(hir::Mutability),
-    SawExprRet,
-    SawExprInlineAsm(StableInlineAsm<'a>),
-    SawExprStruct,
-    SawExprRepeat,
-}
-
-// The boolean returned indicates whether the span of this expression is always
-// significant, regardless of debuginfo.
-fn saw_expr<'a>(node: &'a Expr_,
-                overflow_checks_enabled: bool)
-                -> (SawExprComponent<'a>, bool) {
-    let binop_can_panic_at_runtime = |binop| {
-        match binop {
-            BiAdd |
-            BiSub |
-            BiMul => overflow_checks_enabled,
-
-            BiDiv |
-            BiRem => true,
-
-            BiAnd |
-            BiOr |
-            BiBitXor |
-            BiBitAnd |
-            BiBitOr |
-            BiShl |
-            BiShr |
-            BiEq |
-            BiLt |
-            BiLe |
-            BiNe |
-            BiGe |
-            BiGt => false
-        }
-    };
-
-    let unop_can_panic_at_runtime = |unop| {
-        match unop {
-            UnDeref |
-            UnNot => false,
-            UnNeg => overflow_checks_enabled,
-        }
-    };
-
-    match *node {
-        ExprBox(..)              => (SawExprBox, false),
-        ExprArray(..)            => (SawExprArray, false),
-        ExprCall(..)             => (SawExprCall, false),
-        ExprMethodCall(..)       => (SawExprMethodCall, false),
-        ExprTup(..)              => (SawExprTup, false),
-        ExprBinary(op, ..)       => {
-            (SawExprBinary(op.node), binop_can_panic_at_runtime(op.node))
-        }
-        ExprUnary(op, _)         => {
-            (SawExprUnary(op), unop_can_panic_at_runtime(op))
-        }
-        ExprLit(ref lit)         => (saw_lit(lit), false),
-        ExprCast(..)             => (SawExprCast, false),
-        ExprType(..)             => (SawExprType, false),
-        ExprIf(..)               => (SawExprIf, false),
-        ExprWhile(..)            => (SawExprWhile, false),
-        ExprLoop(_, id, _)       => (SawExprLoop(id.map(|id| id.node.as_str())), false),
-        ExprMatch(..)            => (SawExprMatch, false),
-        ExprClosure(cc, _, _, _) => (SawExprClosure(cc), false),
-        ExprBlock(..)            => (SawExprBlock, false),
-        ExprAssign(..)           => (SawExprAssign, false),
-        ExprAssignOp(op, ..)     => {
-            (SawExprAssignOp(op.node), binop_can_panic_at_runtime(op.node))
-        }
-        ExprField(_, name)       => (SawExprField(name.node.as_str()), false),
-        ExprTupField(_, id)      => (SawExprTupField(id.node), false),
-        ExprIndex(..)            => (SawExprIndex, true),
-        ExprPath(_)              => (SawExprPath, false),
-        ExprAddrOf(m, _)         => (SawExprAddrOf(m), false),
-        ExprBreak(label, _)      => (SawExprBreak(label.ident.map(|i|
-                                                    i.node.name.as_str())), false),
-        ExprAgain(label)         => (SawExprAgain(label.ident.map(|i|
-                                                    i.node.name.as_str())), false),
-        ExprRet(..)              => (SawExprRet, false),
-        ExprInlineAsm(ref a,..)  => (SawExprInlineAsm(StableInlineAsm(a)), false),
-        ExprStruct(..)           => (SawExprStruct, false),
-        ExprRepeat(..)           => (SawExprRepeat, false),
-    }
-}
-
-fn saw_lit(lit: &ast::Lit) -> SawExprComponent<'static> {
-    match lit.node {
-        ast::LitKind::Str(s, style) => SawExprLitStr(s.as_str(), style),
-        ast::LitKind::Float(s, ty) => SawExprLitFloat(s.as_str(), Some(ty)),
-        ast::LitKind::FloatUnsuffixed(s) => SawExprLitFloat(s.as_str(), None),
-        ref node @ _ => SawExprLit(node.clone()),
-    }
-}
-
-#[derive(Hash)]
-enum SawItemComponent {
-    SawItemExternCrate,
-    SawItemUse(UseKind),
-    SawItemStatic(Mutability),
-    SawItemConst,
-    SawItemFn(Unsafety, Constness, Abi),
-    SawItemMod,
-    SawItemForeignMod(Abi),
-    SawItemTy,
-    SawItemEnum,
-    SawItemStruct,
-    SawItemUnion,
-    SawItemTrait(Unsafety),
-    SawItemDefaultImpl(Unsafety),
-    SawItemImpl(Unsafety, ImplPolarity)
-}
-
-fn saw_item(node: &Item_) -> SawItemComponent {
-    match *node {
-        ItemExternCrate(..) => SawItemExternCrate,
-        ItemUse(_, kind) => SawItemUse(kind),
-        ItemStatic(_, mutability, _) => SawItemStatic(mutability),
-        ItemConst(..) =>SawItemConst,
-        ItemFn(_, unsafety, constness, abi, _, _) => SawItemFn(unsafety, constness, abi),
-        ItemMod(..) => SawItemMod,
-        ItemForeignMod(ref fm) => SawItemForeignMod(fm.abi),
-        ItemTy(..) => SawItemTy,
-        ItemEnum(..) => SawItemEnum,
-        ItemStruct(..) => SawItemStruct,
-        ItemUnion(..) => SawItemUnion,
-        ItemTrait(unsafety, ..) => SawItemTrait(unsafety),
-        ItemDefaultImpl(unsafety, _) => SawItemDefaultImpl(unsafety),
-        ItemImpl(unsafety, implpolarity, ..) => SawItemImpl(unsafety, implpolarity)
-    }
-}
-
-#[derive(Hash)]
-enum SawForeignItemComponent {
-    Static { mutable: bool },
-    Fn,
-}
-
-#[derive(Hash)]
-enum SawPatComponent {
-    SawPatWild,
-    SawPatBinding(BindingMode),
-    SawPatStruct,
-    SawPatTupleStruct,
-    SawPatPath,
-    SawPatTuple,
-    SawPatBox,
-    SawPatRef(Mutability),
-    SawPatLit,
-    SawPatRange,
-    SawPatSlice
-}
-
-fn saw_pat(node: &PatKind) -> SawPatComponent {
-    match *node {
-        PatKind::Wild => SawPatWild,
-        PatKind::Binding(bindingmode, ..) => SawPatBinding(bindingmode),
-        PatKind::Struct(..) => SawPatStruct,
-        PatKind::TupleStruct(..) => SawPatTupleStruct,
-        PatKind::Path(_) => SawPatPath,
-        PatKind::Tuple(..) => SawPatTuple,
-        PatKind::Box(..) => SawPatBox,
-        PatKind::Ref(_, mutability) => SawPatRef(mutability),
-        PatKind::Lit(..) => SawPatLit,
-        PatKind::Range(..) => SawPatRange,
-        PatKind::Slice(..) => SawPatSlice
-    }
-}
-
-#[derive(Hash)]
-enum SawTyComponent {
-    SawTySlice,
-    SawTyArray,
-    SawTyPtr(Mutability),
-    SawTyRptr(Mutability),
-    SawTyBareFn(Unsafety, Abi),
-    SawTyNever,
-    SawTyTup,
-    SawTyPath,
-    SawTyObjectSum,
-    SawTyImplTrait,
-    SawTyTypeof,
-    SawTyInfer
-}
-
-fn saw_ty(node: &Ty_) -> SawTyComponent {
-    match *node {
-      TySlice(..) => SawTySlice,
-      TyArray(..) => SawTyArray,
-      TyPtr(ref mty) => SawTyPtr(mty.mutbl),
-      TyRptr(_, ref mty) => SawTyRptr(mty.mutbl),
-      TyBareFn(ref barefnty) => SawTyBareFn(barefnty.unsafety, barefnty.abi),
-      TyNever => SawTyNever,
-      TyTup(..) => SawTyTup,
-      TyPath(_) => SawTyPath,
-      TyTraitObject(..) => SawTyObjectSum,
-      TyImplTrait(..) => SawTyImplTrait,
-      TyTypeof(..) => SawTyTypeof,
-      TyInfer => SawTyInfer
-    }
-}
-
-#[derive(Hash)]
-enum SawTraitOrImplItemComponent {
-    SawTraitOrImplItemConst,
-    // The boolean signifies whether a body is present
-    SawTraitOrImplItemMethod(Unsafety, Constness, Abi, bool),
-    SawTraitOrImplItemType
-}
-
-fn saw_trait_item(ti: &TraitItemKind) -> SawTraitOrImplItemComponent {
-    match *ti {
-        TraitItemKind::Const(..) => SawTraitOrImplItemConst,
-        TraitItemKind::Method(ref sig, TraitMethod::Required(_)) =>
-            SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi, false),
-        TraitItemKind::Method(ref sig, TraitMethod::Provided(_)) =>
-            SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi, true),
-        TraitItemKind::Type(..) => SawTraitOrImplItemType
-    }
-}
-
-fn saw_impl_item(ii: &ImplItemKind) -> SawTraitOrImplItemComponent {
-    match *ii {
-        ImplItemKind::Const(..) => SawTraitOrImplItemConst,
-        ImplItemKind::Method(ref sig, _) =>
-            SawTraitOrImplItemMethod(sig.unsafety, sig.constness, sig.abi, true),
-        ImplItemKind::Type(..) => SawTraitOrImplItemType
-    }
-}
-
-#[derive(Clone, Copy, Hash, Eq, PartialEq)]
-enum SawSpanExpnKind {
-    NoExpansion,
-    SomeExpansion,
-}
-
-/// A wrapper that provides a stable Hash implementation.
-struct StableInlineAsm<'a>(&'a InlineAsm);
-
-impl<'a> Hash for StableInlineAsm<'a> {
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        let InlineAsm {
-            asm,
-            asm_str_style,
-            ref outputs,
-            ref inputs,
-            ref clobbers,
-            volatile,
-            alignstack,
-            dialect,
-            ctxt: _, // This is used for error reporting
-        } = *self.0;
-
-        asm.as_str().hash(state);
-        asm_str_style.hash(state);
-        outputs.len().hash(state);
-        for output in outputs {
-            let InlineAsmOutput { constraint, is_rw, is_indirect } = *output;
-            constraint.as_str().hash(state);
-            is_rw.hash(state);
-            is_indirect.hash(state);
-        }
-        inputs.len().hash(state);
-        for input in inputs {
-            input.as_str().hash(state);
-        }
-        clobbers.len().hash(state);
-        for clobber in clobbers {
-            clobber.as_str().hash(state);
-        }
-        volatile.hash(state);
-        alignstack.hash(state);
-        dialect.hash(state);
-    }
-}
-
-macro_rules! hash_attrs {
-    ($visitor:expr, $attrs:expr) => ({
-        let attrs = $attrs;
-        if attrs.len() > 0 {
-            $visitor.hash_attributes(attrs);
-        }
-    })
-}
-
-macro_rules! hash_span {
-    ($visitor:expr, $span:expr) => ({
-        hash_span!($visitor, $span, false)
-    });
-    ($visitor:expr, $span:expr, $force:expr) => ({
-        if $force || $visitor.hash_spans {
-            $visitor.hash_span($span);
-        }
-    });
-}
-
-impl<'a, 'hash, 'tcx> Visitor<'tcx> for StrictVersionHashVisitor<'a, 'hash, 'tcx> {
-    fn nested_visit_map<'this>(&'this mut self) -> visit::NestedVisitorMap<'this, 'tcx> {
-        if self.hash_bodies {
-            visit::NestedVisitorMap::OnlyBodies(&self.tcx.hir)
-        } else {
-            visit::NestedVisitorMap::None
-        }
-    }
-
-    fn visit_variant_data(&mut self,
-                          s: &'tcx VariantData,
-                          name: Name,
-                          _: &'tcx Generics,
-                          _: NodeId,
-                          span: Span) {
-        debug!("visit_variant_data: st={:?}", self.st);
-        SawStructDef(name.as_str()).hash(self.st);
-        hash_span!(self, span);
-        visit::walk_struct_def(self, s);
-    }
-
-    fn visit_variant(&mut self,
-                     v: &'tcx Variant,
-                     g: &'tcx Generics,
-                     item_id: NodeId) {
-        debug!("visit_variant: st={:?}", self.st);
-        SawVariant(v.node.disr_expr.is_some()).hash(self.st);
-        hash_attrs!(self, &v.node.attrs);
-        visit::walk_variant(self, v, g, item_id)
-    }
-
-    fn visit_name(&mut self, span: Span, name: Name) {
-        debug!("visit_name: st={:?}", self.st);
-        SawIdent(name.as_str()).hash(self.st);
-        hash_span!(self, span);
-    }
-
-    fn visit_lifetime(&mut self, l: &'tcx Lifetime) {
-        debug!("visit_lifetime: st={:?}", self.st);
-        SawLifetime.hash(self.st);
-        visit::walk_lifetime(self, l);
-    }
-
-    fn visit_lifetime_def(&mut self, l: &'tcx LifetimeDef) {
-        debug!("visit_lifetime_def: st={:?}", self.st);
-        SawLifetimeDef(l.bounds.len()).hash(self.st);
-        visit::walk_lifetime_def(self, l);
-    }
-
-    fn visit_expr(&mut self, ex: &'tcx Expr) {
-        debug!("visit_expr: st={:?}", self.st);
-        let (saw_expr, force_span) = saw_expr(&ex.node,
-                                              self.overflow_checks_enabled);
-        SawExpr(saw_expr).hash(self.st);
-        // No need to explicitly hash the discriminant here, since we are
-        // implicitly hashing the discriminant of SawExprComponent.
-        hash_span!(self, ex.span, force_span);
-        hash_attrs!(self, &ex.attrs);
-
-        // Always hash nested constant bodies (e.g. n in `[x; n]`).
-        let hash_bodies = self.hash_bodies;
-        self.hash_bodies = true;
-        visit::walk_expr(self, ex);
-        self.hash_bodies = hash_bodies;
-    }
-
-    fn visit_stmt(&mut self, s: &'tcx Stmt) {
-        debug!("visit_stmt: st={:?}", self.st);
-
-        // We don't want to modify the hash for decls, because
-        // they might be item decls (if they are local decls,
-        // we'll hash that fact in visit_local); but we do want to
-        // remember if this was a StmtExpr or StmtSemi (the later
-        // had an explicit semi-colon; this affects the typing
-        // rules).
-        match s.node {
-            StmtDecl(..) => (),
-            StmtExpr(..) => {
-                SawStmt.hash(self.st);
-                self.hash_discriminant(&s.node);
-                hash_span!(self, s.span);
-            }
-            StmtSemi(..) => {
-                SawStmt.hash(self.st);
-                self.hash_discriminant(&s.node);
-                hash_span!(self, s.span);
-            }
-        }
-
-        visit::walk_stmt(self, s)
-    }
-
-    fn visit_foreign_item(&mut self, i: &'tcx ForeignItem) {
-        debug!("visit_foreign_item: st={:?}", self.st);
-
-        match i.node {
-            ForeignItemFn(..) => {
-                SawForeignItem(SawForeignItemComponent::Fn)
-            }
-            ForeignItemStatic(_, mutable) => {
-                SawForeignItem(SawForeignItemComponent::Static {
-                    mutable: mutable
-                })
-            }
-        }.hash(self.st);
-
-        hash_span!(self, i.span);
-        hash_attrs!(self, &i.attrs);
-        visit::walk_foreign_item(self, i)
-    }
-
-    fn visit_item(&mut self, i: &'tcx Item) {
-        debug!("visit_item: {:?} st={:?}", i, self.st);
-
-        self.maybe_enable_overflow_checks(&i.attrs);
-
-        SawItem(saw_item(&i.node)).hash(self.st);
-        hash_span!(self, i.span);
-        hash_attrs!(self, &i.attrs);
-        visit::walk_item(self, i)
-    }
-
-    fn visit_mod(&mut self, m: &'tcx Mod, span: Span, n: NodeId) {
-        debug!("visit_mod: st={:?}", self.st);
-        SawMod.hash(self.st);
-        hash_span!(self, span);
-        visit::walk_mod(self, m, n)
-    }
-
-    fn visit_ty(&mut self, t: &'tcx Ty) {
-        debug!("visit_ty: st={:?}", self.st);
-        SawTy(saw_ty(&t.node)).hash(self.st);
-        hash_span!(self, t.span);
-
-        // Always hash nested constant bodies (e.g. N in `[T; N]`).
-        let hash_bodies = self.hash_bodies;
-        self.hash_bodies = true;
-        visit::walk_ty(self, t);
-        self.hash_bodies = hash_bodies;
-    }
-
-    fn visit_generics(&mut self, g: &'tcx Generics) {
-        debug!("visit_generics: st={:?}", self.st);
-        SawGenerics.hash(self.st);
-        visit::walk_generics(self, g)
-    }
-
-    fn visit_fn_decl(&mut self, fd: &'tcx FnDecl) {
-        debug!("visit_fn_decl: st={:?}", self.st);
-        SawFnDecl(fd.variadic).hash(self.st);
-        visit::walk_fn_decl(self, fd)
-    }
-
-    fn visit_trait_item(&mut self, ti: &'tcx TraitItem) {
-        debug!("visit_trait_item: st={:?}", self.st);
-
-        self.maybe_enable_overflow_checks(&ti.attrs);
-
-        SawTraitItem(saw_trait_item(&ti.node)).hash(self.st);
-        hash_span!(self, ti.span);
-        hash_attrs!(self, &ti.attrs);
-        visit::walk_trait_item(self, ti)
-    }
-
-    fn visit_impl_item(&mut self, ii: &'tcx ImplItem) {
-        debug!("visit_impl_item: st={:?}", self.st);
-
-        self.maybe_enable_overflow_checks(&ii.attrs);
-
-        SawImplItem(saw_impl_item(&ii.node)).hash(self.st);
-        hash_span!(self, ii.span);
-        hash_attrs!(self, &ii.attrs);
-        visit::walk_impl_item(self, ii)
-    }
-
-    fn visit_struct_field(&mut self, s: &'tcx StructField) {
-        debug!("visit_struct_field: st={:?}", self.st);
-        SawStructField.hash(self.st);
-        hash_span!(self, s.span);
-        hash_attrs!(self, &s.attrs);
-        visit::walk_struct_field(self, s)
-    }
-
-    fn visit_qpath(&mut self, qpath: &'tcx QPath, id: NodeId, span: Span) {
-        debug!("visit_qpath: st={:?}", self.st);
-        SawQPath.hash(self.st);
-        self.hash_discriminant(qpath);
-        visit::walk_qpath(self, qpath, id, span)
-    }
-
-    fn visit_path(&mut self, path: &'tcx Path, _: ast::NodeId) {
-        debug!("visit_path: st={:?}", self.st);
-        hash_span!(self, path.span);
-        visit::walk_path(self, path)
-    }
-
-    fn visit_def_mention(&mut self, def: Def) {
-        self.hash_def(def);
-    }
-
-    fn visit_block(&mut self, b: &'tcx Block) {
-        debug!("visit_block: st={:?}", self.st);
-        SawBlock.hash(self.st);
-        hash_span!(self, b.span);
-        visit::walk_block(self, b)
-    }
-
-    fn visit_pat(&mut self, p: &'tcx Pat) {
-        debug!("visit_pat: st={:?}", self.st);
-        SawPat(saw_pat(&p.node)).hash(self.st);
-        hash_span!(self, p.span);
-        visit::walk_pat(self, p)
-    }
-
-    fn visit_local(&mut self, l: &'tcx Local) {
-        debug!("visit_local: st={:?}", self.st);
-        SawLocal.hash(self.st);
-        hash_attrs!(self, &l.attrs);
-        visit::walk_local(self, l)
-        // No need to hash span, we are hashing all component spans
-    }
-
-    fn visit_arm(&mut self, a: &'tcx Arm) {
-        debug!("visit_arm: st={:?}", self.st);
-        SawArm.hash(self.st);
-        hash_attrs!(self, &a.attrs);
-        visit::walk_arm(self, a)
-    }
-
-    fn visit_id(&mut self, id: NodeId) {
-        debug!("visit_id: id={} st={:?}", id, self.st);
-        self.hash_resolve(id)
-    }
-
-    fn visit_vis(&mut self, v: &'tcx Visibility) {
-        debug!("visit_vis: st={:?}", self.st);
-        SawVis.hash(self.st);
-        self.hash_discriminant(v);
-        visit::walk_vis(self, v)
-    }
-
-    fn visit_associated_item_kind(&mut self, kind: &'tcx AssociatedItemKind) {
-        debug!("visit_associated_item_kind: st={:?}", self.st);
-        SawAssociatedItemKind(*kind).hash(self.st);
-        visit::walk_associated_item_kind(self, kind);
-    }
-
-    fn visit_defaultness(&mut self, defaultness: &'tcx Defaultness) {
-        debug!("visit_associated_item_kind: st={:?}", self.st);
-        SawDefaultness(*defaultness).hash(self.st);
-        visit::walk_defaultness(self, defaultness);
-    }
-
-    fn visit_where_predicate(&mut self, predicate: &'tcx WherePredicate) {
-        debug!("visit_where_predicate: st={:?}", self.st);
-        SawWherePredicate.hash(self.st);
-        self.hash_discriminant(predicate);
-        // Ignoring span. Any important nested components should be visited.
-        visit::walk_where_predicate(self, predicate)
-    }
-
-    fn visit_ty_param_bound(&mut self, bounds: &'tcx TyParamBound) {
-        debug!("visit_ty_param_bound: st={:?}", self.st);
-        SawTyParamBound.hash(self.st);
-        self.hash_discriminant(bounds);
-        // The TraitBoundModifier in TraitTyParamBound will be hash in
-        // visit_poly_trait_ref()
-        visit::walk_ty_param_bound(self, bounds)
-    }
-
-    fn visit_poly_trait_ref(&mut self, t: &'tcx PolyTraitRef, m: TraitBoundModifier) {
-        debug!("visit_poly_trait_ref: st={:?}", self.st);
-        SawPolyTraitRef.hash(self.st);
-        m.hash(self.st);
-        visit::walk_poly_trait_ref(self, t, m)
-    }
-
-    fn visit_path_segment(&mut self, path_span: Span, path_segment: &'tcx PathSegment) {
-        debug!("visit_path_segment: st={:?}", self.st);
-        SawPathSegment.hash(self.st);
-        visit::walk_path_segment(self, path_span, path_segment)
-    }
-
-    fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &'tcx PathParameters) {
-        debug!("visit_path_parameters: st={:?}", self.st);
-        SawPathParameters.hash(self.st);
-        self.hash_discriminant(path_parameters);
-        visit::walk_path_parameters(self, path_span, path_parameters)
-    }
-
-    fn visit_assoc_type_binding(&mut self, type_binding: &'tcx TypeBinding) {
-        debug!("visit_assoc_type_binding: st={:?}", self.st);
-        SawAssocTypeBinding.hash(self.st);
-        hash_span!(self, type_binding.span);
-        visit::walk_assoc_type_binding(self, type_binding)
-    }
-
-    fn visit_attribute(&mut self, _: &ast::Attribute) {
-        // We explicitly do not use this method, since doing that would
-        // implicitly impose an order on the attributes being hashed, while we
-        // explicitly don't want their order to matter
-    }
-
-    fn visit_macro_def(&mut self, macro_def: &'tcx MacroDef) {
-        debug!("visit_macro_def: st={:?}", self.st);
-        SawMacroDef.hash(self.st);
-        hash_attrs!(self, &macro_def.attrs);
-        for tt in macro_def.body.trees() {
-            self.hash_token_tree(&tt);
-        }
-        visit::walk_macro_def(self, macro_def)
-    }
-}
-
-#[derive(Hash)]
-pub enum DefHash {
-    SawDefId,
-    SawLabel,
-    SawPrimTy,
-    SawSelfTy,
-    SawErr,
-}
-
-impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
-    fn hash_resolve(&mut self, id: ast::NodeId) {
-        // Because whether or not a given id has an entry is dependent
-        // solely on expr variant etc, we don't need to hash whether
-        // or not an entry was present (we are already hashing what
-        // variant it is above when we visit the HIR).
-
-        if let Some(traits) = self.tcx.trait_map.get(&id) {
-            debug!("hash_resolve: id={:?} traits={:?} st={:?}", id, traits, self.st);
-            traits.len().hash(self.st);
-
-            // The ordering of the candidates is not fixed. So we hash
-            // the def-ids and then sort them and hash the collection.
-            let mut candidates: Vec<_> =
-                traits.iter()
-                      .map(|&TraitCandidate { def_id, import_id: _ }| {
-                          self.compute_def_id_hash(def_id)
-                      })
-                      .collect();
-            candidates.sort();
-            candidates.hash(self.st);
-        }
-    }
-
-    fn hash_def_id(&mut self, def_id: DefId) {
-        self.compute_def_id_hash(def_id).hash(self.st);
-    }
-
-    fn hash_def(&mut self, def: Def) {
-        match def {
-            // Crucial point: for all of these variants, the variant +
-            // add'l data that is added is always the same if the
-            // def-id is the same, so it suffices to hash the def-id
-            Def::Fn(..) |
-            Def::Mod(..) |
-            Def::Static(..) |
-            Def::Variant(..) |
-            Def::VariantCtor(..) |
-            Def::Enum(..) |
-            Def::TyAlias(..) |
-            Def::AssociatedTy(..) |
-            Def::TyParam(..) |
-            Def::Struct(..) |
-            Def::StructCtor(..) |
-            Def::Union(..) |
-            Def::Trait(..) |
-            Def::Method(..) |
-            Def::Const(..) |
-            Def::AssociatedConst(..) |
-            Def::Local(..) |
-            Def::Upvar(..) |
-            Def::Macro(..) => {
-                DefHash::SawDefId.hash(self.st);
-                self.hash_def_id(def.def_id());
-            }
-
-            Def::Label(..) => {
-                DefHash::SawLabel.hash(self.st);
-                // we don't encode the `id` because it always refers to something
-                // within this item, so if it changed, there would have to be other
-                // changes too
-            }
-            Def::PrimTy(ref prim_ty) => {
-                DefHash::SawPrimTy.hash(self.st);
-                prim_ty.hash(self.st);
-            }
-            Def::SelfTy(..) => {
-                DefHash::SawSelfTy.hash(self.st);
-                // the meaning of Self is always the same within a
-                // given context, so we don't need to hash the other
-                // fields
-            }
-            Def::Err => {
-                DefHash::SawErr.hash(self.st);
-            }
-        }
-    }
-
-    pub fn hash_attributes(&mut self, attributes: &[ast::Attribute]) {
-        debug!("hash_attributes: st={:?}", self.st);
-        let indices = self.indices_sorted_by(attributes, |attr| attr.name());
-
-        for i in indices {
-            let attr = &attributes[i];
-            match attr.name() {
-                Some(name) if IGNORED_ATTRIBUTES.contains(&&*name.as_str()) => continue,
-                _ => {}
-            };
-            if !attr.is_sugared_doc {
-                SawAttribute(attr.style).hash(self.st);
-                for segment in &attr.path.segments {
-                    SawIdent(segment.identifier.name.as_str()).hash(self.st);
-                }
-                for tt in attr.tokens.trees() {
-                    self.hash_token_tree(&tt);
-                }
-            }
-        }
-    }
-
-    fn indices_sorted_by<T, K, F>(&mut self, items: &[T], get_key: F) -> Vec<usize>
-        where K: Ord,
-              F: Fn(&T) -> K
-    {
-        let mut indices = Vec::with_capacity(items.len());
-        indices.extend(0 .. items.len());
-        indices.sort_by_key(|index| get_key(&items[*index]));
-        indices
-    }
-
-    fn maybe_enable_overflow_checks(&mut self, item_attrs: &[ast::Attribute]) {
-        if attr::contains_name(item_attrs, "rustc_inherit_overflow_checks") {
-            self.overflow_checks_enabled = true;
-        }
-    }
-
-    fn hash_token_tree(&mut self, tt: &tokenstream::TokenTree) {
-        self.hash_discriminant(tt);
-        match *tt {
-            tokenstream::TokenTree::Token(span, ref token) => {
-                hash_span!(self, span);
-                self.hash_token(token, span);
-            }
-            tokenstream::TokenTree::Delimited(span, ref delimited) => {
-                hash_span!(self, span);
-                delimited.delim.hash(self.st);
-                for sub_tt in delimited.stream().trees() {
-                    self.hash_token_tree(&sub_tt);
-                }
-            }
-        }
-    }
-
-    fn hash_token(&mut self,
-                  token: &token::Token,
-                  error_reporting_span: Span) {
-        self.hash_discriminant(token);
-        match *token {
-            token::Token::Eq |
-            token::Token::Lt |
-            token::Token::Le |
-            token::Token::EqEq |
-            token::Token::Ne |
-            token::Token::Ge |
-            token::Token::Gt |
-            token::Token::AndAnd |
-            token::Token::OrOr |
-            token::Token::Not |
-            token::Token::Tilde |
-            token::Token::At |
-            token::Token::Dot |
-            token::Token::DotDot |
-            token::Token::DotDotDot |
-            token::Token::Comma |
-            token::Token::Semi |
-            token::Token::Colon |
-            token::Token::ModSep |
-            token::Token::RArrow |
-            token::Token::LArrow |
-            token::Token::FatArrow |
-            token::Token::Pound |
-            token::Token::Dollar |
-            token::Token::Question |
-            token::Token::Underscore |
-            token::Token::Whitespace |
-            token::Token::Comment |
-            token::Token::Eof => {}
-
-            token::Token::BinOp(bin_op_token) |
-            token::Token::BinOpEq(bin_op_token) => bin_op_token.hash(self.st),
-
-            token::Token::OpenDelim(delim_token) |
-            token::Token::CloseDelim(delim_token) => delim_token.hash(self.st),
-
-            token::Token::Literal(ref lit, ref opt_name) => {
-                self.hash_discriminant(lit);
-                match *lit {
-                    token::Lit::Byte(val) |
-                    token::Lit::Char(val) |
-                    token::Lit::Integer(val) |
-                    token::Lit::Float(val) |
-                    token::Lit::Str_(val) |
-                    token::Lit::ByteStr(val) => val.as_str().hash(self.st),
-                    token::Lit::StrRaw(val, n) |
-                    token::Lit::ByteStrRaw(val, n) => {
-                        val.as_str().hash(self.st);
-                        n.hash(self.st);
-                    }
-                };
-                opt_name.map(ast::Name::as_str).hash(self.st);
-            }
-
-            token::Token::Ident(ident) |
-            token::Token::Lifetime(ident) |
-            token::Token::SubstNt(ident) => ident.name.as_str().hash(self.st),
-
-            token::Token::Interpolated(ref non_terminal) => {
-                // FIXME(mw): This could be implemented properly. It's just a
-                //            lot of work, since we would need to hash the AST
-                //            in a stable way, in addition to the HIR.
-                //            Since this is hardly used anywhere, just emit a
-                //            warning for now.
-                if self.tcx.sess.opts.debugging_opts.incremental.is_some() {
-                    let msg = format!("Quasi-quoting might make incremental \
-                                       compilation very inefficient: {:?}",
-                                      non_terminal);
-                    self.tcx.sess.span_warn(error_reporting_span, &msg[..]);
-                }
-
-                non_terminal.hash(self.st);
-            }
-
-            token::Token::DocComment(val) |
-            token::Token::Shebang(val) => val.as_str().hash(self.st),
-        }
-    }
-
-    pub fn hash_crate_root_module(&mut self, krate: &'tcx Crate) {
-        let hir::Crate {
-            ref module,
-            ref attrs,
-            span,
-
-            // These fields are handled separately:
-            exported_macros: _,
-            items: _,
-            trait_items: _,
-            impl_items: _,
-            bodies: _,
-            trait_impls: _,
-            trait_default_impl: _,
-            body_ids: _,
-        } = *krate;
-
-        visit::Visitor::visit_mod(self, module, span, ast::CRATE_NODE_ID);
-        // Crate attributes are not copied over to the root `Mod`, so hash them
-        // explicitly here.
-        hash_attrs!(self, attrs);
-    }
-}
index 477777c975db245a48dc57543fa47afd7253092e..d10df17f85837bc251a7055f04f512704eb5d792 100644 (file)
@@ -22,7 +22,6 @@
 #![feature(rustc_private)]
 #![feature(staged_api)]
 #![feature(rand)]
-#![feature(core_intrinsics)]
 #![feature(conservative_impl_trait)]
 #![cfg_attr(stage0, feature(pub_restricted))]
 
index 2b945e0a3afaff2f8e7d8ffe10335be2e719bbea..7d5887e699fd7fdb2329291736ca32a7130ec1f6 100644 (file)
@@ -259,4 +259,10 @@ fn main() {
             println!("cargo:rustc-link-lib={}", stdcppname);
         }
     }
+
+    // LLVM requires symbols from this library, but apparently they're not printeds
+    // during llvm-config?
+    if target.contains("windows") {
+        println!("cargo:rustc-link-lib=ole32");
+    }
 }
index 26c7a9166e68e9280ed8a683cc421944d530de60..32c9183ece999ff742f7d33f1dd9b0b92fddda20 100644 (file)
@@ -1662,10 +1662,3 @@ pub fn LLVMRustBuildOperandBundleDef(Name: *const c_char,
     pub fn LLVMRustUnsetComdat(V: ValueRef);
     pub fn LLVMRustSetModulePIELevel(M: ModuleRef);
 }
-
-
-// LLVM requires symbols from this library, but apparently they're not printed
-// during llvm-config?
-#[cfg(windows)]
-#[link(name = "ole32")]
-extern "C" {}
index 71e97e4bfe0d3596bbf8b34db481592cc42b08ae..c503b8c7fe06f7bb9c58ed0fce452203e35551e0 100644 (file)
@@ -25,6 +25,9 @@ pub fn block_data_mut(&mut self, blk: BasicBlock) -> &mut BasicBlockData<'tcx> {
         &mut self.basic_blocks[blk]
     }
 
+    // llvm.org/PR32488 makes this function use an excess of stack space. Mark
+    // it as #[inline(never)] to keep rustc's stack use in check.
+    #[inline(never)]
     pub fn start_new_block(&mut self) -> BasicBlock {
         self.basic_blocks.push(BasicBlockData::new(None))
     }
index 05f30f039c8f0649dd3eaf3bab6fc28c909219ee..966cb7ee8d8d83c6299955357d2a2306469c1328 100644 (file)
@@ -222,8 +222,10 @@ fn find_legacy_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>)
             let name = unwrap_or!(attrs[i].name(), continue);
 
             if name == "derive" {
-                let result = attrs[i].parse_list(&self.session.parse_sess,
-                                                 |parser| parser.parse_path(PathStyle::Mod));
+                let result = attrs[i].parse_list(&self.session.parse_sess, |parser| {
+                    parser.parse_path_allowing_meta(PathStyle::Mod)
+                });
+
                 let mut traits = match result {
                     Ok(traits) => traits,
                     Err(mut e) => {
index 7a7fa4eda05a6fd9da7b21fd1c4ea167d6cc69b6..3fd0ce45e3610af20760a82c093a76450a1f6e9d 100644 (file)
@@ -1401,15 +1401,6 @@ fn visit_expr(&mut self, ex: &'l ast::Expr) {
         debug!("visit_expr {:?}", ex.node);
         self.process_macro_use(ex.span, ex.id);
         match ex.node {
-            ast::ExprKind::Call(ref _f, ref _args) => {
-                // Don't need to do anything for function calls,
-                // because just walking the callee path does what we want.
-                visit::walk_expr(self, ex);
-            }
-            ast::ExprKind::Path(_, ref path) => {
-                self.process_path(ex.id, path, None);
-                visit::walk_expr(self, ex);
-            }
             ast::ExprKind::Struct(ref path, ref fields, ref base) => {
                 let hir_expr = self.save_ctxt.tcx.hir.expect_expr(ex.id);
                 let adt = match self.save_ctxt.tables.expr_ty_opt(&hir_expr) {
@@ -1507,6 +1498,8 @@ fn visit_expr(&mut self, ex: &'l ast::Expr) {
                 self.visit_expr(element);
                 self.nest_tables(count.id, |v| v.visit_expr(count));
             }
+            // In particular, we take this branch for call and path expressions,
+            // where we'll index the idents involved just by continuing to walk.
             _ => {
                 visit::walk_expr(self, ex)
             }
@@ -1606,4 +1599,39 @@ fn visit_local(&mut self, l: &'l ast::Local) {
         walk_list!(self, visit_ty, &l.ty);
         walk_list!(self, visit_expr, &l.init);
     }
+
+    fn visit_foreign_item(&mut self, item: &'l ast::ForeignItem) {
+        match item.node {
+            ast::ForeignItemKind::Fn(ref decl, ref generics) => {
+                if let Some(fn_data) = self.save_ctxt.get_extern_item_data(item) {
+                    down_cast_data!(fn_data, FunctionData, item.span);
+                    if !self.span.filter_generated(Some(fn_data.span), item.span) {
+                        self.dumper.function(fn_data.clone().lower(self.tcx));
+                    }
+
+                    self.nest_tables(item.id, |v| v.process_formals(&decl.inputs,
+                                                                    &fn_data.qualname));
+                    self.process_generic_params(generics, item.span, &fn_data.qualname, item.id);
+                }
+
+                for arg in &decl.inputs {
+                    self.visit_ty(&arg.ty);
+                }
+
+                if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output {
+                    self.visit_ty(&ret_ty);
+                }
+            }
+            ast::ForeignItemKind::Static(ref ty, _) => {
+                if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) {
+                    down_cast_data!(var_data, VariableData, item.span);
+                    if !self.span.filter_generated(Some(var_data.span), item.span) {
+                        self.dumper.variable(var_data.lower(self.tcx));
+                    }
+                }
+
+                self.visit_ty(ty);
+            }
+        }
+    }
 }
index 1de9fbc8e4941f04e02d2de4c226c714050f7a31..44615071a56a71eb87e495b03b3907ddb91bcc30 100644 (file)
@@ -120,6 +120,50 @@ pub fn get_external_crates(&self) -> Vec<CrateData> {
         result
     }
 
+    pub fn get_extern_item_data(&self, item: &ast::ForeignItem) -> Option<Data> {
+        let qualname = format!("::{}", self.tcx.node_path_str(item.id));
+        match item.node {
+            ast::ForeignItemKind::Fn(ref decl, ref generics) => {
+                let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Fn);
+                filter!(self.span_utils, sub_span, item.span, None);
+                Some(Data::FunctionData(FunctionData {
+                    id: item.id,
+                    name: item.ident.to_string(),
+                    qualname: qualname,
+                    declaration: None,
+                    span: sub_span.unwrap(),
+                    scope: self.enclosing_scope(item.id),
+                    value: make_signature(decl, generics),
+                    visibility: From::from(&item.vis),
+                    parent: None,
+                    docs: docs_for_attrs(&item.attrs),
+                    sig: self.sig_base_extern(item),
+                    attributes: item.attrs.clone(),
+                }))
+            }
+            ast::ForeignItemKind::Static(ref ty, m) => {
+                let keyword = if m { keywords::Mut } else { keywords::Static };
+                let sub_span = self.span_utils.sub_span_after_keyword(item.span, keyword);
+                filter!(self.span_utils, sub_span, item.span, None);
+                Some(Data::VariableData(VariableData {
+                    id: item.id,
+                    kind: VariableKind::Static,
+                    name: item.ident.to_string(),
+                    qualname: qualname,
+                    span: sub_span.unwrap(),
+                    scope: self.enclosing_scope(item.id),
+                    parent: None,
+                    value: String::new(),
+                    type_value: ty_to_string(ty),
+                    visibility: From::from(&item.vis),
+                    docs: docs_for_attrs(&item.attrs),
+                    sig: Some(self.sig_base_extern(item)),
+                    attributes: item.attrs.clone(),
+                }))
+            }
+        }
+    }
+
     pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
         match item.node {
             ast::ItemKind::Fn(ref decl, .., ref generics, _) => {
@@ -751,6 +795,21 @@ fn sig_base(&self, item: &ast::Item) -> Signature {
         }
     }
 
+    fn sig_base_extern(&self, item: &ast::ForeignItem) -> Signature {
+        let text = self.span_utils.signature_string_for_span(item.span);
+        let name = item.ident.to_string();
+        let ident_start = text.find(&name).expect("Name not in signature?");
+        let ident_end = ident_start + name.len();
+        Signature {
+            span: Span { hi: item.span.lo + BytePos(text.len() as u32), ..item.span },
+            text: text,
+            ident_start: ident_start,
+            ident_end: ident_end,
+            defs: vec![],
+            refs: vec![],
+        }
+    }
+
     #[inline]
     pub fn enclosing_scope(&self, id: NodeId) -> NodeId {
         self.tcx.hir.get_enclosing_scope(id).unwrap_or(CRATE_NODE_ID)
index 8528482c7856cfe5c56120e42369f37c08df4d8e..63cfe591ce366b6fefdd6367de221f214f12610d 100644 (file)
@@ -32,8 +32,7 @@
 
 use {ModuleSource, ModuleTranslation};
 
-const PARTITION_REUSED: &'static str = "rustc_partition_reused";
-const PARTITION_TRANSLATED: &'static str = "rustc_partition_translated";
+use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_TRANSLATED};
 
 const MODULE: &'static str = "module";
 const CFG: &'static str = "cfg";
@@ -62,9 +61,9 @@ struct AssertModuleSource<'a, 'tcx: 'a> {
 
 impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> {
     fn check_attr(&self, attr: &ast::Attribute) {
-        let disposition = if attr.check_name(PARTITION_REUSED) {
+        let disposition = if attr.check_name(ATTR_PARTITION_REUSED) {
             Disposition::Reused
-        } else if attr.check_name(PARTITION_TRANSLATED) {
+        } else if attr.check_name(ATTR_PARTITION_TRANSLATED) {
             Disposition::Translated
         } else {
             return;
index 6d17b2f0eeda3514c3b6079c2c0d92cc7ce315ff..12a1ffa2767255aa325b6f3eff380d6fad49ca44 100644 (file)
@@ -734,9 +734,10 @@ fn link_natively(sess: &Session,
     }
 
     {
-        let mut linker = trans.linker_info.to_linker(&mut cmd, &sess);
+        let mut linker = trans.linker_info.to_linker(cmd, &sess);
         link_args(&mut *linker, sess, crate_type, tmpdir,
                   objects, out_filename, outputs, trans);
+        cmd = linker.finalize();
     }
     cmd.args(&sess.target.target.options.late_link_args);
     for obj in &sess.target.target.options.post_link_objects {
@@ -1021,38 +1022,18 @@ fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
         }
     });
 
-    let pair = sess.cstore.used_libraries().into_iter().filter(|l| {
+    let relevant_libs = sess.cstore.used_libraries().into_iter().filter(|l| {
         relevant_lib(sess, l)
-    }).partition(|lib| {
-        lib.kind == NativeLibraryKind::NativeStatic
     });
-    let (staticlibs, others): (Vec<_>, Vec<_>) = pair;
-
-    // Some platforms take hints about whether a library is static or dynamic.
-    // For those that support this, we ensure we pass the option if the library
-    // was flagged "static" (most defaults are dynamic) to ensure that if
-    // libfoo.a and libfoo.so both exist that the right one is chosen.
-    cmd.hint_static();
 
     let search_path = archive_search_paths(sess);
-    for l in staticlibs {
-        // Here we explicitly ask that the entire archive is included into the
-        // result artifact. For more details see #15460, but the gist is that
-        // the linker will strip away any unused objects in the archive if we
-        // don't otherwise explicitly reference them. This can occur for
-        // libraries which are just providing bindings, libraries with generic
-        // functions, etc.
-        cmd.link_whole_staticlib(&l.name.as_str(), &search_path);
-    }
-
-    cmd.hint_dynamic();
-
-    for lib in others {
+    for lib in relevant_libs {
         match lib.kind {
             NativeLibraryKind::NativeUnknown => cmd.link_dylib(&lib.name.as_str()),
             NativeLibraryKind::NativeFramework => cmd.link_framework(&lib.name.as_str()),
             NativeLibraryKind::NativeStaticNobundle => cmd.link_staticlib(&lib.name.as_str()),
-            NativeLibraryKind::NativeStatic => bug!(),
+            NativeLibraryKind::NativeStatic => cmd.link_whole_staticlib(&lib.name.as_str(),
+                                                                        &search_path)
         }
     }
 }
index 80801e8161cd063e81e1c64b196e5396c11b1b66..a178d17a7c2d371f01e17ce87fc7cd22a41efab7 100644 (file)
@@ -43,7 +43,7 @@ pub fn new(scx: &SharedCrateContext<'a, 'tcx>,
     }
 
     pub fn to_linker(&'a self,
-                     cmd: &'a mut Command,
+                     cmd: Command,
                      sess: &'a Session) -> Box<Linker+'a> {
         if sess.target.target.options.is_like_msvc {
             Box::new(MsvcLinker {
@@ -61,7 +61,8 @@ pub fn to_linker(&'a self,
             Box::new(GnuLinker {
                 cmd: cmd,
                 sess: sess,
-                info: self
+                info: self,
+                hinted_static: false,
             }) as Box<Linker>
         }
     }
@@ -93,30 +94,49 @@ pub trait Linker {
     fn no_default_libraries(&mut self);
     fn build_dylib(&mut self, out_filename: &Path);
     fn args(&mut self, args: &[String]);
-    fn hint_static(&mut self);
-    fn hint_dynamic(&mut self);
-    fn whole_archives(&mut self);
-    fn no_whole_archives(&mut self);
     fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType);
     fn subsystem(&mut self, subsystem: &str);
+    // Should have been finalize(self), but we don't support self-by-value on trait objects (yet?).
+    fn finalize(&mut self) -> Command;
 }
 
 pub struct GnuLinker<'a> {
-    cmd: &'a mut Command,
+    cmd: Command,
     sess: &'a Session,
-    info: &'a LinkerInfo
+    info: &'a LinkerInfo,
+    hinted_static: bool, // Keeps track of the current hinting mode.
 }
 
 impl<'a> GnuLinker<'a> {
     fn takes_hints(&self) -> bool {
         !self.sess.target.target.options.is_like_osx
     }
+
+    // Some platforms take hints about whether a library is static or dynamic.
+    // For those that support this, we ensure we pass the option if the library
+    // was flagged "static" (most defaults are dynamic) to ensure that if
+    // libfoo.a and libfoo.so both exist that the right one is chosen.
+    fn hint_static(&mut self) {
+        if !self.takes_hints() { return }
+        if !self.hinted_static {
+            self.cmd.arg("-Wl,-Bstatic");
+            self.hinted_static = true;
+        }
+    }
+
+    fn hint_dynamic(&mut self) {
+        if !self.takes_hints() { return }
+        if self.hinted_static {
+            self.cmd.arg("-Wl,-Bdynamic");
+            self.hinted_static = false;
+        }
+    }
 }
 
 impl<'a> Linker for GnuLinker<'a> {
-    fn link_dylib(&mut self, lib: &str) { self.cmd.arg("-l").arg(lib); }
-    fn link_staticlib(&mut self, lib: &str) { self.cmd.arg("-l").arg(lib); }
-    fn link_rlib(&mut self, lib: &Path) { self.cmd.arg(lib); }
+    fn link_dylib(&mut self, lib: &str) { self.hint_dynamic(); self.cmd.arg("-l").arg(lib); }
+    fn link_staticlib(&mut self, lib: &str) { self.hint_static(); self.cmd.arg("-l").arg(lib); }
+    fn link_rlib(&mut self, lib: &Path) { self.hint_static(); self.cmd.arg(lib); }
     fn include_path(&mut self, path: &Path) { self.cmd.arg("-L").arg(path); }
     fn framework_path(&mut self, path: &Path) { self.cmd.arg("-F").arg(path); }
     fn output_filename(&mut self, path: &Path) { self.cmd.arg("-o").arg(path); }
@@ -125,14 +145,23 @@ impl<'a> Linker for GnuLinker<'a> {
     fn args(&mut self, args: &[String]) { self.cmd.args(args); }
 
     fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
+        self.hint_dynamic();
         self.cmd.arg("-l").arg(lib);
     }
 
     fn link_framework(&mut self, framework: &str) {
+        self.hint_dynamic();
         self.cmd.arg("-framework").arg(framework);
     }
 
+    // Here we explicitly ask that the entire archive is included into the
+    // result artifact. For more details see #15460, but the gist is that
+    // the linker will strip away any unused objects in the archive if we
+    // don't otherwise explicitly reference them. This can occur for
+    // libraries which are just providing bindings, libraries with generic
+    // functions, etc.
     fn link_whole_staticlib(&mut self, lib: &str, search_path: &[PathBuf]) {
+        self.hint_static();
         let target = &self.sess.target.target;
         if !target.options.is_like_osx {
             self.cmd.arg("-Wl,--whole-archive")
@@ -148,6 +177,7 @@ fn link_whole_staticlib(&mut self, lib: &str, search_path: &[PathBuf]) {
     }
 
     fn link_whole_rlib(&mut self, lib: &Path) {
+        self.hint_static();
         if self.sess.target.target.options.is_like_osx {
             let mut v = OsString::from("-Wl,-force_load,");
             v.push(lib);
@@ -228,26 +258,6 @@ fn build_dylib(&mut self, out_filename: &Path) {
         }
     }
 
-    fn whole_archives(&mut self) {
-        if !self.takes_hints() { return }
-        self.cmd.arg("-Wl,--whole-archive");
-    }
-
-    fn no_whole_archives(&mut self) {
-        if !self.takes_hints() { return }
-        self.cmd.arg("-Wl,--no-whole-archive");
-    }
-
-    fn hint_static(&mut self) {
-        if !self.takes_hints() { return }
-        self.cmd.arg("-Wl,-Bstatic");
-    }
-
-    fn hint_dynamic(&mut self) {
-        if !self.takes_hints() { return }
-        self.cmd.arg("-Wl,-Bdynamic");
-    }
-
     fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) {
         // If we're compiling a dylib, then we let symbol visibility in object
         // files to take care of whether they're exported or not.
@@ -311,10 +321,17 @@ fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) {
     fn subsystem(&mut self, subsystem: &str) {
         self.cmd.arg(&format!("-Wl,--subsystem,{}", subsystem));
     }
+
+    fn finalize(&mut self) -> Command {
+        self.hint_dynamic(); // Reset to default before returning the composed command line.
+        let mut cmd = Command::new("");
+        ::std::mem::swap(&mut cmd, &mut self.cmd);
+        cmd
+    }
 }
 
 pub struct MsvcLinker<'a> {
-    cmd: &'a mut Command,
+    cmd: Command,
     sess: &'a Session,
     info: &'a LinkerInfo
 }
@@ -416,22 +433,6 @@ fn debuginfo(&mut self) {
         self.cmd.arg("/DEBUG");
     }
 
-    fn whole_archives(&mut self) {
-        // hints not supported?
-    }
-    fn no_whole_archives(&mut self) {
-        // hints not supported?
-    }
-
-    // On windows static libraries are of the form `foo.lib` and dynamic
-    // libraries are not linked against directly, but rather through their
-    // import libraries also called `foo.lib`. As a result there's no
-    // possibility for a native library to appear both dynamically and
-    // statically in the same folder so we don't have to worry about hints like
-    // we do on Unix platforms.
-    fn hint_static(&mut self) {}
-    fn hint_dynamic(&mut self) {}
-
     // Currently the compiler doesn't use `dllexport` (an LLVM attribute) to
     // export symbols from a dynamic library. When building a dynamic library,
     // however, we're going to want some symbols exported, so this function
@@ -492,10 +493,16 @@ fn subsystem(&mut self, subsystem: &str) {
             self.cmd.arg("/ENTRY:mainCRTStartup");
         }
     }
+
+    fn finalize(&mut self) -> Command {
+        let mut cmd = Command::new("");
+        ::std::mem::swap(&mut cmd, &mut self.cmd);
+        cmd
+    }
 }
 
 pub struct EmLinker<'a> {
-    cmd: &'a mut Command,
+    cmd: Command,
     sess: &'a Session,
     info: &'a LinkerInfo
 }
@@ -591,22 +598,6 @@ fn build_dylib(&mut self, _out_filename: &Path) {
         bug!("building dynamic library is unsupported on Emscripten")
     }
 
-    fn whole_archives(&mut self) {
-        // noop
-    }
-
-    fn no_whole_archives(&mut self) {
-        // noop
-    }
-
-    fn hint_static(&mut self) {
-        // noop
-    }
-
-    fn hint_dynamic(&mut self) {
-        // noop
-    }
-
     fn export_symbols(&mut self, _tmpdir: &Path, crate_type: CrateType) {
         let symbols = &self.info.exports[&crate_type];
 
@@ -640,6 +631,12 @@ fn export_symbols(&mut self, _tmpdir: &Path, crate_type: CrateType) {
     fn subsystem(&mut self, _subsystem: &str) {
         // noop
     }
+
+    fn finalize(&mut self) -> Command {
+        let mut cmd = Command::new("");
+        ::std::mem::swap(&mut cmd, &mut self.cmd);
+        cmd
+    }
 }
 
 fn exported_symbols(scx: &SharedCrateContext,
index 226d40948c4dc41096e482f3571954aec8319f0a..d69f31a45048d48721e669e0c9af3cfcd56bb18d 100644 (file)
@@ -762,7 +762,6 @@ fn get_personality_slot(&mut self, bcx: &Builder<'a, 'tcx>) -> ValueRef {
             let llretty = Type::struct_(ccx, &[Type::i8p(ccx), Type::i32(ccx)], false);
             let slot = bcx.alloca(llretty, "personalityslot");
             self.llpersonalityslot = Some(slot);
-            Lifetime::Start.call(bcx, slot);
             slot
         }
     }
@@ -794,6 +793,7 @@ fn landing_pad_uncached(&mut self, target_bb: BasicBlockRef) -> BasicBlockRef {
         let llretval = bcx.landing_pad(llretty, llpersonality, 1, self.llfn);
         bcx.set_cleanup(llretval);
         let slot = self.get_personality_slot(&bcx);
+        Lifetime::Start.call(&bcx, slot);
         bcx.store(llretval, slot, None);
         bcx.br(target_bb);
         bcx.llbb()
index 67ee7ef58653057542de300eb054dff68864141b..4b975d7b324f99c492ef96ab3d2a448db289fadf 100644 (file)
@@ -196,19 +196,23 @@ pub fn report_method_error(&self,
 
                                     let field_ty = field.ty(tcx, substs);
 
-                                    if self.is_fn_ty(&field_ty, span) {
-                                        err.help(&format!("use `({0}.{1})(...)` if you \
-                                                           meant to call the function \
-                                                           stored in the `{1}` field",
-                                                          expr_string,
-                                                          item_name));
+                                    if tcx.vis_is_accessible_from(field.vis, self.body_id) {
+                                        if self.is_fn_ty(&field_ty, span) {
+                                            err.help(&format!("use `({0}.{1})(...)` if you \
+                                                               meant to call the function \
+                                                               stored in the `{1}` field",
+                                                              expr_string,
+                                                              item_name));
+                                        } else {
+                                            err.help(&format!("did you mean to write `{0}.{1}` \
+                                                               instead of `{0}.{1}(...)`?",
+                                                              expr_string,
+                                                              item_name));
+                                        }
+                                        err.span_label(span, &"field, not a method");
                                     } else {
-                                        err.help(&format!("did you mean to write `{0}.{1}` \
-                                                           instead of `{0}.{1}(...)`?",
-                                                          expr_string,
-                                                          item_name));
+                                        err.span_label(span, &"private field, not a method");
                                     }
-                                    err.span_label(span, &"field, not a method");
                                     break;
                                 }
                             }
index 4b36072243c810ae1f9b110faa3f8fc69580e784..33280fb931aafebb0fd7431e6fb09d69ffb20adf 100644 (file)
@@ -11,7 +11,6 @@
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::hir;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
-use rustc::lint;
 use rustc::traits::{self, Reveal};
 use rustc::ty::{self, TyCtxt};
 
@@ -53,12 +52,16 @@ enum Namespace {
 
             for &item2 in &impl_items2[..] {
                 if (name, namespace) == name_and_namespace(item2) {
-                    let msg = format!("duplicate definitions with name `{}`", name);
-                    let node_id = self.tcx.hir.as_local_node_id(item1).unwrap();
-                    self.tcx.sess.add_lint(lint::builtin::OVERLAPPING_INHERENT_IMPLS,
-                                           node_id,
-                                           self.tcx.span_of_impl(item1).unwrap(),
-                                           msg);
+                    struct_span_err!(self.tcx.sess,
+                                     self.tcx.span_of_impl(item1).unwrap(),
+                                     E0592,
+                                     "duplicate definitions with name `{}`",
+                                     name)
+                        .span_label(self.tcx.span_of_impl(item1).unwrap(),
+                                    &format!("duplicate definitions for `{}`", name))
+                        .span_label(self.tcx.span_of_impl(item2).unwrap(),
+                                    &format!("other definition for `{}`", name))
+                        .emit();
                 }
             }
         }
index 0b098fb14f1904c2f43a8879ab061d8a8cbe10d3..245a3946a3709c31f8c5e0c759d927e037504d7d 100644 (file)
@@ -427,12 +427,15 @@ fn list_item(parser: &mut ParserWrapper, buffer: &mut String,
                     looper(parser, &mut content, Some(x), toc_builder, shorter, &mut None);
                 }
             }
+            if shorter.is_compact() {
+                break
+            }
         }
         buffer.push_str(&format!("<li>{}</li>", content));
     }
 
     fn list(parser: &mut ParserWrapper, buffer: &mut String, toc_builder: &mut Option<TocBuilder>,
-            shorter: MarkdownOutputStyle) {
+            shorter: MarkdownOutputStyle, is_sorted_list: bool) {
         debug!("List");
         let mut content = String::new();
         while let Some(event) = parser.next() {
@@ -445,8 +448,13 @@ fn list(parser: &mut ParserWrapper, buffer: &mut String, toc_builder: &mut Optio
                     looper(parser, &mut content, Some(x), toc_builder, shorter, &mut None);
                 }
             }
+            if shorter.is_compact() {
+                break
+            }
         }
-        buffer.push_str(&format!("<ul>{}</ul>", content));
+        buffer.push_str(&format!("<{0}>{1}</{0}>",
+                                 if is_sorted_list { "ol" } else { "ul" },
+                                 content));
     }
 
     fn emphasis(parser: &mut ParserWrapper, buffer: &mut String,
@@ -516,8 +524,8 @@ fn looper<'a>(parser: &'a mut ParserWrapper, buffer: &mut String, next_event: Op
                 Event::Start(Tag::BlockQuote) => {
                     blockquote(parser, buffer, toc_builder, shorter);
                 }
-                Event::Start(Tag::List(_)) => {
-                    list(parser, buffer, toc_builder, shorter);
+                Event::Start(Tag::List(x)) => {
+                    list(parser, buffer, toc_builder, shorter, x.is_some());
                 }
                 Event::Start(Tag::Emphasis) => {
                     emphasis(parser, buffer, toc_builder, shorter, id);
index 1cac11f668d95ebc90366af15145066816921d16..b36253862094f4acf1c6aff41f1c89dd23193edb 100644 (file)
@@ -9,6 +9,20 @@
 // except according to those terms.
 
 //! Operations on ASCII strings and characters.
+//!
+//! Most string operations in Rust act on UTF-8 strings. However, at times it
+//! makes more sense to only consider the ASCII character set for a specific
+//! operation.
+//!
+//! The [`AsciiExt`] trait provides methods that allow for character
+//! operations that only act on the ASCII subset and leave non-ASCII characters
+//! alone.
+//!
+//! The [`escape_default`] function provides an iterator over the bytes of an
+//! escaped version of the character given.
+//!
+//! [`AsciiExt`]: trait.AsciiExt.html
+//! [`escape_default`]: fn.escape_default.html
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -53,11 +67,11 @@ pub trait AsciiExt {
     /// use std::ascii::AsciiExt;
     ///
     /// let ascii = 'a';
-    /// let utf8 = '❤';
+    /// let non_ascii = '❤';
     /// let int_ascii = 97;
     ///
     /// assert!(ascii.is_ascii());
-    /// assert!(!utf8.is_ascii());
+    /// assert!(!non_ascii.is_ascii());
     /// assert!(int_ascii.is_ascii());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -79,11 +93,11 @@ pub trait AsciiExt {
     /// use std::ascii::AsciiExt;
     ///
     /// let ascii = 'a';
-    /// let utf8 = '❤';
+    /// let non_ascii = '❤';
     /// let int_ascii = 97;
     ///
     /// assert_eq!('A', ascii.to_ascii_uppercase());
-    /// assert_eq!('❤', utf8.to_ascii_uppercase());
+    /// assert_eq!('❤', non_ascii.to_ascii_uppercase());
     /// assert_eq!(65, int_ascii.to_ascii_uppercase());
     /// ```
     ///
@@ -108,11 +122,11 @@ pub trait AsciiExt {
     /// use std::ascii::AsciiExt;
     ///
     /// let ascii = 'A';
-    /// let utf8 = '❤';
+    /// let non_ascii = '❤';
     /// let int_ascii = 65;
     ///
     /// assert_eq!('a', ascii.to_ascii_lowercase());
-    /// assert_eq!('❤', utf8.to_ascii_lowercase());
+    /// assert_eq!('❤', non_ascii.to_ascii_lowercase());
     /// assert_eq!(97, int_ascii.to_ascii_lowercase());
     /// ```
     ///
@@ -934,8 +948,12 @@ fn is_ascii_control(&self) -> bool {
     }
 }
 
-/// An iterator over the escaped version of a byte, constructed via
-/// `std::ascii::escape_default`.
+/// An iterator over the escaped version of a byte.
+///
+/// This `struct` is created by the [`escape_default`] function. See its
+/// documentation for more.
+///
+/// [`escape_default`]: fn.escape_default.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct EscapeDefault {
     range: Range<usize>,
@@ -966,6 +984,38 @@ pub struct EscapeDefault {
 ///
 /// assert_eq!(b'\\', escaped.next().unwrap());
 /// assert_eq!(b't', escaped.next().unwrap());
+///
+/// let mut escaped = ascii::escape_default(b'\r');
+///
+/// assert_eq!(b'\\', escaped.next().unwrap());
+/// assert_eq!(b'r', escaped.next().unwrap());
+///
+/// let mut escaped = ascii::escape_default(b'\n');
+///
+/// assert_eq!(b'\\', escaped.next().unwrap());
+/// assert_eq!(b'n', escaped.next().unwrap());
+///
+/// let mut escaped = ascii::escape_default(b'\'');
+///
+/// assert_eq!(b'\\', escaped.next().unwrap());
+/// assert_eq!(b'\'', escaped.next().unwrap());
+///
+/// let mut escaped = ascii::escape_default(b'"');
+///
+/// assert_eq!(b'\\', escaped.next().unwrap());
+/// assert_eq!(b'"', escaped.next().unwrap());
+///
+/// let mut escaped = ascii::escape_default(b'\\');
+///
+/// assert_eq!(b'\\', escaped.next().unwrap());
+/// assert_eq!(b'\\', escaped.next().unwrap());
+///
+/// let mut escaped = ascii::escape_default(b'\x9d');
+///
+/// assert_eq!(b'\\', escaped.next().unwrap());
+/// assert_eq!(b'x', escaped.next().unwrap());
+/// assert_eq!(b'9', escaped.next().unwrap());
+/// assert_eq!(b'd', escaped.next().unwrap());
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn escape_default(c: u8) -> EscapeDefault {
index 57332170081465d74afdbe1a1c1269d58d668c97..a06299eaefe0ad47ac8068c65747bb1396fdbd5d 100644 (file)
@@ -472,7 +472,7 @@ fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>)
     }
 
     // Now we've done all our shifting. Return the value we grabbed earlier.
-    (retkey, retval, gap.into_bucket().into_table())
+    (retkey, retval, gap.into_table())
 }
 
 /// Perform robin hood bucket stealing at the given `bucket`. You must
@@ -485,14 +485,14 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
                                 mut key: K,
                                 mut val: V)
                                 -> FullBucketMut<'a, K, V> {
-    let start_index = bucket.index();
     let size = bucket.table().size();
-    // Save the *starting point*.
-    let mut bucket = bucket.stash();
+    let raw_capacity = bucket.table().capacity();
     // There can be at most `size - dib` buckets to displace, because
     // in the worst case, there are `size` elements and we already are
     // `displacement` buckets away from the initial one.
-    let idx_end = start_index + size - bucket.displacement();
+    let idx_end = (bucket.index() + size - bucket.displacement()) % raw_capacity;
+    // Save the *starting point*.
+    let mut bucket = bucket.stash();
 
     loop {
         let (old_hash, old_key, old_val) = bucket.replace(hash, key, val);
@@ -568,11 +568,8 @@ fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> InternalEntry<K, V, &'a mut
     // The caller should ensure that invariants by Robin Hood Hashing hold
     // and that there's space in the underlying table.
     fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) {
-        let raw_cap = self.raw_capacity();
         let mut buckets = Bucket::new(&mut self.table, hash);
-        // note that buckets.index() keeps increasing
-        // even if the pointer wraps back to the first bucket.
-        let limit_bucket = buckets.index() + raw_cap;
+        let start_index = buckets.index();
 
         loop {
             // We don't need to compare hashes for value swap.
@@ -585,7 +582,7 @@ fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) {
                 Full(b) => b.into_bucket(),
             };
             buckets.next();
-            debug_assert!(buckets.index() < limit_bucket);
+            debug_assert!(buckets.index() != start_index);
         }
     }
 }
@@ -1244,24 +1241,25 @@ pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
     pub fn retain<F>(&mut self, mut f: F)
         where F: FnMut(&K, &mut V) -> bool
     {
-        if self.table.capacity() == 0 || self.table.size() == 0 {
+        if self.table.size() == 0 {
             return;
         }
+        let mut elems_left = self.table.size();
         let mut bucket = Bucket::head_bucket(&mut self.table);
         bucket.prev();
-        let tail = bucket.index();
-        loop {
+        let start_index = bucket.index();
+        while elems_left != 0 {
             bucket = match bucket.peek() {
                 Full(mut full) => {
+                    elems_left -= 1;
                     let should_remove = {
                         let (k, v) = full.read_mut();
                         !f(k, v)
                     };
                     if should_remove {
-                        let prev_idx = full.index();
                         let prev_raw = full.raw();
                         let (_, _, t) = pop_internal(full);
-                        Bucket::new_from(prev_raw, prev_idx, t)
+                        Bucket::new_from(prev_raw, t)
                     } else {
                         full.into_bucket()
                     }
@@ -1271,9 +1269,7 @@ pub fn retain<F>(&mut self, mut f: F)
                 }
             };
             bucket.prev();  // reverse iteration
-            if bucket.index() == tail {
-                break;
-            }
+            debug_assert!(elems_left == 0 || bucket.index() != start_index);
         }
     }
 }
index da5fb1a47333ea1757bfa47845fec5baeca9324f..9623706548b322d32c9e2a887e92cf6dbedd810d 100644 (file)
@@ -113,7 +113,7 @@ fn ptr(&self) -> *mut HashUint {
 /// when the RawTable is created and is accessible with the `tag` and `set_tag`
 /// functions.
 pub struct RawTable<K, V> {
-    capacity: usize,
+    capacity_mask: usize,
     size: usize,
     hashes: TaggedHashUintPtr,
 
@@ -125,10 +125,13 @@ pub struct RawTable<K, V> {
 unsafe impl<K: Send, V: Send> Send for RawTable<K, V> {}
 unsafe impl<K: Sync, V: Sync> Sync for RawTable<K, V> {}
 
+// An unsafe view of a RawTable bucket
+// Valid indexes are within [0..table_capacity)
 pub struct RawBucket<K, V> {
-    hash: *mut HashUint,
+    hash_start: *mut HashUint,
     // We use *const to ensure covariance with respect to K and V
-    pair: *const (K, V),
+    pair_start: *const (K, V),
+    idx: usize,
     _marker: marker::PhantomData<(K, V)>,
 }
 
@@ -141,7 +144,6 @@ fn clone(&self) -> RawBucket<K, V> {
 
 pub struct Bucket<K, V, M> {
     raw: RawBucket<K, V>,
-    idx: usize,
     table: M,
 }
 
@@ -154,13 +156,11 @@ fn clone(&self) -> Bucket<K, V, M> {
 
 pub struct EmptyBucket<K, V, M> {
     raw: RawBucket<K, V>,
-    idx: usize,
     table: M,
 }
 
 pub struct FullBucket<K, V, M> {
     raw: RawBucket<K, V>,
-    idx: usize,
     table: M,
 }
 
@@ -232,13 +232,17 @@ fn can_alias_safehash_as_hash() {
     assert_eq!(size_of::<SafeHash>(), size_of::<HashUint>())
 }
 
+// RawBucket methods are unsafe as it's possible to
+// make a RawBucket point to invalid memory using safe code.
 impl<K, V> RawBucket<K, V> {
-    unsafe fn offset(self, count: isize) -> RawBucket<K, V> {
-        RawBucket {
-            hash: self.hash.offset(count),
-            pair: self.pair.offset(count),
-            _marker: marker::PhantomData,
-        }
+    unsafe fn hash(&self) -> *mut HashUint {
+        self.hash_start.offset(self.idx as isize)
+    }
+    unsafe fn pair(&self) -> *mut (K, V) {
+        self.pair_start.offset(self.idx as isize) as *mut (K, V)
+    }
+    unsafe fn hash_pair(&self) -> (*mut HashUint, *mut (K, V)) {
+        (self.hash(), self.pair())
     }
 }
 
@@ -258,7 +262,7 @@ pub fn into_table(self) -> M {
     }
     /// Get the raw index.
     pub fn index(&self) -> usize {
-        self.idx
+        self.raw.idx
     }
     /// Get the raw bucket.
     pub fn raw(&self) -> RawBucket<K, V> {
@@ -280,7 +284,7 @@ pub fn table_mut(&mut self) -> &mut M {
 impl<K, V, M> Bucket<K, V, M> {
     /// Get the raw index.
     pub fn index(&self) -> usize {
-        self.idx
+        self.raw.idx
     }
     /// get the table.
     pub fn into_table(self) -> M {
@@ -331,12 +335,11 @@ pub fn new(table: M, hash: SafeHash) -> Bucket<K, V, M> {
         Bucket::at_index(table, hash.inspect() as usize)
     }
 
-    pub fn new_from(r: RawBucket<K, V>, i: usize, t: M)
+    pub fn new_from(r: RawBucket<K, V>, t: M)
         -> Bucket<K, V, M>
     {
         Bucket {
             raw: r,
-            idx: i,
             table: t,
         }
     }
@@ -346,18 +349,16 @@ pub fn at_index(table: M, ib_index: usize) -> Bucket<K, V, M> {
         // This is an uncommon case though, so avoid it in release builds.
         debug_assert!(table.capacity() > 0,
                       "Table should have capacity at this point");
-        let ib_index = ib_index & (table.capacity() - 1);
+        let ib_index = ib_index & table.capacity_mask;
         Bucket {
-            raw: unsafe { table.first_bucket_raw().offset(ib_index as isize) },
-            idx: ib_index,
+            raw: table.raw_bucket_at(ib_index),
             table: table,
         }
     }
 
     pub fn first(table: M) -> Bucket<K, V, M> {
         Bucket {
-            raw: table.first_bucket_raw(),
-            idx: 0,
+            raw: table.raw_bucket_at(0),
             table: table,
         }
     }
@@ -401,48 +402,30 @@ pub fn head_bucket(table: M) -> Bucket<K, V, M> {
     /// the appropriate types to call most of the other functions in
     /// this module.
     pub fn peek(self) -> BucketState<K, V, M> {
-        match unsafe { *self.raw.hash } {
+        match unsafe { *self.raw.hash() } {
             EMPTY_BUCKET => {
                 Empty(EmptyBucket {
                     raw: self.raw,
-                    idx: self.idx,
                     table: self.table,
                 })
             }
             _ => {
                 Full(FullBucket {
                     raw: self.raw,
-                    idx: self.idx,
                     table: self.table,
                 })
             }
         }
     }
 
-    /// Modifies the bucket pointer in place to make it point to the next slot.
+    /// Modifies the bucket in place to make it point to the next slot.
     pub fn next(&mut self) {
-        self.idx += 1;
-        let range = self.table.capacity();
-        // This code is branchless thanks to a conditional move.
-        let dist = if self.idx & (range - 1) == 0 {
-            1 - range as isize
-        } else {
-            1
-        };
-        unsafe {
-            self.raw = self.raw.offset(dist);
-        }
+        self.raw.idx = self.raw.idx.wrapping_add(1) & self.table.capacity_mask;
     }
 
-    /// Modifies the bucket pointer in place to make it point to the previous slot.
+    /// Modifies the bucket in place to make it point to the previous slot.
     pub fn prev(&mut self) {
-        let range = self.table.capacity();
-        let new_idx = self.idx.wrapping_sub(1) & (range - 1);
-        let dist = (new_idx as isize).wrapping_sub(self.idx as isize);
-        self.idx = new_idx;
-        unsafe {
-            self.raw = self.raw.offset(dist);
-        }
+        self.raw.idx = self.raw.idx.wrapping_sub(1) & self.table.capacity_mask;
     }
 }
 
@@ -458,7 +441,6 @@ pub fn next(self) -> Bucket<K, V, M> {
     pub fn into_bucket(self) -> Bucket<K, V, M> {
         Bucket {
             raw: self.raw,
-            idx: self.idx,
             table: self.table,
         }
     }
@@ -466,7 +448,6 @@ pub fn into_bucket(self) -> Bucket<K, V, M> {
     pub fn gap_peek(self) -> Result<GapThenFull<K, V, M>, Bucket<K, V, M>> {
         let gap = EmptyBucket {
             raw: self.raw,
-            idx: self.idx,
             table: (),
         };
 
@@ -494,15 +475,14 @@ impl<K, V, M> EmptyBucket<K, V, M>
     /// Use `make_hash` to construct a `SafeHash` to pass to this function.
     pub fn put(mut self, hash: SafeHash, key: K, value: V) -> FullBucket<K, V, M> {
         unsafe {
-            *self.raw.hash = hash.inspect();
-            ptr::write(self.raw.pair as *mut (K, V), (key, value));
+            *self.raw.hash() = hash.inspect();
+            ptr::write(self.raw.pair(), (key, value));
 
             self.table.borrow_table_mut().size += 1;
         }
 
         FullBucket {
             raw: self.raw,
-            idx: self.idx,
             table: self.table,
         }
     }
@@ -510,15 +490,14 @@ pub fn put(mut self, hash: SafeHash, key: K, value: V) -> FullBucket<K, V, M> {
     /// Puts given key, remain value uninitialized.
     /// It is only used for inplacement insertion.
     pub unsafe fn put_key(mut self, hash: SafeHash, key: K) -> FullBucket<K, V, M> {
-        *self.raw.hash = hash.inspect();
-        let pair_mut = self.raw.pair as *mut (K, V);
-        ptr::write(&mut (*pair_mut).0, key);
+        *self.raw.hash() = hash.inspect();
+        let pair_ptr = self.raw.pair();
+        ptr::write(&mut (*pair_ptr).0, key);
 
         self.table.borrow_table_mut().size += 1;
 
         FullBucket {
             raw: self.raw,
-            idx: self.idx,
             table: self.table,
         }
     }
@@ -536,7 +515,6 @@ pub fn next(self) -> Bucket<K, V, M> {
     pub fn into_bucket(self) -> Bucket<K, V, M> {
         Bucket {
             raw: self.raw,
-            idx: self.idx,
             table: self.table,
         }
     }
@@ -546,7 +524,6 @@ pub fn into_bucket(self) -> Bucket<K, V, M> {
     pub fn stash(self) -> FullBucket<K, V, Self> {
         FullBucket {
             raw: self.raw,
-            idx: self.idx,
             table: self,
         }
     }
@@ -560,17 +537,20 @@ pub fn displacement(&self) -> usize {
         // Calculates the distance one has to travel when going from
         // `hash mod capacity` onwards to `idx mod capacity`, wrapping around
         // if the destination is not reached before the end of the table.
-        (self.idx.wrapping_sub(self.hash().inspect() as usize)) & (self.table.capacity() - 1)
+        (self.raw.idx.wrapping_sub(self.hash().inspect() as usize)) & self.table.capacity_mask
     }
 
     #[inline]
     pub fn hash(&self) -> SafeHash {
-        unsafe { SafeHash { hash: *self.raw.hash } }
+        unsafe { SafeHash { hash: *self.raw.hash() } }
     }
 
     /// Gets references to the key and value at a given index.
     pub fn read(&self) -> (&K, &V) {
-        unsafe { (&(*self.raw.pair).0, &(*self.raw.pair).1) }
+        unsafe {
+            let pair_ptr = self.raw.pair();
+            (&(*pair_ptr).0, &(*pair_ptr).1)
+        }
     }
 }
 
@@ -586,11 +566,10 @@ pub fn take(mut self) -> (EmptyBucket<K, V, &'t mut RawTable<K, V>>, K, V) {
         self.table.size -= 1;
 
         unsafe {
-            *self.raw.hash = EMPTY_BUCKET;
-            let (k, v) = ptr::read(self.raw.pair);
+            *self.raw.hash() = EMPTY_BUCKET;
+            let (k, v) = ptr::read(self.raw.pair());
             (EmptyBucket {
                  raw: self.raw,
-                 idx: self.idx,
                  table: self.table,
              },
             k,
@@ -604,9 +583,9 @@ pub fn take(mut self) -> (EmptyBucket<K, V, &'t mut RawTable<K, V>>, K, V) {
     pub unsafe fn remove_key(&mut self) {
         self.table.size -= 1;
 
-        *self.raw.hash = EMPTY_BUCKET;
-        let pair_mut = self.raw.pair as *mut (K, V);
-        ptr::drop_in_place(&mut (*pair_mut).0); // only drop key
+        *self.raw.hash() = EMPTY_BUCKET;
+        let pair_ptr = self.raw.pair();
+        ptr::drop_in_place(&mut (*pair_ptr).0); // only drop key
     }
 }
 
@@ -617,8 +596,8 @@ impl<K, V, M> FullBucket<K, V, M>
 {
     pub fn replace(&mut self, h: SafeHash, k: K, v: V) -> (SafeHash, K, V) {
         unsafe {
-            let old_hash = ptr::replace(self.raw.hash as *mut SafeHash, h);
-            let (old_key, old_val) = ptr::replace(self.raw.pair as *mut (K, V), (k, v));
+            let old_hash = ptr::replace(self.raw.hash() as *mut SafeHash, h);
+            let (old_key, old_val) = ptr::replace(self.raw.pair(), (k, v));
 
             (old_hash, old_key, old_val)
         }
@@ -630,8 +609,10 @@ impl<K, V, M> FullBucket<K, V, M>
 {
     /// Gets mutable references to the key and value at a given index.
     pub fn read_mut(&mut self) -> (&mut K, &mut V) {
-        let pair_mut = self.raw.pair as *mut (K, V);
-        unsafe { (&mut (*pair_mut).0, &mut (*pair_mut).1) }
+        unsafe {
+            let pair_ptr = self.raw.pair();
+            (&mut (*pair_ptr).0, &mut (*pair_ptr).1)
+        }
     }
 }
 
@@ -644,7 +625,10 @@ impl<'t, K, V, M> FullBucket<K, V, M>
     /// in exchange for this, the returned references have a longer lifetime
     /// than the references returned by `read()`.
     pub fn into_refs(self) -> (&'t K, &'t V) {
-        unsafe { (&(*self.raw.pair).0, &(*self.raw.pair).1) }
+        unsafe {
+            let pair_ptr = self.raw.pair();
+            (&(*pair_ptr).0, &(*pair_ptr).1)
+        }
     }
 }
 
@@ -654,8 +638,10 @@ impl<'t, K, V, M> FullBucket<K, V, M>
     /// This works similarly to `into_refs`, exchanging a bucket state
     /// for mutable references into the table.
     pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) {
-        let pair_mut = self.raw.pair as *mut (K, V);
-        unsafe { (&mut (*pair_mut).0, &mut (*pair_mut).1) }
+        unsafe {
+            let pair_ptr = self.raw.pair();
+            (&mut (*pair_ptr).0, &mut (*pair_ptr).1)
+        }
     }
 }
 
@@ -667,22 +653,23 @@ pub fn full(&self) -> &FullBucket<K, V, M> {
         &self.full
     }
 
-    pub fn into_bucket(self) -> Bucket<K, V, M> {
-        self.full.into_bucket()
+    pub fn into_table(self) -> M {
+        self.full.into_table()
     }
 
     pub fn shift(mut self) -> Result<GapThenFull<K, V, M>, Bucket<K, V, M>> {
         unsafe {
-            *self.gap.raw.hash = mem::replace(&mut *self.full.raw.hash, EMPTY_BUCKET);
-            ptr::copy_nonoverlapping(self.full.raw.pair, self.gap.raw.pair as *mut (K, V), 1);
+            let (gap_hash, gap_pair) = self.gap.raw.hash_pair();
+            let (full_hash, full_pair) = self.full.raw.hash_pair();
+            *gap_hash = mem::replace(&mut *full_hash, EMPTY_BUCKET);
+            ptr::copy_nonoverlapping(full_pair, gap_pair, 1);
         }
 
-        let FullBucket { raw: prev_raw, idx: prev_idx, .. } = self.full;
+        let FullBucket { raw: prev_raw, .. } = self.full;
 
         match self.full.next().peek() {
             Full(bucket) => {
                 self.gap.raw = prev_raw;
-                self.gap.idx = prev_idx;
 
                 self.full = bucket;
 
@@ -761,7 +748,7 @@ unsafe fn new_uninitialized(capacity: usize) -> RawTable<K, V> {
         if capacity == 0 {
             return RawTable {
                 size: 0,
-                capacity: 0,
+                capacity_mask: capacity.wrapping_sub(1),
                 hashes: TaggedHashUintPtr::new(EMPTY as *mut HashUint),
                 marker: marker::PhantomData,
             };
@@ -801,25 +788,27 @@ unsafe fn new_uninitialized(capacity: usize) -> RawTable<K, V> {
         let hashes = buffer.offset(hash_offset as isize) as *mut HashUint;
 
         RawTable {
-            capacity: capacity,
+            capacity_mask: capacity.wrapping_sub(1),
             size: 0,
             hashes: TaggedHashUintPtr::new(hashes),
             marker: marker::PhantomData,
         }
     }
 
-    fn first_bucket_raw(&self) -> RawBucket<K, V> {
-        let hashes_size = self.capacity * size_of::<HashUint>();
-        let pairs_size = self.capacity * size_of::<(K, V)>();
+    fn raw_bucket_at(&self, index: usize) -> RawBucket<K, V> {
+        let hashes_size = self.capacity() * size_of::<HashUint>();
+        let pairs_size = self.capacity() * size_of::<(K, V)>();
 
-        let buffer = self.hashes.ptr() as *mut u8;
         let (pairs_offset, _, oflo) =
             calculate_offsets(hashes_size, pairs_size, align_of::<(K, V)>());
         debug_assert!(!oflo, "capacity overflow");
+
+        let buffer = self.hashes.ptr() as *mut u8;
         unsafe {
             RawBucket {
-                hash: self.hashes.ptr(),
-                pair: buffer.offset(pairs_offset as isize) as *const _,
+                hash_start: buffer as *mut HashUint,
+                pair_start: buffer.offset(pairs_offset as isize) as *const (K, V),
+                idx: index,
                 _marker: marker::PhantomData,
             }
         }
@@ -837,7 +826,7 @@ pub fn new(capacity: usize) -> RawTable<K, V> {
 
     /// The hashtable's capacity, similar to a vector's.
     pub fn capacity(&self) -> usize {
-        self.capacity
+        self.capacity_mask.wrapping_add(1)
     }
 
     /// The number of elements ever `put` in the hashtable, minus the number
@@ -848,8 +837,8 @@ pub fn size(&self) -> usize {
 
     fn raw_buckets(&self) -> RawBuckets<K, V> {
         RawBuckets {
-            raw: self.first_bucket_raw(),
-            hashes_end: unsafe { self.hashes.ptr().offset(self.capacity as isize) },
+            raw: self.raw_bucket_at(0),
+            elems_left: self.size,
             marker: marker::PhantomData,
         }
     }
@@ -857,25 +846,23 @@ fn raw_buckets(&self) -> RawBuckets<K, V> {
     pub fn iter(&self) -> Iter<K, V> {
         Iter {
             iter: self.raw_buckets(),
-            elems_left: self.size(),
         }
     }
 
     pub fn iter_mut(&mut self) -> IterMut<K, V> {
         IterMut {
             iter: self.raw_buckets(),
-            elems_left: self.size(),
             _marker: marker::PhantomData,
         }
     }
 
     pub fn into_iter(self) -> IntoIter<K, V> {
-        let RawBuckets { raw, hashes_end, .. } = self.raw_buckets();
+        let RawBuckets { raw, elems_left, .. } = self.raw_buckets();
         // Replace the marker regardless of lifetime bounds on parameters.
         IntoIter {
             iter: RawBuckets {
                 raw: raw,
-                hashes_end: hashes_end,
+                elems_left: elems_left,
                 marker: marker::PhantomData,
             },
             table: self,
@@ -883,12 +870,12 @@ pub fn into_iter(self) -> IntoIter<K, V> {
     }
 
     pub fn drain(&mut self) -> Drain<K, V> {
-        let RawBuckets { raw, hashes_end, .. } = self.raw_buckets();
+        let RawBuckets { raw, elems_left, .. } = self.raw_buckets();
         // Replace the marker regardless of lifetime bounds on parameters.
         Drain {
             iter: RawBuckets {
                 raw: raw,
-                hashes_end: hashes_end,
+                elems_left: elems_left,
                 marker: marker::PhantomData,
             },
             table: unsafe { Shared::new(self) },
@@ -900,18 +887,16 @@ pub fn drain(&mut self) -> Drain<K, V> {
     /// state and should only be used for dropping the table's remaining
     /// entries. It's used in the implementation of Drop.
     unsafe fn rev_drop_buckets(&mut self) {
-        let first_raw = self.first_bucket_raw();
-        let mut raw = first_raw.offset(self.capacity as isize);
+        // initialize the raw bucket past the end of the table
+        let mut raw = self.raw_bucket_at(self.capacity());
         let mut elems_left = self.size;
 
         while elems_left != 0 {
-            debug_assert!(raw.hash != first_raw.hash);
+            raw.idx -= 1;
 
-            raw = raw.offset(-1);
-
-            if *raw.hash != EMPTY_BUCKET {
+            if *raw.hash() != EMPTY_BUCKET {
                 elems_left -= 1;
-                ptr::drop_in_place(raw.pair as *mut (K, V));
+                ptr::drop_in_place(raw.pair());
             }
         }
     }
@@ -931,7 +916,7 @@ pub fn tag(&self) -> bool {
 /// this interface is safe, it's not used outside this module.
 struct RawBuckets<'a, K, V> {
     raw: RawBucket<K, V>,
-    hashes_end: *mut HashUint,
+    elems_left: usize,
 
     // Strictly speaking, this should be &'a (K,V), but that would
     // require that K:'a, and we often use RawBuckets<'static...> for
@@ -946,7 +931,7 @@ impl<'a, K, V> Clone for RawBuckets<'a, K, V> {
     fn clone(&self) -> RawBuckets<'a, K, V> {
         RawBuckets {
             raw: self.raw,
-            hashes_end: self.hashes_end,
+            elems_left: self.elems_left,
             marker: marker::PhantomData,
         }
     }
@@ -957,25 +942,36 @@ impl<'a, K, V> Iterator for RawBuckets<'a, K, V> {
     type Item = RawBucket<K, V>;
 
     fn next(&mut self) -> Option<RawBucket<K, V>> {
-        while self.raw.hash != self.hashes_end {
+        if self.elems_left == 0 {
+            return None;
+        }
+
+        loop {
             unsafe {
-                // We are swapping out the pointer to a bucket and replacing
-                // it with the pointer to the next one.
-                let prev = ptr::replace(&mut self.raw, self.raw.offset(1));
-                if *prev.hash != EMPTY_BUCKET {
-                    return Some(prev);
+                let item = self.raw;
+                self.raw.idx += 1;
+                if *item.hash() != EMPTY_BUCKET {
+                    self.elems_left -= 1;
+                    return Some(item);
                 }
             }
         }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.elems_left, Some(self.elems_left))
+    }
+}
 
-        None
+impl<'a, K, V> ExactSizeIterator for RawBuckets<'a, K, V> {
+    fn len(&self) -> usize {
+        self.elems_left
     }
 }
 
 /// Iterator over shared references to entries in a table.
 pub struct Iter<'a, K: 'a, V: 'a> {
     iter: RawBuckets<'a, K, V>,
-    elems_left: usize,
 }
 
 unsafe impl<'a, K: Sync, V: Sync> Sync for Iter<'a, K, V> {}
@@ -986,16 +982,13 @@ impl<'a, K, V> Clone for Iter<'a, K, V> {
     fn clone(&self) -> Iter<'a, K, V> {
         Iter {
             iter: self.iter.clone(),
-            elems_left: self.elems_left,
         }
     }
 }
 
-
 /// Iterator over mutable references to entries in a table.
 pub struct IterMut<'a, K: 'a, V: 'a> {
     iter: RawBuckets<'a, K, V>,
-    elems_left: usize,
     // To ensure invariance with respect to V
     _marker: marker::PhantomData<&'a mut V>,
 }
@@ -1009,7 +1002,6 @@ impl<'a, K: 'a, V: 'a> IterMut<'a, K, V> {
     pub fn iter(&self) -> Iter<K, V> {
         Iter {
             iter: self.iter.clone(),
-            elems_left: self.elems_left,
         }
     }
 }
@@ -1027,7 +1019,6 @@ impl<K, V> IntoIter<K, V> {
     pub fn iter(&self) -> Iter<K, V> {
         Iter {
             iter: self.iter.clone(),
-            elems_left: self.table.size,
         }
     }
 }
@@ -1044,11 +1035,8 @@ unsafe impl<'a, K: Send, V: Send> Send for Drain<'a, K, V> {}
 
 impl<'a, K, V> Drain<'a, K, V> {
     pub fn iter(&self) -> Iter<K, V> {
-        unsafe {
-            Iter {
-                iter: self.iter.clone(),
-                elems_left: (**self.table).size,
-            }
+        Iter {
+            iter: self.iter.clone(),
         }
     }
 }
@@ -1057,19 +1045,20 @@ impl<'a, K, V> Iterator for Iter<'a, K, V> {
     type Item = (&'a K, &'a V);
 
     fn next(&mut self) -> Option<(&'a K, &'a V)> {
-        self.iter.next().map(|bucket| {
-            self.elems_left -= 1;
-            unsafe { (&(*bucket.pair).0, &(*bucket.pair).1) }
+        self.iter.next().map(|raw| unsafe {
+            let pair_ptr = raw.pair();
+            (&(*pair_ptr).0, &(*pair_ptr).1)
         })
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.elems_left, Some(self.elems_left))
+        self.iter.size_hint()
     }
 }
+
 impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
     fn len(&self) -> usize {
-        self.elems_left
+        self.iter.len()
     }
 }
 
@@ -1077,20 +1066,20 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
     type Item = (&'a K, &'a mut V);
 
     fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
-        self.iter.next().map(|bucket| {
-            self.elems_left -= 1;
-            let pair_mut = bucket.pair as *mut (K, V);
-            unsafe { (&(*pair_mut).0, &mut (*pair_mut).1) }
+        self.iter.next().map(|raw| unsafe {
+            let pair_ptr = raw.pair();
+            (&(*pair_ptr).0, &mut (*pair_ptr).1)
         })
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.elems_left, Some(self.elems_left))
+        self.iter.size_hint()
     }
 }
+
 impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
     fn len(&self) -> usize {
-        self.elems_left
+        self.iter.len()
     }
 }
 
@@ -1098,23 +1087,23 @@ impl<K, V> Iterator for IntoIter<K, V> {
     type Item = (SafeHash, K, V);
 
     fn next(&mut self) -> Option<(SafeHash, K, V)> {
-        self.iter.next().map(|bucket| {
+        self.iter.next().map(|raw| {
             self.table.size -= 1;
             unsafe {
-                let (k, v) = ptr::read(bucket.pair);
-                (SafeHash { hash: *bucket.hash }, k, v)
+                let (k, v) = ptr::read(raw.pair());
+                (SafeHash { hash: *raw.hash() }, k, v)
             }
         })
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let size = self.table.size();
-        (size, Some(size))
+        self.iter.size_hint()
     }
 }
+
 impl<K, V> ExactSizeIterator for IntoIter<K, V> {
     fn len(&self) -> usize {
-        self.table.size()
+        self.iter().len()
     }
 }
 
@@ -1123,23 +1112,21 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> {
 
     #[inline]
     fn next(&mut self) -> Option<(SafeHash, K, V)> {
-        self.iter.next().map(|bucket| {
-            unsafe {
-                (*self.table.as_mut_ptr()).size -= 1;
-                let (k, v) = ptr::read(bucket.pair);
-                (SafeHash { hash: ptr::replace(bucket.hash, EMPTY_BUCKET) }, k, v)
-            }
+        self.iter.next().map(|raw| unsafe {
+            (*self.table.as_mut_ptr()).size -= 1;
+            let (k, v) = ptr::read(raw.pair());
+            (SafeHash { hash: ptr::replace(&mut *raw.hash(), EMPTY_BUCKET) }, k, v)
         })
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let size = unsafe { (**self.table).size() };
-        (size, Some(size))
+        self.iter.size_hint()
     }
 }
+
 impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
     fn len(&self) -> usize {
-        unsafe { (**self.table).size() }
+        self.iter.len()
     }
 }
 
@@ -1152,30 +1139,21 @@ fn drop(&mut self) {
 impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
     fn clone(&self) -> RawTable<K, V> {
         unsafe {
-            let mut new_ht = RawTable::new_uninitialized(self.capacity());
-
-            {
-                let cap = self.capacity();
-                let mut new_buckets = Bucket::first(&mut new_ht);
-                let mut buckets = Bucket::first(self);
-                while buckets.index() != cap {
-                    match buckets.peek() {
-                        Full(full) => {
-                            let (h, k, v) = {
-                                let (k, v) = full.read();
-                                (full.hash(), k.clone(), v.clone())
-                            };
-                            *new_buckets.raw.hash = h.inspect();
-                            ptr::write(new_buckets.raw.pair as *mut (K, V), (k, v));
-                        }
-                        Empty(..) => {
-                            *new_buckets.raw.hash = EMPTY_BUCKET;
-                        }
-                    }
-                    new_buckets.next();
-                    buckets.next();
+            let cap = self.capacity();
+            let mut new_ht = RawTable::new_uninitialized(cap);
+
+            let mut new_buckets = new_ht.raw_bucket_at(0);
+            let mut buckets = self.raw_bucket_at(0);
+            while buckets.idx < cap {
+                *new_buckets.hash() = *buckets.hash();
+                if *new_buckets.hash() != EMPTY_BUCKET {
+                    let pair_ptr = buckets.pair();
+                    let kv = ((*pair_ptr).0.clone(), (*pair_ptr).1.clone());
+                    ptr::write(new_buckets.pair(), kv);
                 }
-            };
+                buckets.idx += 1;
+                new_buckets.idx += 1;
+            }
 
             new_ht.size = self.size();
 
@@ -1186,7 +1164,7 @@ fn clone(&self) -> RawTable<K, V> {
 
 unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> {
     fn drop(&mut self) {
-        if self.capacity == 0 {
+        if self.capacity() == 0 {
             return;
         }
 
@@ -1202,8 +1180,8 @@ fn drop(&mut self) {
             }
         }
 
-        let hashes_size = self.capacity * size_of::<HashUint>();
-        let pairs_size = self.capacity * size_of::<(K, V)>();
+        let hashes_size = self.capacity() * size_of::<HashUint>();
+        let pairs_size = self.capacity() * size_of::<(K, V)>();
         let (align, _, size, oflo) = calculate_allocation(hashes_size,
                                                           align_of::<HashUint>(),
                                                           pairs_size,
index ca26dc9527c041e86061ff9c1f11ffbec73827f4..1b00eb95de2bc434340918ffeeda17c62d2ce8db 100644 (file)
@@ -1726,9 +1726,9 @@ pub fn new() -> DirBuilder {
         }
     }
 
-    /// Indicate that directories create should be created recursively, creating
-    /// all parent directories if they do not exist with the same security and
-    /// permissions settings.
+    /// Indicates that directories should be created recursively, creating all
+    /// parent directories. Parents that do not exist are created with the same
+    /// security and permissions settings.
     ///
     /// This option defaults to `false`.
     ///
@@ -1749,6 +1749,9 @@ pub fn recursive(&mut self, recursive: bool) -> &mut Self {
     /// Create the specified directory with the options configured in this
     /// builder.
     ///
+    /// It is considered an error if the directory already exists unless
+    /// recursive mode is enabled.
+    ///
     /// # Examples
     ///
     /// ```no_run
index 295a49d6a8e8916050ad20267b666b06bce6c07f..a7b01e49d2bb625f2654b1bd13d5e30c81fae272 100644 (file)
@@ -50,12 +50,11 @@ struct BarrierState {
     generation_id: usize,
 }
 
-/// A result returned from wait.
+/// A `BarrierWaitResult` is returned by [`wait`] when all threads in the [`Barrier`]
+/// have rendezvoused.
 ///
-/// Currently this opaque structure only has one method, [`.is_leader`]. Only
-/// one thread will receive a result that will return `true` from this function.
-///
-/// [`.is_leader`]: #method.is_leader
+/// [`wait`]: struct.Barrier.html#method.wait
+/// [`Barrier`]: struct.Barrier.html
 ///
 /// # Examples
 ///
index 71dd94161c03df8625c719e73a2e595fccbdea72..0da65a4f2e12f2c9ed8d256d583515612a888092 100644 (file)
 //! This module provides message-based communication over channels, concretely
 //! defined among three types:
 //!
-//! * `Sender`
-//! * `SyncSender`
-//! * `Receiver`
+//! * [`Sender`]
+//! * [`SyncSender`]
+//! * [`Receiver`]
 //!
-//! A `Sender` or `SyncSender` is used to send data to a `Receiver`. Both
+//! A [`Sender`] or [`SyncSender`] is used to send data to a [`Receiver`]. Both
 //! senders are clone-able (multi-producer) such that many threads can send
 //! simultaneously to one receiver (single-consumer).
 //!
 //! These channels come in two flavors:
 //!
-//! 1. An asynchronous, infinitely buffered channel. The `channel()` function
+//! 1. An asynchronous, infinitely buffered channel. The [`channel`] function
 //!    will return a `(Sender, Receiver)` tuple where all sends will be
 //!    **asynchronous** (they never block). The channel conceptually has an
 //!    infinite buffer.
 //!
-//! 2. A synchronous, bounded channel. The `sync_channel()` function will return
-//!    a `(SyncSender, Receiver)` tuple where the storage for pending messages
-//!    is a pre-allocated buffer of a fixed size. All sends will be
+//! 2. A synchronous, bounded channel. The [`sync_channel`] function will
+//!    return a `(SyncSender, Receiver)` tuple where the storage for pending
+//!    messages is a pre-allocated buffer of a fixed size. All sends will be
 //!    **synchronous** by blocking until there is buffer space available. Note
-//!    that a bound of 0 is allowed, causing the channel to become a
-//!    "rendezvous" channel where each sender atomically hands off a message to
-//!    a receiver.
+//!    that a bound of 0 is allowed, causing the channel to become a "rendezvous"
+//!    channel where each sender atomically hands off a message to a receiver.
+//!
+//! [`Sender`]: ../../../std/sync/mpsc/struct.Sender.html
+//! [`SyncSender`]: ../../../std/sync/mpsc/struct.SyncSender.html
+//! [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html
+//! [`send`]: ../../../std/sync/mpsc/struct.Sender.html#method.send
+//! [`channel`]: ../../../std/sync/mpsc/fn.channel.html
+//! [`sync_channel`]: ../../../std/sync/mpsc/fn.sync_channel.html
 //!
 //! ## Disconnection
 //!
-//! The send and receive operations on channels will all return a `Result`
+//! The send and receive operations on channels will all return a [`Result`]
 //! indicating whether the operation succeeded or not. An unsuccessful operation
 //! is normally indicative of the other half of a channel having "hung up" by
 //! being dropped in its corresponding thread.
 //!
 //! Once half of a channel has been deallocated, most operations can no longer
-//! continue to make progress, so `Err` will be returned. Many applications will
-//! continue to `unwrap()` the results returned from this module, instigating a
-//! propagation of failure among threads if one unexpectedly dies.
+//! continue to make progress, so [`Err`] will be returned. Many applications
+//! will continue to [`unwrap`] the results returned from this module,
+//! instigating a propagation of failure among threads if one unexpectedly dies.
+//!
+//! [`Result`]: ../../../std/result/enum.Result.html
+//! [`Err`]: ../../../std/result/enum.Result.html#variant.Err
+//! [`unwrap`]: ../../../std/result/enum.Result.html#method.unwrap
 //!
 //! # Examples
 //!
 mod spsc_queue;
 
 /// The receiving-half of Rust's channel type. This half can only be owned by
-/// one thread
+/// one thread.
+///
+/// Messages sent to the channel can be retrieved using [`recv`].
+///
+/// [`recv`]: ../../../std/sync/mpsc/struct.Receiver.html#method.recv
+///
+/// # Examples
+///
+/// ```rust
+/// use std::sync::mpsc::channel;
+/// use std::thread;
+/// use std::time::Duration;
+///
+/// let (send, recv) = channel();
+///
+/// thread::spawn(move || {
+///     send.send("Hello world!").unwrap();
+///     thread::sleep(Duration::from_secs(2)); // block for two seconds
+///     send.send("Delayed for 2 seconds").unwrap();
+/// });
+///
+/// println!("{}", recv.recv().unwrap()); // Received immediately
+/// println!("Waiting...");
+/// println!("{}", recv.recv().unwrap()); // Received after 2 seconds
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Receiver<T> {
     inner: UnsafeCell<Flavor<T>>,
@@ -302,9 +336,12 @@ unsafe impl<T: Send> Send for Receiver<T> { }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> !Sync for Receiver<T> { }
 
-/// An iterator over messages on a receiver, this iterator will block
-/// whenever `next` is called, waiting for a new message, and `None` will be
-/// returned when the corresponding channel has hung up.
+/// An iterator over messages on a receiver, this iterator will block whenever
+/// [`next`] is called, waiting for a new message, and [`None`] will be returned
+/// when the corresponding channel has hung up.
+///
+/// [`next`]: ../../../std/iter/trait.Iterator.html#tymethod.next
+/// [`None`]: ../../../std/option/enum.Option.html#variant.None
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 pub struct Iter<'a, T: 'a> {
@@ -312,11 +349,13 @@ pub struct Iter<'a, T: 'a> {
 }
 
 /// An iterator that attempts to yield all pending values for a receiver.
-/// `None` will be returned when there are no pending values remaining or
-/// if the corresponding channel has hung up.
+/// [`None`] will be returned when there are no pending values remaining or if
+/// the corresponding channel has hung up.
 ///
 /// This Iterator will never block the caller in order to wait for data to
-/// become available. Instead, it will return `None`.
+/// become available. Instead, it will return [`None`].
+///
+/// [`None`]: ../../../std/option/enum.Option.html#variant.None
 #[stable(feature = "receiver_try_iter", since = "1.15.0")]
 #[derive(Debug)]
 pub struct TryIter<'a, T: 'a> {
@@ -324,8 +363,12 @@ pub struct TryIter<'a, T: 'a> {
 }
 
 /// An owning iterator over messages on a receiver, this iterator will block
-/// whenever `next` is called, waiting for a new message, and `None` will be
+/// whenever [`next`] is called, waiting for a new message, and [`None`] will be
 /// returned when the corresponding channel has hung up.
+///
+/// [`next`]: ../../../std/iter/trait.Iterator.html#tymethod.next
+/// [`None`]: ../../../std/option/enum.Option.html#variant.None
+///
 #[stable(feature = "receiver_into_iter", since = "1.1.0")]
 #[derive(Debug)]
 pub struct IntoIter<T> {
@@ -334,6 +377,35 @@ pub struct IntoIter<T> {
 
 /// The sending-half of Rust's asynchronous channel type. This half can only be
 /// owned by one thread, but it can be cloned to send to other threads.
+///
+/// Messages can be sent through this channel with [`send`].
+///
+/// [`send`]: ../../../std/sync/mpsc/struct.Sender.html#method.send
+///
+/// # Examples
+///
+/// ```rust
+/// use std::sync::mpsc::channel;
+/// use std::thread;
+///
+/// let (sender, receiver) = channel();
+/// let sender2 = sender.clone();
+///
+/// // First thread owns sender
+/// thread::spawn(move || {
+///     sender.send(1).unwrap();
+/// });
+///
+/// // Second thread owns sender2
+/// thread::spawn(move || {
+///     sender2.send(2).unwrap();
+/// });
+///
+/// let msg = receiver.recv().unwrap();
+/// let msg2 = receiver.recv().unwrap();
+///
+/// assert_eq!(3, msg + msg2);
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Sender<T> {
     inner: UnsafeCell<Flavor<T>>,
@@ -349,6 +421,10 @@ impl<T> !Sync for Sender<T> { }
 
 /// The sending-half of Rust's synchronous channel type. This half can only be
 /// owned by one thread, but it can be cloned to send to other threads.
+///
+/// [`send`]: ../../../std/sync/mpsc/struct.Sender.html#method.send
+/// [`SyncSender::send`]: ../../../std/sync/mpsc/struct.SyncSender.html#method.send
+///
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct SyncSender<T> {
     inner: Arc<sync::Packet<T>>,
@@ -360,25 +436,32 @@ unsafe impl<T: Send> Send for SyncSender<T> {}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> !Sync for SyncSender<T> {}
 
-/// An error returned from the `send` function on channels.
+/// An error returned from the [`send`] function on channels.
 ///
-/// A `send` operation can only fail if the receiving end of a channel is
+/// A [`send`] operation can only fail if the receiving end of a channel is
 /// disconnected, implying that the data could never be received. The error
 /// contains the data being sent as a payload so it can be recovered.
+///
+/// [`send`]: ../../../std/sync/mpsc/struct.Sender.html#method.send
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(PartialEq, Eq, Clone, Copy)]
 pub struct SendError<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
 
-/// An error returned from the `recv` function on a `Receiver`.
+/// An error returned from the [`recv`] function on a [`Receiver`].
 ///
-/// The `recv` operation can only fail if the sending half of a channel is
+/// The [`recv`] operation can only fail if the sending half of a channel is
 /// disconnected, implying that no further messages will ever be received.
+///
+/// [`recv`]: ../../../std/sync/mpsc/struct.Receiver.html#method.recv
+/// [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RecvError;
 
-/// This enumeration is the list of the possible reasons that `try_recv` could
+/// This enumeration is the list of the possible reasons that [`try_recv`] could
 /// not return data when called.
+///
+/// [`try_recv`]: ../../../std/sync/mpsc/struct.Receiver.html#method.try_recv
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum TryRecvError {
@@ -393,8 +476,10 @@ pub enum TryRecvError {
     Disconnected,
 }
 
-/// This enumeration is the list of possible errors that `recv_timeout` could
+/// This enumeration is the list of possible errors that [`recv_timeout`] could
 /// not return data when called.
+///
+/// [`recv_timeout`]: ../../../std/sync/mpsc/struct.Receiver.html#method.recv_timeout
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 #[stable(feature = "mpsc_recv_timeout", since = "1.12.0")]
 pub enum RecvTimeoutError {
@@ -409,7 +494,9 @@ pub enum RecvTimeoutError {
 }
 
 /// This enumeration is the list of the possible error outcomes for the
-/// `SyncSender::try_send` method.
+/// [`SyncSender::try_send`] method.
+///
+/// [`SyncSender::try_send`]: ../../../std/sync/mpsc/struct.SyncSender.html#method.try_send
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(PartialEq, Eq, Clone, Copy)]
 pub enum TrySendError<T> {
@@ -556,10 +643,13 @@ fn new(inner: Flavor<T>) -> Sender<T> {
     /// A successful send occurs when it is determined that the other end of
     /// the channel has not hung up already. An unsuccessful send would be one
     /// where the corresponding receiver has already been deallocated. Note
-    /// that a return value of `Err` means that the data will never be
-    /// received, but a return value of `Ok` does *not* mean that the data
+    /// that a return value of [`Err`] means that the data will never be
+    /// received, but a return value of [`Ok`] does *not* mean that the data
     /// will be received.  It is possible for the corresponding receiver to
-    /// hang up immediately after this function returns `Ok`.
+    /// hang up immediately after this function returns [`Ok`].
+    ///
+    /// [`Err`]: ../../../std/result/enum.Result.html#variant.Err
+    /// [`Ok`]: ../../../std/result/enum.Result.html#variant.Ok
     ///
     /// This method will never block the current thread.
     ///
@@ -702,9 +792,12 @@ fn new(inner: Arc<sync::Packet<T>>) -> SyncSender<T> {
     /// time. If the buffer size is 0, however, it can be guaranteed that the
     /// receiver has indeed received the data if this function returns success.
     ///
-    /// This function will never panic, but it may return `Err` if the
-    /// `Receiver` has disconnected and is no longer able to receive
+    /// This function will never panic, but it may return [`Err`] if the
+    /// [`Receiver`] has disconnected and is no longer able to receive
     /// information.
+    ///
+    /// [`Err`]: ../../../std/result/enum.Result.html#variant.Err
+    /// [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn send(&self, t: T) -> Result<(), SendError<T>> {
         self.inner.send(t).map_err(SendError)
@@ -712,13 +805,16 @@ pub fn send(&self, t: T) -> Result<(), SendError<T>> {
 
     /// Attempts to send a value on this channel without blocking.
     ///
-    /// This method differs from `send` by returning immediately if the
+    /// This method differs from [`send`] by returning immediately if the
     /// channel's buffer is full or no receiver is waiting to acquire some
-    /// data. Compared with `send`, this function has two failure cases
+    /// data. Compared with [`send`], this function has two failure cases
     /// instead of one (one for disconnection, one for a full buffer).
     ///
-    /// See `SyncSender::send` for notes about guarantees of whether the
+    /// See [`SyncSender::send`] for notes about guarantees of whether the
     /// receiver has received the data or not if this function is successful.
+    ///
+    /// [`send`]: ../../../std/sync/mpsc/struct.Sender.html#method.send
+    /// [`SyncSender::send`]: ../../../std/sync/mpsc/struct.SyncSender.html#method.send
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> {
         self.inner.try_send(t)
@@ -819,15 +915,18 @@ pub fn try_recv(&self) -> Result<T, TryRecvError> {
     ///
     /// This function will always block the current thread if there is no data
     /// available and it's possible for more data to be sent. Once a message is
-    /// sent to the corresponding `Sender`, then this receiver will wake up and
+    /// sent to the corresponding [`Sender`], then this receiver will wake up and
     /// return that message.
     ///
-    /// If the corresponding `Sender` has disconnected, or it disconnects while
-    /// this call is blocking, this call will wake up and return `Err` to
+    /// If the corresponding [`Sender`] has disconnected, or it disconnects while
+    /// this call is blocking, this call will wake up and return [`Err`] to
     /// indicate that no more messages can ever be received on this channel.
     /// However, since channels are buffered, messages sent before the disconnect
     /// will still be properly received.
     ///
+    /// [`Sender`]: ../../../std/sync/mpsc/struct.Sender.html
+    /// [`Err`]: ../../../std/result/enum.Result.html#variant.Err
+    ///
     /// # Examples
     ///
     /// ```
@@ -907,15 +1006,18 @@ pub fn recv(&self) -> Result<T, RecvError> {
     ///
     /// This function will always block the current thread if there is no data
     /// available and it's possible for more data to be sent. Once a message is
-    /// sent to the corresponding `Sender`, then this receiver will wake up and
+    /// sent to the corresponding [`Sender`], then this receiver will wake up and
     /// return that message.
     ///
-    /// If the corresponding `Sender` has disconnected, or it disconnects while
-    /// this call is blocking, this call will wake up and return `Err` to
+    /// If the corresponding [`Sender`] has disconnected, or it disconnects while
+    /// this call is blocking, this call will wake up and return [`Err`] to
     /// indicate that no more messages can ever be received on this channel.
     /// However, since channels are buffered, messages sent before the disconnect
     /// will still be properly received.
     ///
+    /// [`Sender`]: ../../../std/sync/mpsc/struct.Sender.html
+    /// [`Err`]: ../../../std/result/enum.Result.html#variant.Err
+    ///
     /// # Examples
     ///
     /// ```no_run
@@ -993,7 +1095,29 @@ fn recv_max_until(&self, deadline: Instant) -> Result<T, RecvTimeoutError> {
     }
 
     /// Returns an iterator that will block waiting for messages, but never
-    /// `panic!`. It will return `None` when the channel has hung up.
+    /// [`panic!`]. It will return [`None`] when the channel has hung up.
+    ///
+    /// [`panic!`]: ../../../std/macro.panic.html
+    /// [`None`]: ../../../std/option/enum.Option.html#variant.None
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::sync::mpsc::channel;
+    /// use std::thread;
+    ///
+    /// let (send, recv) = channel();
+    ///
+    /// thread::spawn(move || {
+    ///     send.send(1u8).unwrap();
+    ///     send.send(2u8).unwrap();
+    ///     send.send(3u8).unwrap();
+    /// });
+    ///
+    /// for x in recv.iter() {
+    ///     println!("Got: {}", x);
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter(&self) -> Iter<T> {
         Iter { rx: self }
@@ -1001,8 +1125,10 @@ pub fn iter(&self) -> Iter<T> {
 
     /// Returns an iterator that will attempt to yield all pending values.
     /// It will return `None` if there are no more pending values or if the
-    /// channel has hung up. The iterator will never `panic!` or block the
+    /// channel has hung up. The iterator will never [`panic!`] or block the
     /// user by waiting for values.
+    ///
+    /// [`panic!`]: ../../../std/macro.panic.html
     #[stable(feature = "receiver_try_iter", since = "1.15.0")]
     pub fn try_iter(&self) -> TryIter<T> {
         TryIter { rx: self }
index d79be2944c9e31a956387df4c29c621de590dd51..f2c178a1ad503f6e21f62ac574b41bb759a40316 100644 (file)
@@ -30,7 +30,7 @@
 ///
 /// The mutexes in this module implement a strategy called "poisoning" where a
 /// mutex is considered poisoned whenever a thread panics while holding the
-/// lock. Once a mutex is poisoned, all other threads are unable to access the
+/// mutex. Once a mutex is poisoned, all other threads are unable to access the
 /// data by default as it is likely tainted (some invariant is not being
 /// upheld).
 ///
@@ -115,7 +115,7 @@ pub struct Mutex<T: ?Sized> {
     // Note that this mutex is in a *box*, not inlined into the struct itself.
     // Once a native mutex has been used once, its address can never change (it
     // can't be moved). This mutex type can be safely moved at any time, so to
-    // ensure that the native mutex is used correctly we box the inner lock to
+    // ensure that the native mutex is used correctly we box the inner mutex to
     // give it a constant address.
     inner: Box<sys::Mutex>,
     poison: poison::Flag,
@@ -183,7 +183,7 @@ impl<T: ?Sized> Mutex<T> {
     /// Acquires a mutex, blocking the current thread until it is able to do so.
     ///
     /// This function will block the local thread until it is available to acquire
-    /// the mutex. Upon returning, the thread is the only thread with the mutex
+    /// the mutex. Upon returning, the thread is the only thread with the lock
     /// held. An RAII guard is returned to allow scoped unlock of the lock. When
     /// the guard goes out of scope, the mutex will be unlocked.
     ///
@@ -267,9 +267,9 @@ pub fn try_lock(&self) -> TryLockResult<MutexGuard<T>> {
         }
     }
 
-    /// Determines whether the lock is poisoned.
+    /// Determines whether the mutex is poisoned.
     ///
-    /// If another thread is active, the lock can still become poisoned at any
+    /// If another thread is active, the mutex can still become poisoned at any
     /// time. You should not trust a `false` value for program correctness
     /// without additional synchronization.
     ///
@@ -312,7 +312,7 @@ pub fn is_poisoned(&self) -> bool {
     #[stable(feature = "mutex_into_inner", since = "1.6.0")]
     pub fn into_inner(self) -> LockResult<T> where T: Sized {
         // We know statically that there are no outstanding references to
-        // `self` so there's no need to lock the inner lock.
+        // `self` so there's no need to lock the inner mutex.
         //
         // To get the inner value, we'd like to call `data.into_inner()`,
         // but because `Mutex` impl-s `Drop`, we can't move out of it, so
@@ -353,7 +353,7 @@ pub fn into_inner(self) -> LockResult<T> where T: Sized {
     #[stable(feature = "mutex_get_mut", since = "1.6.0")]
     pub fn get_mut(&mut self) -> LockResult<&mut T> {
         // We know statically that there are no other references to `self`, so
-        // there's no need to lock the inner lock.
+        // there's no need to lock the inner mutex.
         let data = unsafe { &mut *self.data.get() };
         poison::map_result(self.poison.borrow(), |_| data )
     }
index 75aa72e3cff8c5cddc85c5cd47dcad13c0d44436..296235e173d13f575a04b395b1042b9a47a1b470 100644 (file)
@@ -72,13 +72,6 @@ pub trait IntoRawFd {
     fn into_raw_fd(self) -> RawFd;
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl AsRawFd for RawFd {
-    fn as_raw_fd(&self) -> RawFd {
-        *self
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl AsRawFd for fs::File {
     fn as_raw_fd(&self) -> RawFd {
@@ -91,14 +84,6 @@ unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
         fs::File::from_inner(sys::fs::File::from_inner(fd))
     }
 }
-
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawFd for RawFd {
-    fn into_raw_fd(self) -> RawFd {
-        self
-    }
-}
-
 #[stable(feature = "into_raw_os", since = "1.4.0")]
 impl IntoRawFd for fs::File {
     fn into_raw_fd(self) -> RawFd {
index c57751a01d7c1b6f0293da4c000cd33b51e0dab4..854d380d128c9d18d500297b7ecaa07badce30a3 100644 (file)
@@ -92,7 +92,7 @@ fn oom_handler() -> ! {
 
     #[cfg(not(any(target_os = "nacl", target_os = "emscripten", target_os="fuchsia")))]
     unsafe fn reset_sigpipe() {
-        assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != !0);
+        assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != libc::SIG_ERR);
     }
     #[cfg(any(target_os = "nacl", target_os = "emscripten", target_os="fuchsia"))]
     unsafe fn reset_sigpipe() {}
index 51e00fc1ab96abe8456cfb7280fc367af249dbef..706256ff10ec9dac6cb548150ff68ad129dc0511 100644 (file)
@@ -8,11 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use cmp;
 use io;
 use libc::{self, c_int};
 use mem;
-use ptr;
 use sys::{cvt, cvt_r};
 use sys::fd::FileDesc;
 
@@ -80,16 +78,14 @@ pub fn read2(p1: AnonPipe,
     p1.set_nonblocking(true)?;
     p2.set_nonblocking(true)?;
 
-    let max = cmp::max(p1.raw(), p2.raw());
+    let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() };
+    fds[0].fd = p1.raw();
+    fds[0].events = libc::POLLIN;
+    fds[1].fd = p2.raw();
+    fds[1].events = libc::POLLIN;
     loop {
-        // wait for either pipe to become readable using `select`
-        cvt_r(|| unsafe {
-            let mut read: libc::fd_set = mem::zeroed();
-            libc::FD_SET(p1.raw(), &mut read);
-            libc::FD_SET(p2.raw(), &mut read);
-            libc::select(max + 1, &mut read, ptr::null_mut(), ptr::null_mut(),
-                         ptr::null_mut())
-        })?;
+        // wait for either pipe to become readable using `poll`
+        cvt_r(|| unsafe { libc::poll(fds.as_mut_ptr(), 2, -1) })?;
 
         // Read as much as we can from each pipe, ignoring EWOULDBLOCK or
         // EAGAIN. If we hit EOF, then this will happen because the underlying
@@ -109,11 +105,11 @@ pub fn read2(p1: AnonPipe,
                 }
             }
         };
-        if read(&p1, v1)? {
+        if fds[0].revents != 0 && read(&p1, v1)? {
             p2.set_nonblocking(false)?;
             return p2.read_to_end(v2).map(|_| ());
         }
-        if read(&p2, v2)? {
+        if fds[1].revents != 0 && read(&p2, v2)? {
             p1.set_nonblocking(false)?;
             return p1.read_to_end(v1).map(|_| ());
         }
index edf928d61063e2463a8a25670f2f151d0bf0463f..18c00e7c5f1b6af27e54e090257271651c5da4f5 100644 (file)
 //! [`Err`]: ../../std/result/enum.Result.html#variant.Err
 //! [`panic!`]: ../../std/macro.panic.html
 //! [`Builder`]: ../../std/thread/struct.Builder.html
-//! [`thread::current`]: ../../std/thread/fn.spawn.html
+//! [`thread::current`]: ../../std/thread/fn.current.html
 //! [`Thread`]: ../../std/thread/struct.Thread.html
 //! [`park`]: ../../std/thread/fn.park.html
 //! [`unpark`]: ../../std/thread/struct.Thread.html#method.unpark
index c79040424f619e0c4c8a745f3fae66138d235408..e7c5d8278d9775065d1c800633ceaba2458e7e17 100644 (file)
@@ -26,7 +26,8 @@ pub fn collect_derives(cx: &mut ExtCtxt, attrs: &mut Vec<ast::Attribute>) -> Vec
             return true;
         }
 
-        match attr.parse_list(cx.parse_sess, |parser| parser.parse_path(PathStyle::Mod)) {
+        match attr.parse_list(cx.parse_sess,
+                              |parser| parser.parse_path_allowing_meta(PathStyle::Mod)) {
             Ok(ref traits) if traits.is_empty() => {
                 cx.span_warn(attr.span, "empty trait list in `derive`");
                 false
index 12d25ca4274fea1fe09ef93cbcd49784b407b4ec..412803ddcd5a3d1b5eb160dddc82c3c1d03824c2 100644 (file)
@@ -292,9 +292,6 @@ pub fn new() -> Features {
     // Allows attributes on lifetime/type formal parameters in generics (RFC 1327)
     (active, generic_param_attrs, "1.11.0", Some(34761)),
 
-    // The #![windows_subsystem] attribute
-    (active, windows_subsystem, "1.14.0", Some(37499)),
-
     // Allows #[link(..., cfg(..))]
     (active, link_cfg, "1.14.0", Some(37406)),
 
@@ -408,7 +405,8 @@ pub fn new() -> Features {
     (accepted, static_recursion, "1.17.0", Some(29719)),
     // pub(restricted) visibilities (RFC 1422)
     (accepted, pub_restricted, "1.17.0", Some(32409)),
-
+    // The #![windows_subsystem] attribute
+    (accepted, windows_subsystem, "1.18.0", Some(37499)),
 );
 // If you change this, please modify src/doc/unstable-book as well. You must
 // move that documentation into the relevant place in the other docs, and
@@ -768,11 +766,7 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
                                         "unboxed_closures are still evolving",
                                         cfg_fn!(unboxed_closures))),
 
-    ("windows_subsystem", Whitelisted, Gated(Stability::Unstable,
-                                             "windows_subsystem",
-                                             "the windows subsystem attribute \
-                                              is currently unstable",
-                                             cfg_fn!(windows_subsystem))),
+    ("windows_subsystem", Whitelisted, Ungated),
 
     ("proc_macro_attribute", Normal, Gated(Stability::Unstable,
                                            "proc_macro",
index a27fc070ebec3e59877ae0606661f703f02c6eba..0dd2c03acb654b8eee67693b3d561381b65afcd0 100644 (file)
@@ -1767,6 +1767,26 @@ pub fn parse_path(&mut self, mode: PathStyle) -> PResult<'a, ast::Path> {
         })
     }
 
+    /// Like `parse_path`, but also supports parsing `Word` meta items into paths for back-compat.
+    /// This is used when parsing derive macro paths in `#[derive]` attributes.
+    pub fn parse_path_allowing_meta(&mut self, mode: PathStyle) -> PResult<'a, ast::Path> {
+        let meta_ident = match self.token {
+            token::Interpolated(ref nt) => match **nt {
+                token::NtMeta(ref meta) => match meta.node {
+                    ast::MetaItemKind::Word => Some(ast::Ident::with_empty_ctxt(meta.name)),
+                    _ => None,
+                },
+                _ => None,
+            },
+            _ => None,
+        };
+        if let Some(ident) = meta_ident {
+            self.bump();
+            return Ok(ast::Path::from_ident(self.prev_span, ident));
+        }
+        self.parse_path(mode)
+    }
+
     /// Examples:
     /// - `a::b<T,U>::c<V,W>`
     /// - `a::b<T,U>::c(V) -> W`
@@ -4657,25 +4677,30 @@ pub fn parse_impl_item(&mut self) -> PResult<'a, ImplItem> {
         })
     }
 
-    fn complain_if_pub_macro(&mut self, visa: &Visibility, span: Span) {
-        match *visa {
-            Visibility::Inherited => (),
+    fn complain_if_pub_macro(&mut self, vis: &Visibility, sp: Span) {
+        if let Err(mut err) = self.complain_if_pub_macro_diag(vis, sp) {
+            err.emit();
+        }
+    }
+
+    fn complain_if_pub_macro_diag(&mut self, vis: &Visibility, sp: Span) -> PResult<'a, ()> {
+        match *vis {
+            Visibility::Inherited => Ok(()),
             _ => {
                 let is_macro_rules: bool = match self.token {
                     token::Ident(sid) => sid.name == Symbol::intern("macro_rules"),
                     _ => false,
                 };
                 if is_macro_rules {
-                    self.diagnostic().struct_span_err(span, "can't qualify macro_rules \
-                                                             invocation with `pub`")
-                                     .help("did you mean #[macro_export]?")
-                                     .emit();
+                    let mut err = self.diagnostic()
+                        .struct_span_err(sp, "can't qualify macro_rules invocation with `pub`");
+                    err.help("did you mean #[macro_export]?");
+                    Err(err)
                 } else {
-                    self.diagnostic().struct_span_err(span, "can't qualify macro \
-                                                             invocation with `pub`")
-                                     .help("try adjusting the macro to put `pub` \
-                                            inside the invocation")
-                                     .emit();
+                    let mut err = self.diagnostic()
+                        .struct_span_err(sp, "can't qualify macro invocation with `pub`");
+                    err.help("try adjusting the macro to put `pub` inside the invocation");
+                    Err(err)
                 }
             }
         }
@@ -4686,14 +4711,36 @@ fn parse_impl_method(&mut self, vis: &Visibility)
                          -> PResult<'a, (Ident, Vec<ast::Attribute>, ast::ImplItemKind)> {
         // code copied from parse_macro_use_or_failure... abstraction!
         if self.token.is_path_start() {
-            // method macro.
+            // Method macro.
 
             let prev_span = self.prev_span;
-            self.complain_if_pub_macro(&vis, prev_span);
+            // Before complaining about trying to set a macro as `pub`,
+            // check if `!` comes after the path.
+            let err = self.complain_if_pub_macro_diag(&vis, prev_span);
 
             let lo = self.span;
             let pth = self.parse_path(PathStyle::Mod)?;
-            self.expect(&token::Not)?;
+            let bang_err = self.expect(&token::Not);
+            if let Err(mut err) = err {
+                if let Err(mut bang_err) = bang_err {
+                    // Given this code `pub path(`, it seems like this is not setting the
+                    // visibility of a macro invocation, but rather a mistyped method declaration.
+                    // Create a diagnostic pointing out that `fn` is missing.
+                    //
+                    // x |     pub path(&self) {
+                    //   |        ^ missing `fn` for method declaration
+
+                    err.cancel();
+                    bang_err.cancel();
+                    //     pub  path(
+                    //        ^^ `sp` below will point to this
+                    let sp = prev_span.between(self.prev_span);
+                    err = self.diagnostic()
+                        .struct_span_err(sp, "missing `fn` for method declaration");
+                    err.span_label(sp, &"missing `fn`");
+                }
+                return Err(err);
+            }
 
             // eat a matched-delimiter token tree:
             let (delim, tts) = self.expect_delimited_token_tree()?;
index 5875015893144db01dc58244a4f110a43774ebc9..15111bbba0a92d6d04cdb03b0f0f5f09fcd09587 100644 (file)
@@ -43,6 +43,8 @@
 
 use serialize::{Encodable, Decodable, Encoder, Decoder};
 
+use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
+                                           HashStable};
 /// An owned smart pointer.
 #[derive(Hash, PartialEq, Eq, PartialOrd, Ord)]
 pub struct P<T: ?Sized> {
@@ -215,3 +217,13 @@ fn decode<D: Decoder>(d: &mut D) -> Result<P<[T]>, D::Error> {
         }))
     }
 }
+
+impl<CTX, T> HashStable<CTX> for P<T>
+    where T: ?Sized + HashStable<CTX>
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        (**self).hash_stable(hcx, hasher);
+    }
+}
index 195fb23f9d8c75ed8b8c3f0e4ce1042f207b259b..2d9fd7aa87553dc81ad73bb36f77fc3198ce781a 100644 (file)
@@ -12,6 +12,9 @@
 use std::ops::Deref;
 use std::rc::Rc;
 
+use rustc_data_structures::stable_hasher::{StableHasher, StableHasherResult,
+                                           HashStable};
+
 #[derive(Clone)]
 pub struct RcSlice<T> {
     data: Rc<Box<[T]>>,
@@ -41,3 +44,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::Debug::fmt(self.deref(), f)
     }
 }
+
+impl<CTX, T> HashStable<CTX> for RcSlice<T>
+    where T: HashStable<CTX>
+{
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        (**self).hash_stable(hcx, hasher);
+    }
+}
index 3f09b2009a795541825eb7e0c556c3bf0d49e855..9b88b9f7696fb3a35f68c5165d3f5ccc59ce610f 100644 (file)
@@ -189,6 +189,30 @@ pub fn to(self, end: Span) -> Span {
             Span { hi: end.hi, ..self }
         }
     }
+
+    pub fn between(self, end: Span) -> Span {
+        Span {
+            lo: self.hi,
+            hi: end.lo,
+            ctxt: if end.ctxt == SyntaxContext::empty() {
+                end.ctxt
+            } else {
+                self.ctxt
+            }
+        }
+    }
+
+    pub fn until(self, end: Span) -> Span {
+        Span {
+            lo: self.lo,
+            hi: end.lo,
+            ctxt: if end.ctxt == SyntaxContext::empty() {
+                end.ctxt
+            } else {
+                self.ctxt
+            }
+        }
+    }
 }
 
 #[derive(Clone, Debug)]
index 077d57a9da389f895bc6b20f3fee50dcdc267b62..f04394f716660e6a0460dd55efc98eba25635f88 100644 (file)
@@ -39,8 +39,10 @@ pub trait Stats {
     ///
     /// Note: this method sacrifices performance at the altar of accuracy
     /// Depends on IEEE-754 arithmetic guarantees. See proof of correctness at:
-    /// ["Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric Predicates"]
-    /// (http://www.cs.cmu.edu/~quake-papers/robust-arithmetic.ps)
+    /// ["Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric
+    /// Predicates"][paper]
+    ///
+    /// [paper]: http://www.cs.cmu.edu/~quake-papers/robust-arithmetic.ps
     fn sum(&self) -> f64;
 
     /// Minimum value of the samples.
index ed3d5212bf25677a3372f0764927a7ce02d767e0..9b8099d55a024eea1e7e8f80a2f6049c76c6aed4 100644 (file)
@@ -35,7 +35,8 @@ fn main() {
     } else if target.contains("dragonfly") {
         println!("cargo:rustc-link-lib=gcc_pic");
     } else if target.contains("windows-gnu") {
-        println!("cargo:rustc-link-lib=gcc_eh");
+        println!("cargo:rustc-link-lib=static-nobundle=gcc_eh");
+        println!("cargo:rustc-link-lib=static-nobundle=pthread");
     } else if target.contains("fuchsia") {
         println!("cargo:rustc-link-lib=unwind");
     }
index 7fa2ce650fd6cea7d98459c612a85176047673a9..d4d52322adab0e5955b8ab98d1210e060337c64a 100644 (file)
@@ -17,6 +17,7 @@
 #![feature(cfg_target_vendor)]
 #![feature(staged_api)]
 #![feature(unwind_attributes)]
+#![feature(static_nobundle)]
 
 #![cfg_attr(not(target_env = "msvc"), feature(libc))]
 
diff --git a/src/test/codegen/personality_lifetimes.rs b/src/test/codegen/personality_lifetimes.rs
new file mode 100644 (file)
index 0000000..e0de64b
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2017 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-msvc
+
+// compile-flags: -O -C no-prepopulate-passes
+
+#![crate_type="lib"]
+
+struct S;
+
+impl Drop for S {
+    fn drop(&mut self) {
+    }
+}
+
+fn might_unwind() {
+}
+
+// CHECK-LABEL: @test
+#[no_mangle]
+pub fn test() {
+    let _s = S;
+    // Check that the personality slot alloca gets a lifetime start in each cleanup block, not just
+    // in the first one.
+    // CHECK-LABEL: cleanup:
+    // CHECK: bitcast{{.*}}personalityslot
+    // CHECK-NEXT: call void @llvm.lifetime.start
+    // CHECK-LABEL: cleanup1:
+    // CHECK: bitcast{{.*}}personalityslot
+    // CHECK-NEXT: call void @llvm.lifetime.start
+    might_unwind();
+    might_unwind();
+}
diff --git a/src/test/compile-fail/coherence-overlapping-inherent-impl-trait.rs b/src/test/compile-fail/coherence-overlapping-inherent-impl-trait.rs
deleted file mode 100644 (file)
index 158d360..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 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 C {}
-impl C { fn f() {} } //~ ERROR duplicate definitions with name `f`
-impl C { fn f() {} }
-fn main() { }
diff --git a/src/test/compile-fail/inherent-overlap.rs b/src/test/compile-fail/inherent-overlap.rs
deleted file mode 100644 (file)
index 18e77dd..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that you cannot define items with the same name in overlapping inherent
-// impl blocks.
-
-#![allow(unused)]
-
-struct Foo;
-
-impl Foo {
-    fn id() {} //~ ERROR duplicate definitions
-}
-
-impl Foo {
-    fn id() {}
-}
-
-struct Bar<T>(T);
-
-impl<T> Bar<T> {
-    fn bar(&self) {} //~ ERROR duplicate definitions
-}
-
-impl Bar<u32> {
-    fn bar(&self) {}
-}
-
-struct Baz<T>(T);
-
-impl<T: Copy> Baz<T> {
-    fn baz(&self) {} //~ ERROR duplicate definitions
-}
-
-impl<T> Baz<Vec<T>> {
-    fn baz(&self) {}
-}
-
-fn main() {}
diff --git a/src/test/compile-fail/windows-subsystem-gated.rs b/src/test/compile-fail/windows-subsystem-gated.rs
deleted file mode 100644 (file)
index 63f891a..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2016 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.
-
-// gate-test-windows_subsystem
-
-#![windows_subsystem = "console"]
-//~^ ERROR: the windows subsystem attribute is currently unstable
-
-fn main() {}
index e0003440719e62b2d3f1860e4c566299f26ad693..7772cfd6a2c93894bd9e7e843661c6922b214c60 100644 (file)
@@ -10,7 +10,6 @@
 
 // error-pattern: invalid windows subsystem `wrong`, only `windows` and `console` are allowed
 
-#![feature(windows_subsystem)]
 #![windows_subsystem = "wrong"]
 
 fn main() {}
diff --git a/src/test/run-make/multiple-emits/Makefile b/src/test/run-make/multiple-emits/Makefile
new file mode 100644 (file)
index 0000000..e126422
--- /dev/null
@@ -0,0 +1,7 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) foo.rs --emit=asm,llvm-ir -o $(TMPDIR)/out 2>&1
+       rm $(TMPDIR)/out.ll $(TMPDIR)/out.s
+       $(RUSTC) foo.rs --emit=asm,llvm-ir -o $(TMPDIR)/out2.ext 2>&1
+       rm $(TMPDIR)/out2.ll $(TMPDIR)/out2.s
diff --git a/src/test/run-make/multiple-emits/foo.rs b/src/test/run-make/multiple-emits/foo.rs
new file mode 100644 (file)
index 0000000..8ae3d07
--- /dev/null
@@ -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.
+
+fn main() {}
index e331f65abb7b3200edb7fb16a5c8c7b55ef95bf5..a996aa4fad5a7c247e0791430489ed8e61bdf4c3 100644 (file)
@@ -448,3 +448,8 @@ fn test_format_args() {
     print!("{0} + {} = {}", x, y);
     print!("x is {}, y is {1}, name is {n}", x, y, n = name);
 }
+
+extern {
+    static EXTERN_FOO: u8;
+    fn extern_foo(a: u8, b: i32) -> String;
+}
index 3aedb0ecab722f6a8ef6a82e6bbc909cd6066068..ffad1e35ee6607df6e3a0854e5e8310690cdcf19 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(windows_subsystem)]
 #![windows_subsystem = "console"]
 
 fn main() {}
index 5d875a5a1bf1f5ee7e371297f3f82067707c6352..33cbe32059190fb2c0bebe95db127534827a192b 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(windows_subsystem)]
 #![windows_subsystem = "windows"]
 
 fn main() {}
index a1c9ff8a21edb4b45341181130892a66f50a9e87..f7f79356a0b9f22284b76925a49f0b2f82eca5ed 100644 (file)
 #![deny(const_err)]
 
 const X: *const u8 = b"" as _;
+const Y: bool = 'A' == 'B';
+const Z: char = 'A';
+const W: bool = Z <= 'B';
+
 
 fn main() {
     let _ = ((-1 as i8) << 8 - 1) as f32;
diff --git a/src/test/run-pass/issue-40962.rs b/src/test/run-pass/issue-40962.rs
new file mode 100644 (file)
index 0000000..b35cfa1
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2017 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.
+
+macro_rules! m {
+    ($i:meta) => {
+        #[derive($i)]
+        struct S;
+    }
+}
+
+m!(Clone);
+
+fn main() {}
diff --git a/src/test/rustdoc/test-lists.rs b/src/test/rustdoc/test-lists.rs
new file mode 100644 (file)
index 0000000..71a826a
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2017 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.
+
+#![crate_name = "foo"]
+
+// ignore-tidy-linelength
+
+// @has foo/fn.f.html
+// @has - "<pre class='rust fn'>pub fn f()</pre><div class='docblock'><ol><li>list<ol><li>fooooo</li><li>x</li></ol></li><li>foo</li></ol>"
+/// 1. list
+///     1. fooooo
+///     2. x
+/// 2. foo
+pub fn f() {}
+
+// @has foo/fn.foo2.html
+// @has - "<pre class='rust fn'>pub fn foo2()</pre><div class='docblock'><ul><li>normal list<ul><li><p>sub list</p></li><li><p>new elem still same elem</p><p>and again same elem!</p></li></ul></li><li>new big elem</li></ul>"
+/// * normal list
+///     * sub list
+///     * new elem
+///       still same elem
+///
+///       and again same elem!
+/// * new big elem
+pub fn foo2() {}
\ No newline at end of file
diff --git a/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.rs b/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.rs
new file mode 100644 (file)
index 0000000..a72ad03
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2016 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 C {}
+impl C { fn f() {} }
+impl C { fn f() {} }
+fn main() { }
diff --git a/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr b/src/test/ui/codemap_tests/coherence-overlapping-inherent-impl-trait.stderr
new file mode 100644 (file)
index 0000000..7f1ab92
--- /dev/null
@@ -0,0 +1,10 @@
+error[E0592]: duplicate definitions with name `f`
+  --> $DIR/coherence-overlapping-inherent-impl-trait.rs:14:10
+   |
+14 | impl C { fn f() {} }
+   |          ^^^^^^^^^ duplicate definitions for `f`
+15 | impl C { fn f() {} }
+   |          --------- other definition for `f`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/codemap_tests/overlapping_inherent_impls.rs b/src/test/ui/codemap_tests/overlapping_inherent_impls.rs
new file mode 100644 (file)
index 0000000..a626b63
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that you cannot define items with the same name in overlapping inherent
+// impl blocks.
+
+#![allow(unused)]
+
+struct Foo;
+
+impl Foo {
+    fn id() {}
+}
+
+impl Foo {
+    fn id() {}
+}
+
+struct Bar<T>(T);
+
+impl<T> Bar<T> {
+    fn bar(&self) {}
+}
+
+impl Bar<u32> {
+    fn bar(&self) {}
+}
+
+struct Baz<T>(T);
+
+impl<T: Copy> Baz<T> {
+    fn baz(&self) {}
+}
+
+impl<T> Baz<Vec<T>> {
+    fn baz(&self) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr b/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr
new file mode 100644 (file)
index 0000000..de8a24c
--- /dev/null
@@ -0,0 +1,29 @@
+error[E0592]: duplicate definitions with name `id`
+  --> $DIR/overlapping_inherent_impls.rs:19:5
+   |
+19 |     fn id() {}
+   |     ^^^^^^^^^^ duplicate definitions for `id`
+...
+23 |     fn id() {}
+   |     ---------- other definition for `id`
+
+error[E0592]: duplicate definitions with name `bar`
+  --> $DIR/overlapping_inherent_impls.rs:29:5
+   |
+29 |     fn bar(&self) {}
+   |     ^^^^^^^^^^^^^^^^ duplicate definitions for `bar`
+...
+33 |     fn bar(&self) {}
+   |     ---------------- other definition for `bar`
+
+error[E0592]: duplicate definitions with name `baz`
+  --> $DIR/overlapping_inherent_impls.rs:39:5
+   |
+39 |     fn baz(&self) {}
+   |     ^^^^^^^^^^^^^^^^ duplicate definitions for `baz`
+...
+43 |     fn baz(&self) {}
+   |     ---------------- other definition for `baz`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/did_you_mean/issue-40006.rs b/src/test/ui/did_you_mean/issue-40006.rs
new file mode 100644 (file)
index 0000000..cf75929
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2017 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 S;
+
+impl S {
+    pub hello_method(&self) {
+        println!("Hello");
+    }
+}
+
+fn main() {
+    S.hello_method();
+}
diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr
new file mode 100644 (file)
index 0000000..4609580
--- /dev/null
@@ -0,0 +1,8 @@
+error: missing `fn` for method declaration
+  --> $DIR/issue-40006.rs:14:8
+   |
+14 |     pub hello_method(&self) {
+   |        ^ missing `fn`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/suggestions/confuse-field-and-method/private-field.rs b/src/test/ui/suggestions/confuse-field-and-method/private-field.rs
new file mode 100644 (file)
index 0000000..94cf38f
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2017 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 mod animal {
+    pub struct Dog {
+        pub age: usize,
+        dog_age: usize,
+    }
+
+    impl Dog {
+        pub fn new(age: usize) -> Dog {
+            Dog { age: age, dog_age: age * 7 }
+        }
+    }
+}
+
+fn main() {
+    let dog = animal::Dog::new(3);
+    let dog_age = dog.dog_age();
+    //let dog_age = dog.dog_age;
+    println!("{}", dog_age);
+}
diff --git a/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr b/src/test/ui/suggestions/confuse-field-and-method/private-field.stderr
new file mode 100644 (file)
index 0000000..d078859
--- /dev/null
@@ -0,0 +1,8 @@
+error: no method named `dog_age` found for type `animal::Dog` in the current scope
+  --> $DIR/private-field.rs:26:23
+   |
+26 |     let dog_age = dog.dog_age();
+   |                       ^^^^^^^ private field, not a method
+
+error: aborting due to previous error
+
index 3808c05c6b9398a95f86db47e493db3a26a29206..0dbf0d4316abd9c2cdc92ee7794747168f7b69c7 100644 (file)
@@ -75,7 +75,7 @@
     "src/libtest", // Probably should defer to unstable std::sys APIs
 
     // std testing crates, ok for now at least
-    "src/libcoretest",
+    "src/libcore/tests",
 
     // non-std crates
     "src/test",