about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--RELEASES.md220
-rw-r--r--src/doc/book/enums.md16
-rw-r--r--src/doc/book/structs.md46
-rw-r--r--src/etc/htmldocck.py140
-rw-r--r--src/liballoc/arc.rs9
-rw-r--r--src/liballoc/rc.rs8
-rw-r--r--src/libcollections/binary_heap.rs20
-rw-r--r--src/libcollections/btree/map.rs23
-rw-r--r--src/libcollections/btree/set.rs12
-rw-r--r--src/libcollections/slice.rs3
-rw-r--r--src/libcollections/string.rs399
-rw-r--r--src/libcollections/vec_deque.rs22
-rw-r--r--src/libcollectionstest/binary_heap.rs22
-rw-r--r--src/libcollectionstest/btree/map.rs3
-rw-r--r--src/libcollectionstest/slice.rs11
-rw-r--r--src/libcore/iter.rs84
-rw-r--r--src/libcore/lib.rs6
-rw-r--r--src/libcore/num/f32.rs6
-rw-r--r--src/libcore/num/f64.rs6
-rw-r--r--src/libcore/num/float_macros.rs141
-rw-r--r--src/libcore/num/mod.rs6
-rw-r--r--src/libcore/option.rs55
-rw-r--r--src/libcore/result.rs55
-rw-r--r--src/libcore/simd.rs143
-rw-r--r--src/libcore/simd_old.rs98
-rw-r--r--src/libcore/slice.rs18
-rw-r--r--src/libcoretest/iter.rs12
-rw-r--r--src/libcoretest/lib.rs1
-rw-r--r--src/libcoretest/num/flt2dec/mod.rs5
-rw-r--r--src/libcoretest/num/mod.rs29
-rw-r--r--src/librand/chacha.rs9
-rw-r--r--src/librand/isaac.rs17
-rw-r--r--src/librand/reseeding.rs5
-rw-r--r--src/librustc/middle/const_eval.rs2
-rw-r--r--src/librustc/middle/cstore.rs9
-rw-r--r--src/librustc/middle/ty/sty.rs28
-rw-r--r--src/librustc/mir/repr.rs59
-rw-r--r--src/librustc/mir/visit.rs316
-rw-r--r--src/librustc_data_structures/lib.rs1
-rw-r--r--src/librustc_data_structures/tuple_slice.rs60
-rw-r--r--src/librustc_front/intravisit.rs4
-rw-r--r--src/librustc_metadata/common.rs3
-rw-r--r--src/librustc_metadata/csearch.rs11
-rw-r--r--src/librustc_metadata/decoder.rs58
-rw-r--r--src/librustc_metadata/encoder.rs24
-rw-r--r--src/librustc_mir/build/expr/as_lvalue.rs2
-rw-r--r--src/librustc_mir/build/expr/as_rvalue.rs2
-rw-r--r--src/librustc_mir/build/expr/into.rs12
-rw-r--r--src/librustc_mir/build/matches/mod.rs2
-rw-r--r--src/librustc_mir/build/matches/test.rs8
-rw-r--r--src/librustc_mir/transform/simplify_cfg.rs11
-rw-r--r--src/librustc_trans/trans/base.rs18
-rw-r--r--src/librustc_trans/trans/mir/block.rs2
-rw-r--r--src/librustc_trans/trans/mir/rvalue.rs2
-rw-r--r--src/librustc_unicode/char.rs7
-rw-r--r--src/librustc_unicode/lib.rs4
-rw-r--r--src/librustc_unicode/u_str.rs95
-rw-r--r--src/libstd/collections/hash/bench.rs15
-rw-r--r--src/libstd/collections/hash/map.rs23
-rw-r--r--src/libstd/ffi/c_str.rs27
-rw-r--r--src/libstd/fs.rs79
-rw-r--r--src/libstd/io/prelude.rs3
-rw-r--r--src/libstd/lib.rs5
-rw-r--r--src/libstd/num/f32.rs28
-rw-r--r--src/libstd/num/f64.rs28
-rw-r--r--src/libstd/primitive_docs.rs2
-rw-r--r--src/libstd/sys/windows/c.rs11
-rw-r--r--src/libstd/thread/local.rs17
-rw-r--r--src/test/bench/shootout-mandelbrot.rs209
-rw-r--r--src/test/bench/shootout-spectralnorm.rs123
-rw-r--r--src/test/compile-fail/feature-gate-simd-ffi.rs14
-rw-r--r--src/test/compile-fail/issue-26656.rs52
-rw-r--r--src/test/debuginfo/simd.rs23
-rw-r--r--src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs5
-rw-r--r--src/test/run-pass/simd-issue-10604.rs17
-rw-r--r--src/test/run-pass/sync-send-iterators-in-libcore.rs4
-rw-r--r--src/test/run-pass/tls-init-on-init.rs51
-rw-r--r--src/test/run-pass/while-let.rs2
78 files changed, 1438 insertions, 1690 deletions
diff --git a/RELEASES.md b/RELEASES.md
index 54fe87dc658..f8679431339 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,5 +1,223 @@
+Version 1.5.0 (2015-12-10)
+==========================
+
+* ~700 changes, numerous bugfixes
+
+Highlights
+----------
+
+* Stabilized APIs:
+  [`BinaryHeap::from`], [`BinaryHeap::into_sorted_vec`],
+  [`BinaryHeap::into_vec`], [`Condvar::wait_timeout`],
+  [`FileTypeExt::is_block_device`], [`FileTypeExt::is_char_device`],
+  [`FileTypeExt::is_fifo`], [`FileTypeExt::is_socket`],
+  [`FileTypeExt`], [`Formatter::alternate`], [`Formatter::fill`],
+  [`Formatter::precision`], [`Formatter::sign_aware_zero_pad`],
+  [`Formatter::sign_minus`], [`Formatter::sign_plus`],
+  [`Formatter::width`], [`Iterator::cmp`], [`Iterator::eq`],
+  [`Iterator::ge`], [`Iterator::gt`], [`Iterator::le`],
+  [`Iterator::lt`], [`Iterator::ne`], [`Iterator::partial_cmp`],
+  [`Path::canonicalize`], [`Path::exists`], [`Path::is_dir`],
+  [`Path::is_file`], [`Path::metadata`], [`Path::read_dir`],
+  [`Path::read_link`], [`Path::symlink_metadata`],
+  [`Utf8Error::valid_up_to`], [`Vec::resize`],
+  [`VecDeque::as_mut_slices`], [`VecDeque::as_slices`],
+  [`VecDeque::insert`], [`VecDeque::shrink_to_fit`],
+  [`VecDeque::swap_remove_back`], [`VecDeque::swap_remove_front`],
+  [`slice::split_first_mut`], [`slice::split_first`],
+  [`slice::split_last_mut`], [`slice::split_last`],
+  [`char::from_u32_unchecked`], [`fs::canonicalize`],
+  [`str::MatchIndices`], [`str::RMatchIndices`],
+  [`str::match_indices`], [`str::rmatch_indices`],
+  [`str::slice_mut_unchecked`], [`string::ParseError`].
+* Rust applications hosted on crates.io can be installed locally to
+  `~/.cargo/bin` with the [`cargo install`] command. Among other
+  things this makes it easier to augment Cargo with new subcommands:
+  when a binary named e.g. `cargo-foo` is found in `$PATH` it can be
+  invoked as `cargo foo`.
+* Crates with wildcard (`*`) dependencies will [emit warnings when
+  published][1.5w]. In 1.6 it will no longer be possible to publish
+  crates with wildcard dependencies.
+
+Breaking Changes
+----------------
+
+* The rules determining when a particular lifetime must outlive
+  a particular value (known as '[dropck]') have been [modified
+  to not rely on parametricity][1.5p].
+* [Implementations of `AsRef` and `AsMut` were added to `Box`, `Rc`,
+  and `Arc`][1.5a]. Because these smart pointer types implement
+  `Deref`, this causes breakage in cases where the interior type
+  contains methods of the same name.
+* [Correct a bug in Rc/Arc][1.5c] that caused [dropck] to be unaware
+  that they could drop their content. Soundness fix.
+* All method invocations are [properly checked][1.5wf1] for
+  [well-formedness][1.5wf2]. Soundness fix.
+* Traits whose supertraits contain `Self` are [not object
+  safe][1.5o]. Soundness fix.
+* Target specifications support a [`no_default_libraries`][1.5nd]
+  setting that controls whether `-nodefaultlibs` is passed to the
+  linker, and in turn the `is_like_windows` setting no longer affects
+  the `-nodefaultlibs` flag.
+* `#[derive(Show)]`, long-deprecated, [has been removed][1.5ds].
+* The `#[inline]` and `#[repr]` attributes [can only appear
+  in valid locations][1.5at].
+* Native libraries linked from the local crate are [passed to
+  the linker before native libraries from upstream crates][1.5nl].
+* Two rarely-used attributes, `#[no_debug]` and
+  `#[omit_gdb_pretty_printer_section]` [are feature gated][1.5fg].
+* Negation of unsigned integers, which has been a warning for
+  several releases, [is now behind a feature gate and will
+  generate errors][1.5nu].
+* The parser accidentally accepted visibility modifiers on
+  enum variants, a bug [which has been fixed][1.5ev].
+* [A bug was fixed that allowed `use` statements to import unstable
+  features][1.5use].
+
+Language
+--------
+
+* When evaluating expressions at compile-time that are not
+  compile-time constants (const-evaluating expressions in non-const
+  contexts), incorrect code such as overlong bitshifts and arithmetic
+  overflow will [generate a warning instead of an error][1.5ce],
+  delaying the error until runtime. This will allow the
+  const-evaluator to be expanded in the future backwards-compatibly.
+* The `improper_ctypes` lint [no longer warns about using `isize` and
+  `usize` in FFI][1.5ict].
+
+Libraries
+---------
+
+* `Arc<T>` and `Rc<T>` are [covariant with respect to `T` instead of
+  invariant][1.5c].
+* `Default` is [implemented for mutable slices][1.5d].
+* `FromStr` is [implemented for `SockAddrV4` and `SockAddrV6`][1.5s].
+* There are now `From` conversions [between floating point
+  types][1.5f] where the conversions are lossless.
+* Thera are now `From` conversions [between integer types][1.5i] where
+  the conversions are lossless.
+* [`fs::Metadata` implements `Clone`][1.5fs].
+* The `parse` method [accepts a leading "+" when parsing
+  integers][1.5pi].
+* [`AsMut` is implemented for `Vec`][1.5am].
+* The `clone_from` implementations for `String` and `BinaryHeap` [have
+  been optimized][1.5cf] and no longer rely on the default impl.
+* The `extern "Rust"`, `extern "C"`, `unsafe extern "Rust"` and
+  `unsafe extern "C"` function types now [implement `Clone`,
+  `PartialEq`, `Eq`, `PartialOrd`, `Ord`, `Hash`, `fmt::Pointer`, and
+  `fmt::Debug` for up to 12 arguments][1.5fp].
+* [Dropping `Vec`s is much faster in unoptimized builds when the
+  element types don't implement `Drop`][1.5dv].
+* A bug that caused in incorrect behavior when [combining `VecDeque`
+  with zero-sized types][1.5vdz] was resolved.
+* [`PartialOrd` for slices is faster][1.5po].
+
+Miscellaneous
+-------------
+
+* [Crate metadata size was reduced by 20%][1.5md].
+* [Improvements to code generation reduced the size of libcore by 3.3
+  MB and rustc's memory usage by 18MB][1.5m].
+* [Improvements to deref translation increased performance in
+  unoptimized builds][1.5dr].
+* Various errors in trait resolution [are deduplicated to only be
+  reported once][1.5te].
+* Rust has preliminary [support for rumprun kernels][1.5rr].
+* Rust has preliminary [support for NetBSD on amd64][1.5na].
+
+[1.5use]: https://github.com/rust-lang/rust/pull/28364
+[1.5po]: https://github.com/rust-lang/rust/pull/28436
+[1.5ev]: https://github.com/rust-lang/rust/pull/28442
+[1.5nu]: https://github.com/rust-lang/rust/pull/28468
+[1.5dr]: https://github.com/rust-lang/rust/pull/28491
+[1.5vdz]: https://github.com/rust-lang/rust/pull/28494
+[1.5md]: https://github.com/rust-lang/rust/pull/28521
+[1.5fg]: https://github.com/rust-lang/rust/pull/28522
+[1.5dv]: https://github.com/rust-lang/rust/pull/28531
+[1.5na]: https://github.com/rust-lang/rust/pull/28543
+[1.5fp]: https://github.com/rust-lang/rust/pull/28560
+[1.5rr]: https://github.com/rust-lang/rust/pull/28593
+[1.5cf]: https://github.com/rust-lang/rust/pull/28602
+[1.5nl]: https://github.com/rust-lang/rust/pull/28605
+[1.5te]: https://github.com/rust-lang/rust/pull/28645
+[1.5at]: https://github.com/rust-lang/rust/pull/28650
+[1.5am]: https://github.com/rust-lang/rust/pull/28663
+[1.5m]: https://github.com/rust-lang/rust/pull/28778
+[1.5ict]: https://github.com/rust-lang/rust/pull/28779
+[1.5a]: https://github.com/rust-lang/rust/pull/28811
+[1.5pi]: https://github.com/rust-lang/rust/pull/28826
+[1.5ce]: https://github.com/rust-lang/rfcs/blob/master/text/1229-compile-time-asserts.md
+[1.5p]: https://github.com/rust-lang/rfcs/blob/master/text/1238-nonparametric-dropck.md
+[1.5i]: https://github.com/rust-lang/rust/pull/28921
+[1.5fs]: https://github.com/rust-lang/rust/pull/29021
+[1.5f]: https://github.com/rust-lang/rust/pull/29129
+[1.5ds]: https://github.com/rust-lang/rust/pull/29148
+[1.5s]: https://github.com/rust-lang/rust/pull/29190
+[1.5d]: https://github.com/rust-lang/rust/pull/29245
+[1.5o]: https://github.com/rust-lang/rust/pull/29259
+[1.5nd]: https://github.com/rust-lang/rust/pull/28578
+[1.5wf2]: https://github.com/rust-lang/rfcs/blob/master/text/1214-projections-lifetimes-and-wf.md
+[1.5wf1]: https://github.com/rust-lang/rust/pull/28669
+[dropck]: https://doc.rust-lang.org/nightly/nomicon/dropck.html
+[1.5c]: https://github.com/rust-lang/rust/pull/29110
+[1.5w]: https://github.com/rust-lang/rfcs/blob/master/text/1241-no-wildcard-deps.md
+[`cargo install`]: https://github.com/rust-lang/rfcs/blob/master/text/1200-cargo-install.md
+[`BinaryHeap::from`]: http://doc.rust-lang.org/nightly/std/convert/trait.From.html#method.from
+[`BinaryHeap::into_sorted_vec`]: http://doc.rust-lang.org/nightly/std/collections/struct.BinaryHeap.html#method.into_sorted_vec
+[`BinaryHeap::into_vec`]: http://doc.rust-lang.org/nightly/std/collections/struct.BinaryHeap.html#method.into_vec
+[`Condvar::wait_timeout`]: http://doc.rust-lang.org/nightly/std/sync/struct.Condvar.html#method.wait_timeout
+[`FileTypeExt::is_block_device`]: http://doc.rust-lang.org/nightly/std/os/unix/fs/trait.FileTypeExt.html#tymethod.is_block_device
+[`FileTypeExt::is_char_device`]: http://doc.rust-lang.org/nightly/std/os/unix/fs/trait.FileTypeExt.html#tymethod.is_char_device
+[`FileTypeExt::is_fifo`]: http://doc.rust-lang.org/nightly/std/os/unix/fs/trait.FileTypeExt.html#tymethod.is_fifo
+[`FileTypeExt::is_socket`]: http://doc.rust-lang.org/nightly/std/os/unix/fs/trait.FileTypeExt.html#tymethod.is_socket
+[`FileTypeExt`]: http://doc.rust-lang.org/nightly/std/os/unix/fs/trait.FileTypeExt.html
+[`Formatter::alternate`]: http://doc.rust-lang.org/nightly/core/fmt/struct.Formatter.html#method.alternate
+[`Formatter::fill`]: http://doc.rust-lang.org/nightly/core/fmt/struct.Formatter.html#method.fill
+[`Formatter::precision`]: http://doc.rust-lang.org/nightly/core/fmt/struct.Formatter.html#method.precision
+[`Formatter::sign_aware_zero_pad`]: http://doc.rust-lang.org/nightly/core/fmt/struct.Formatter.html#method.sign_aware_zero_pad
+[`Formatter::sign_minus`]: http://doc.rust-lang.org/nightly/core/fmt/struct.Formatter.html#method.sign_minus
+[`Formatter::sign_plus`]: http://doc.rust-lang.org/nightly/core/fmt/struct.Formatter.html#method.sign_plus
+[`Formatter::width`]: http://doc.rust-lang.org/nightly/core/fmt/struct.Formatter.html#method.width
+[`Iterator::cmp`]: http://doc.rust-lang.org/nightly/core/iter/trait.Iterator.html#method.cmp
+[`Iterator::eq`]: http://doc.rust-lang.org/nightly/core/iter/trait.Iterator.html#method.eq
+[`Iterator::ge`]: http://doc.rust-lang.org/nightly/core/iter/trait.Iterator.html#method.ge
+[`Iterator::gt`]: http://doc.rust-lang.org/nightly/core/iter/trait.Iterator.html#method.gt
+[`Iterator::le`]: http://doc.rust-lang.org/nightly/core/iter/trait.Iterator.html#method.le
+[`Iterator::lt`]: http://doc.rust-lang.org/nightly/core/iter/trait.Iterator.html#method.lt
+[`Iterator::ne`]: http://doc.rust-lang.org/nightly/core/iter/trait.Iterator.html#method.ne
+[`Iterator::partial_cmp`]: http://doc.rust-lang.org/nightly/core/iter/trait.Iterator.html#method.partial_cmp
+[`Path::canonicalize`]: http://doc.rust-lang.org/nightly/std/path/struct.Path.html#method.canonicalize
+[`Path::exists`]: http://doc.rust-lang.org/nightly/std/path/struct.Path.html#method.exists
+[`Path::is_dir`]: http://doc.rust-lang.org/nightly/std/path/struct.Path.html#method.is_dir
+[`Path::is_file`]: http://doc.rust-lang.org/nightly/std/path/struct.Path.html#method.is_file
+[`Path::metadata`]: http://doc.rust-lang.org/nightly/std/path/struct.Path.html#method.metadata
+[`Path::read_dir`]: http://doc.rust-lang.org/nightly/std/path/struct.Path.html#method.read_dir
+[`Path::read_link`]: http://doc.rust-lang.org/nightly/std/path/struct.Path.html#method.read_link
+[`Path::symlink_metadata`]: http://doc.rust-lang.org/nightly/std/path/struct.Path.html#method.symlink_metadata
+[`Utf8Error::valid_up_to`]: http://doc.rust-lang.org/nightly/core/str/struct.Utf8Error.html#method.valid_up_to
+[`Vec::resize`]: http://doc.rust-lang.org/nightly/std/vec/struct.Vec.html#method.resize
+[`VecDeque::as_mut_slices`]: http://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.as_mut_slices
+[`VecDeque::as_slices`]: http://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.as_slices
+[`VecDeque::insert`]: http://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.insert
+[`VecDeque::shrink_to_fit`]: http://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.shrink_to_fit
+[`VecDeque::swap_remove_back`]: http://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.swap_remove_back
+[`VecDeque::swap_remove_front`]: http://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.swap_remove_front
+[`slice::split_first_mut`]: http://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_first_mut
+[`slice::split_first`]: http://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_first
+[`slice::split_last_mut`]: http://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_last_mut
+[`slice::split_last`]: http://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_last
+[`char::from_u32_unchecked`]: http://doc.rust-lang.org/nightly/std/char/fn.from_u32_unchecked.html
+[`fs::canonicalize`]: http://doc.rust-lang.org/nightly/std/fs/fn.canonicalize.html
+[`str::MatchIndices`]: http://doc.rust-lang.org/nightly/std/str/struct.MatchIndices.html
+[`str::RMatchIndices`]: http://doc.rust-lang.org/nightly/std/str/struct.RMatchIndices.html
+[`str::match_indices`]: http://doc.rust-lang.org/nightly/std/primitive.str.html#method.match_indices
+[`str::rmatch_indices`]: http://doc.rust-lang.org/nightly/std/primitive.str.html#method.rmatch_indices
+[`str::slice_mut_unchecked`]: http://doc.rust-lang.org/nightly/std/primitive.str.html#method.slice_mut_unchecked
+[`string::ParseError`]: http://doc.rust-lang.org/nightly/std/string/enum.ParseError.html
+
 Version 1.4.0 (2015-10-29)
-============================
+==========================
 
 * ~1200 changes, numerous bugfixes
 
diff --git a/src/doc/book/enums.md b/src/doc/book/enums.md
index 8ad4eeedd18..e17d3f762b9 100644
--- a/src/doc/book/enums.md
+++ b/src/doc/book/enums.md
@@ -1,7 +1,8 @@
 % Enums
 
-An `enum` in Rust is a type that represents data that could be one of
-several possible variants:
+An `enum` in Rust is a type that represents data that is one of
+several possible variants. Each variant in the `enum` can optionally
+have data associated with it:
 
 ```rust
 enum Message {
@@ -12,9 +13,8 @@ enum Message {
 }
 ```
 
-Each variant can optionally have data associated with it. The syntax for
-defining variants resembles the syntaxes used to define structs: you can
-have variants with no data (like unit-like structs), variants with named
+The syntax for defining variants resembles the syntaxes used to define structs:
+you can have variants with no data (like unit-like structs), variants with named
 data, and variants with unnamed data (like tuple structs). Unlike
 separate struct definitions, however, an `enum` is a single type. A
 value of the enum can match any of the variants. For this reason, an
@@ -41,7 +41,7 @@ let y: BoardGameTurn = BoardGameTurn::Move { squares: 1 };
 Both variants are named `Move`, but since they’re scoped to the name of
 the enum, they can both be used without conflict.
 
-A value of an enum type contains information about which variant it is,
+A value of an `enum` type contains information about which variant it is,
 in addition to any data associated with that variant. This is sometimes
 referred to as a ‘tagged union’, since the data includes a ‘tag’
 indicating what type it is. The compiler uses this information to
@@ -67,7 +67,7 @@ equality yet, but we’ll find out in the [`traits`][traits] section.
 
 # Constructors as functions
 
-An enum’s constructors can also be used like functions. For example:
+An `enum` constructor can also be used like a function. For example:
 
 ```rust
 # enum Message {
@@ -76,7 +76,7 @@ An enum’s constructors can also be used like functions. For example:
 let m = Message::Write("Hello, world".to_string());
 ```
 
-Is the same as
+is the same as
 
 ```rust
 # enum Message {
diff --git a/src/doc/book/structs.md b/src/doc/book/structs.md
index b51ad8e087d..1d70ee27869 100644
--- a/src/doc/book/structs.md
+++ b/src/doc/book/structs.md
@@ -9,7 +9,8 @@ let origin_x = 0;
 let origin_y = 0;
 ```
 
-A `struct` lets us combine these two into a single, unified datatype:
+A `struct` lets us combine these two into a single, unified datatype with `x`
+and `y` as field labels:
 
 ```rust
 struct Point {
@@ -32,7 +33,7 @@ We can create an instance of our `struct` via `let`, as usual, but we use a `key
 value` style syntax to set each field. The order doesn’t need to be the same as
 in the original declaration.
 
-Finally, because fields have names, we can access the field through dot
+Finally, because fields have names, we can access them through dot
 notation: `origin.x`.
 
 The values in `struct`s are immutable by default, like other bindings in Rust.
@@ -67,9 +68,8 @@ struct Point {
 
 Mutability is a property of the binding, not of the structure itself. If you’re
 used to field-level mutability, this may seem strange at first, but it
-significantly simplifies things. It even lets you make things mutable for a short
-time only:
-
+significantly simplifies things. It even lets you make things mutable on a temporary
+basis:
 
 ```rust,ignore
 struct Point {
@@ -82,7 +82,7 @@ fn main() {
 
     point.x = 5;
 
-    let point = point; // this new binding can’t change now
+    let point = point; // now immutable
 
     point.y = 6; // this causes an error
 }
@@ -121,27 +121,24 @@ let point = Point3d { z: 1, x: 2, .. origin };
 # Tuple structs
 
 Rust has another data type that’s like a hybrid between a [tuple][tuple] and a
-`struct`, called a ‘tuple struct’. Tuple structs have a name, but
-their fields don’t:
+`struct`, called a ‘tuple struct’. Tuple structs have a name, but their fields
+don't. They are declared with the `struct` keyword, and then with a name
+followed by a tuple:
+
+[tuple]: primitive-types.html#tuples
 
 ```rust
 struct Color(i32, i32, i32);
 struct Point(i32, i32, i32);
-```
 
-[tuple]: primitive-types.html#tuples
-
-These two will not be equal, even if they have the same values:
-
-```rust
-# struct Color(i32, i32, i32);
-# struct Point(i32, i32, i32);
 let black = Color(0, 0, 0);
 let origin = Point(0, 0, 0);
 ```
+Here, `black` and `origin` are not equal, even though they contain the same
+values.
 
-It is almost always better to use a `struct` than a tuple struct. We would write
-`Color` and `Point` like this instead:
+It is almost always better to use a `struct` than a tuple struct. We
+would write `Color` and `Point` like this instead:
 
 ```rust
 struct Color {
@@ -157,13 +154,14 @@ struct Point {
 }
 ```
 
-Now, we have actual names, rather than positions. Good names are important,
-and with a `struct`, we have actual names.
+Good names are important, and while values in a tuple struct can be
+referenced with dot notation as well, a `struct` gives us actual names,
+rather than positions.
 
-There _is_ one case when a tuple struct is very useful, though, and that’s a
-tuple struct with only one element. We call this the ‘newtype’ pattern, because
-it allows you to create a new type, distinct from that of its contained value
-and expressing its own semantic meaning:
+There _is_ one case when a tuple struct is very useful, though, and that is when
+it has only one element. We call this the ‘newtype’ pattern, because
+it allows you to create a new type that is distinct from its contained value
+and also expresses its own semantic meaning:
 
 ```rust
 struct Inches(i32);
diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py
index 2acee8a97f5..8362c239b65 100644
--- a/src/etc/htmldocck.py
+++ b/src/etc/htmldocck.py
@@ -104,6 +104,7 @@ checks if the given file does not exist, for example.
 
 """
 
+from __future__ import print_function
 import sys
 import os.path
 import re
@@ -160,8 +161,13 @@ class CustomHTMLParser(HTMLParser):
         HTMLParser.close(self)
         return self.__builder.close()
 
-Command = namedtuple('Command', 'negated cmd args lineno')
+Command = namedtuple('Command', 'negated cmd args lineno context')
 
+class FailedCheck(Exception):
+    pass
+
+class InvalidCheck(Exception):
+    pass
 
 def concat_multi_lines(f):
     """returns a generator out of the file object, which
@@ -196,7 +202,7 @@ def concat_multi_lines(f):
             catenated = ''
 
     if lastline is not None:
-        raise RuntimeError('Trailing backslash in the end of file')
+        print_err(lineno, line, 'Trailing backslash at the end of the file')
 
 LINE_PATTERN = re.compile(r'''
     (?<=(?<!\S)@)(?P<negated>!?)
@@ -216,9 +222,10 @@ def get_commands(template):
             cmd = m.group('cmd')
             args = m.group('args')
             if args and not args[:1].isspace():
-                raise RuntimeError('Invalid template syntax at line {}'.format(lineno+1))
+                print_err(lineno, line, 'Invalid template syntax')
+                continue
             args = shlex.split(args)
-            yield Command(negated=negated, cmd=cmd, args=args, lineno=lineno+1)
+            yield Command(negated=negated, cmd=cmd, args=args, lineno=lineno+1, context=line)
 
 
 def _flatten(node, acc):
@@ -242,8 +249,7 @@ def normalize_xpath(path):
     elif path.startswith('.//'):
         return path
     else:
-        raise RuntimeError('Non-absolute XPath is not supported due to \
-                            the implementation issue.')
+        raise InvalidCheck('Non-absolute XPath is not supported due to implementation issues')
 
 
 class CachedFiles(object):
@@ -259,41 +265,40 @@ class CachedFiles(object):
             self.last_path = path
             return path
         elif self.last_path is None:
-            raise RuntimeError('Tried to use the previous path in the first command')
+            raise InvalidCheck('Tried to use the previous path in the first command')
         else:
             return self.last_path
 
     def get_file(self, path):
         path = self.resolve_path(path)
-        try:
+        if path in self.files:
             return self.files[path]
-        except KeyError:
-            try:
-                with open(os.path.join(self.root, path)) as f:
-                    data = f.read()
-            except Exception as e:
-                raise RuntimeError('Cannot open file {!r}: {}'.format(path, e))
-            else:
-                self.files[path] = data
-                return data
+
+        abspath = os.path.join(self.root, path)
+        if not(os.path.exists(abspath) and os.path.isfile(abspath)):
+            raise FailedCheck('File does not exist {!r}'.format(path))
+
+        with open(abspath) as f:
+            data = f.read()
+            self.files[path] = data
+            return data
 
     def get_tree(self, path):
         path = self.resolve_path(path)
-        try:
+        if path in self.trees:
             return self.trees[path]
-        except KeyError:
-            try:
-                f = open(os.path.join(self.root, path))
-            except Exception as e:
-                raise RuntimeError('Cannot open file {!r}: {}'.format(path, e))
+
+        abspath = os.path.join(self.root, path)
+        if not(os.path.exists(abspath) and os.path.isfile(abspath)):
+            raise FailedCheck('File does not exist {!r}'.format(path))
+
+        with open(abspath) as f:
             try:
-                with f:
-                    tree = ET.parse(f, CustomHTMLParser())
+                tree = ET.parse(f, CustomHTMLParser())
             except Exception as e:
                 raise RuntimeError('Cannot parse an HTML file {!r}: {}'.format(path, e))
-            else:
-                self.trees[path] = tree
-                return self.trees[path]
+            self.trees[path] = tree
+            return self.trees[path]
 
 
 def check_string(data, pat, regexp):
@@ -311,14 +316,14 @@ def check_tree_attr(tree, path, attr, pat, regexp):
     path = normalize_xpath(path)
     ret = False
     for e in tree.findall(path):
-        try:
+        if attr in e.attrib:
             value = e.attrib[attr]
-        except KeyError:
-            continue
         else:
-            ret = check_string(value, pat, regexp)
-            if ret:
-                break
+            continue
+
+        ret = check_string(value, pat, regexp)
+        if ret:
+            break
     return ret
 
 
@@ -341,57 +346,84 @@ def check_tree_count(tree, path, count):
     path = normalize_xpath(path)
     return len(tree.findall(path)) == count
 
+def stderr(*args):
+    print(*args, file=sys.stderr)
 
-def check(target, commands):
-    cache = CachedFiles(target)
-    for c in commands:
+def print_err(lineno, context, err, message=None):
+    global ERR_COUNT
+    ERR_COUNT += 1
+    stderr("{}: {}".format(lineno, message or err))
+    if message and err:
+        stderr("\t{}".format(err))
+
+    if context:
+        stderr("\t{}".format(context))
+
+ERR_COUNT = 0
+
+def check_command(c, cache):
+    try:
+        cerr = ""
         if c.cmd == 'has' or c.cmd == 'matches': # string test
             regexp = (c.cmd == 'matches')
             if len(c.args) == 1 and not regexp: # @has <path> = file existence
                 try:
                     cache.get_file(c.args[0])
                     ret = True
-                except RuntimeError:
+                except FailedCheck as err:
+                    cerr = err.message
                     ret = False
             elif len(c.args) == 2: # @has/matches <path> <pat> = string test
+                cerr = "`PATTERN` did not match"
                 ret = check_string(cache.get_file(c.args[0]), c.args[1], regexp)
             elif len(c.args) == 3: # @has/matches <path> <pat> <match> = XML tree test
+                cerr = "`XPATH PATTERN` did not match"
                 tree = cache.get_tree(c.args[0])
                 pat, sep, attr = c.args[1].partition('/@')
                 if sep: # attribute
-                    ret = check_tree_attr(cache.get_tree(c.args[0]), pat, attr, c.args[2], regexp)
+                    tree = cache.get_tree(c.args[0])
+                    ret = check_tree_attr(tree, pat, attr, c.args[2], regexp)
                 else: # normalized text
                     pat = c.args[1]
                     if pat.endswith('/text()'):
                         pat = pat[:-7]
                     ret = check_tree_text(cache.get_tree(c.args[0]), pat, c.args[2], regexp)
             else:
-                raise RuntimeError('Invalid number of @{} arguments \
-                                    at line {}'.format(c.cmd, c.lineno))
+                raise InvalidCheck('Invalid number of @{} arguments'.format(c.cmd))
 
         elif c.cmd == 'count': # count test
             if len(c.args) == 3: # @count <path> <pat> <count> = count test
                 ret = check_tree_count(cache.get_tree(c.args[0]), c.args[1], int(c.args[2]))
             else:
-                raise RuntimeError('Invalid number of @{} arguments \
-                                    at line {}'.format(c.cmd, c.lineno))
-
+                raise InvalidCheck('Invalid number of @{} arguments'.format(c.cmd))
         elif c.cmd == 'valid-html':
-            raise RuntimeError('Unimplemented @valid-html at line {}'.format(c.lineno))
+            raise InvalidCheck('Unimplemented @valid-html')
 
         elif c.cmd == 'valid-links':
-            raise RuntimeError('Unimplemented @valid-links at line {}'.format(c.lineno))
-
+            raise InvalidCheck('Unimplemented @valid-links')
         else:
-            raise RuntimeError('Unrecognized @{} at line {}'.format(c.cmd, c.lineno))
+            raise InvalidCheck('Unrecognized @{}'.format(c.cmd))
 
         if ret == c.negated:
-            raise RuntimeError('@{}{} check failed at line {}'.format('!' if c.negated else '',
-                                                                      c.cmd, c.lineno))
+            raise FailedCheck(cerr)
+
+    except FailedCheck as err:
+        message = '@{}{} check failed'.format('!' if c.negated else '', c.cmd)
+        print_err(c.lineno, c.context, err.message, message)
+    except InvalidCheck as err:
+        print_err(c.lineno, c.context, err.message)
+
+def check(target, commands):
+    cache = CachedFiles(target)
+    for c in commands:
+        check_command(c, cache)
 
 if __name__ == '__main__':
-    if len(sys.argv) < 3:
-        print >>sys.stderr, 'Usage: {} <doc dir> <template>'.format(sys.argv[0])
+    if len(sys.argv) != 3:
+        stderr('Usage: {} <doc dir> <template>'.format(sys.argv[0]))
+        raise SystemExit(1)
+
+    check(sys.argv[1], get_commands(sys.argv[2]))
+    if ERR_COUNT:
+        stderr("\nEncountered {} errors".format(ERR_COUNT))
         raise SystemExit(1)
-    else:
-        check(sys.argv[1], get_commands(sys.argv[2]))
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index f8483a8ed9b..9479d47943e 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -385,13 +385,6 @@ impl<T: ?Sized> Deref for Arc<T> {
 }
 
 impl<T: Clone> Arc<T> {
-    #[unstable(feature = "arc_make_unique", reason = "renamed to Arc::make_mut",
-               issue = "27718")]
-    #[rustc_deprecated(since = "1.4.0", reason = "renamed to Arc::make_mut")]
-    pub fn make_unique(this: &mut Self) -> &mut T {
-        Arc::make_mut(this)
-    }
-
     /// Make a mutable reference into the given `Arc<T>` by cloning the inner
     /// data if the `Arc<T>` doesn't have one strong reference and no weak
     /// references.
@@ -428,7 +421,7 @@ impl<T: Clone> Arc<T> {
         // weak count, there's no chance the ArcInner itself could be
         // deallocated.
         if this.inner().strong.compare_and_swap(1, 0, Acquire) != 1 {
-            // Another srong pointer exists; clone
+            // Another strong pointer exists; clone
             *this = Arc::new((**this).clone());
         } else if this.inner().weak.load(Relaxed) != 1 {
             // Relaxed suffices in the above because this is fundamentally an
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 404c7522403..8f00605d33b 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -360,14 +360,6 @@ impl<T: ?Sized> Rc<T> {
 }
 
 impl<T: Clone> Rc<T> {
-    #[inline]
-    #[unstable(feature = "rc_make_unique", reason = "renamed to Rc::make_mut",
-               issue = "27718")]
-    #[rustc_deprecated(since = "1.4.0", reason = "renamed to Rc::make_mut")]
-    pub fn make_unique(&mut self) -> &mut T {
-        Rc::make_mut(self)
-    }
-
     /// Make a mutable reference into the given `Rc<T>` by cloning the inner
     /// data if the `Rc<T>` doesn't have one strong reference and no weak
     /// references.
diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs
index b8ca48ac75d..04cffeddc5f 100644
--- a/src/libcollections/binary_heap.rs
+++ b/src/libcollections/binary_heap.rs
@@ -230,26 +230,6 @@ impl<T: Ord> BinaryHeap<T> {
         BinaryHeap { data: Vec::with_capacity(capacity) }
     }
 
-    /// Creates a `BinaryHeap` from a vector. This is sometimes called
-    /// `heapifying` the vector.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(binary_heap_extras)]
-    /// # #![allow(deprecated)]
-    ///
-    /// use std::collections::BinaryHeap;
-    /// let heap = BinaryHeap::from_vec(vec![9, 1, 2, 7, 3, 2]);
-    /// ```
-    #[unstable(feature = "binary_heap_extras",
-               reason = "needs to be audited",
-               issue = "28147")]
-    #[rustc_deprecated(since = "1.5.0", reason = "use BinaryHeap::from instead")]
-    pub fn from_vec(vec: Vec<T>) -> BinaryHeap<T> {
-        BinaryHeap::from(vec)
-    }
-
     /// Returns an iterator visiting all values in the underlying vector, in
     /// arbitrary order.
     ///
diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs
index 08b0a39d9b0..de9c8a2feaf 100644
--- a/src/libcollections/btree/map.rs
+++ b/src/libcollections/btree/map.rs
@@ -151,25 +151,14 @@ impl<K: Ord, V> BTreeMap<K, V> {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[allow(deprecated)]
     pub fn new() -> BTreeMap<K, V> {
-        // FIXME(Gankro): Tune this as a function of size_of<K/V>?
-        BTreeMap::with_b(6)
-    }
-
-    /// Makes a new empty BTreeMap with the given B.
-    ///
-    /// B cannot be less than 2.
-    #[unstable(feature = "btree_b",
-               reason = "probably want this to be on the type, eventually",
-               issue = "27795")]
-    #[rustc_deprecated(since = "1.4.0", reason = "niche API")]
-    pub fn with_b(b: usize) -> BTreeMap<K, V> {
-        assert!(b > 1, "B must be greater than 1");
         BTreeMap {
             length: 0,
             depth: 1,
-            root: Node::make_leaf_root(b),
-            b: b,
+            root: Node::make_leaf_root(6),
+            // FIXME(Gankro): Tune this as a function of size_of<K/V>?
+            b: 6,
         }
+
     }
 
     /// Clears the map, removing all values.
@@ -185,11 +174,9 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// assert!(a.is_empty());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[allow(deprecated)]
     pub fn clear(&mut self) {
-        let b = self.b;
         // avoid recursive destructors by manually traversing the tree
-        for _ in mem::replace(self, BTreeMap::with_b(b)) {}
+        for _ in mem::replace(self, BTreeMap::new()) {}
     }
 
     // Searching in a B-Tree is pretty straightforward.
diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs
index 8d741f9e34a..a2c09c36795 100644
--- a/src/libcollections/btree/set.rs
+++ b/src/libcollections/btree/set.rs
@@ -98,18 +98,6 @@ impl<T: Ord> BTreeSet<T> {
     pub fn new() -> BTreeSet<T> {
         BTreeSet { map: BTreeMap::new() }
     }
-
-    /// Makes a new BTreeSet with the given B.
-    ///
-    /// B cannot be less than 2.
-    #[unstable(feature = "btree_b",
-               reason = "probably want this to be on the type, eventually",
-               issue = "27795")]
-    #[rustc_deprecated(since = "1.4.0", reason = "niche API")]
-    #[allow(deprecated)]
-    pub fn with_b(b: usize) -> BTreeSet<T> {
-        BTreeSet { map: BTreeMap::with_b(b) }
-    }
 }
 
 impl<T> BTreeSet<T> {
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 6342ae5c816..9bb5ec80819 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -110,9 +110,6 @@ pub use core::slice::{Iter, IterMut};
 pub use core::slice::{SplitMut, ChunksMut, Split};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut};
-#[unstable(feature = "ref_slice", issue = "27774")]
-#[allow(deprecated)]
-pub use core::slice::{bytes, mut_ref_slice, ref_slice};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::slice::{from_raw_parts, from_raw_parts_mut};
 
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index a3c69182934..8c0b52f71f8 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -291,13 +291,23 @@ pub struct FromUtf8Error {
 pub struct FromUtf16Error(());
 
 impl String {
-    /// Creates a new string buffer initialized with the empty string.
+    /// Creates a new empty `String`.
+    ///
+    /// Given that the `String` is empty, this will not allocate any initial
+    /// buffer. While that means that this initial operation is very
+    /// inexpensive, but may cause excessive allocation later, when you add
+    /// data. If you have an idea of how much data the `String` will hold,
+    /// consider the [`with_capacity()`] method to prevent excessive
+    /// re-allocation.
+    ///
+    /// [`with_capacity()`]: #method.with_capacity
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
-    /// # #![allow(unused_mut)]
-    /// let mut s = String::new();
+    /// let s = String::new();
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -305,12 +315,26 @@ impl String {
         String { vec: Vec::new() }
     }
 
-    /// Creates a new string buffer with the given capacity.
-    /// The string will be able to hold exactly `capacity` bytes without
-    /// reallocating. If `capacity` is 0, the string will not allocate.
+    /// Creates a new empty `String` with a particular capacity.
+    ///
+    /// `String`s have an internal buffer to hold their data. The capacity is
+    /// the length of that buffer, and can be queried with the [`capacity()`]
+    /// method. This method creates an empty `String`, but one with an initial
+    /// buffer that can hold `capacity` bytes. This is useful when you may be
+    /// appending a bunch of data to the `String`, reducing the number of
+    /// reallocations it needs to do.
+    ///
+    /// [`capacity()`]: #method.capacity
+    ///
+    /// If the given capacity is `0`, no allocation will occur, and this method
+    /// is identical to the [`new()`] method.
+    ///
+    /// [`new()`]: #method.new
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let mut s = String::with_capacity(10);
     ///
@@ -346,26 +370,30 @@ impl String {
 
     /// Converts a vector of bytes to a `String`.
     ///
-    /// A string slice (`&str`) is made of bytes (`u8`), and a vector of bytes
-    /// (`Vec<u8>`) is made of bytes, so this function converts between the
+    /// A string slice ([`&str`]) is made of bytes ([`u8`]), and a vector of bytes
+    /// ([`Vec<u8>`]) is made of bytes, so this function converts between the
     /// two. Not all byte slices are valid `String`s, however: `String`
     /// 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`]: ../primitive.str.html
+    /// [`u8`]: ../primitive.u8.html
+    /// [`Vec<u8>`]: ../vec/struct.Vec.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 this function, [`from_utf8_unchecked()`][fromutf8], which has the
-    /// same behavior but skips the check.
+    /// of this function, [`from_utf8_unchecked()`], which has the same behavior
+    /// but skips the check.
     ///
-    /// [fromutf8]: struct.String.html#method.from_utf8_unchecked
+    /// [`from_utf8_unchecked()`]: struct.String.html#method.from_utf8_unchecked
     ///
     /// This method will take care to not copy the vector, for efficiency's
     /// sake.
     ///
     /// If you need a `&str` instead of a `String`, consider
-    /// [`str::from_utf8()`][str].
+    /// [`str::from_utf8()`].
     ///
-    /// [str]: ../str/fn.from_utf8.html
+    /// [`str::from_utf8()`]: ../str/fn.from_utf8.html
     ///
     /// # Failure
     ///
@@ -395,10 +423,10 @@ impl String {
     /// assert!(String::from_utf8(sparkle_heart).is_err());
     /// ```
     ///
-    /// See the docs for [`FromUtf8Error`][error] for more details on what you
-    /// can do with this error.
+    /// See the docs for [`FromUtf8Error`] for more details on what you can do
+    /// with this error.
     ///
-    /// [error]: struct.FromUtf8Error.html
+    /// [`FromUtf8Error`]: struct.FromUtf8Error.html
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
@@ -415,24 +443,28 @@ impl String {
 
     /// Converts a slice of bytes to a `String`, including invalid characters.
     ///
-    /// A string slice (`&str`) is made of bytes (`u8`), and a slice of bytes
-    /// (`&[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. During this conversion, `from_utf8_lossy()`
-    /// will replace any invalid UTF-8 sequences with
+    /// A string slice ([`&str`]) is made of bytes ([`u8`]), and a slice of
+    /// bytes ([`&[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. During this conversion,
+    /// `from_utf8_lossy()` will replace any invalid UTF-8 sequences with
     /// `U+FFFD REPLACEMENT CHARACTER`, which looks like this: �
     ///
+    /// [`&str`]: ../primitive.str.html
+    /// [`u8`]: ../primitive.u8.html
+    /// [`&[u8]`]: ../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 conversion, there is an unsafe version
-    /// of this function, [`from_utf8_unchecked()`][fromutf8], which has the
-    /// same behavior but skips the checks.
+    /// of this function, [`from_utf8_unchecked()`], which has the same behavior
+    /// but skips the checks.
     ///
-    /// [fromutf8]: struct.String.html#method.from_utf8_unchecked
+    /// [`from_utf8_unchecked()`]: struct.String.html#method.from_utf8_unchecked
     ///
-    /// If you need a `&str` instead of a `String`, consider
-    /// [`str::from_utf8()`][str].
+    /// If you need a [`&str`] instead of a `String`, consider
+    /// [`str::from_utf8()`].
     ///
-    /// [str]: ../str/fn.from_utf8.html
+    /// [`str::from_utf8()`]: ../str/fn.from_utf8.html
     ///
     /// # Examples
     ///
@@ -576,12 +608,14 @@ impl String {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// // 𝄞music
     /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
     ///           0x0073, 0x0069, 0x0063];
-    /// assert_eq!(String::from_utf16(v).unwrap(),
-    ///            "𝄞music".to_string());
+    /// assert_eq!(String::from("𝄞music"),
+    ///            String::from_utf16(v).unwrap());
     ///
     /// // 𝄞mu<invalid>ic
     /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
@@ -598,14 +632,16 @@ impl String {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// // 𝄞mus<invalid>ic<invalid>
     /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
     ///           0x0073, 0xDD1E, 0x0069, 0x0063,
     ///           0xD834];
     ///
-    /// assert_eq!(String::from_utf16_lossy(v),
-    ///            "𝄞mus\u{FFFD}ic\u{FFFD}".to_string());
+    /// assert_eq!(String::from("𝄞mus\u{FFFD}ic\u{FFFD}"),
+    ///            String::from_utf16_lossy(v));
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -617,13 +653,37 @@ impl String {
     ///
     /// # Safety
     ///
-    /// This is _very_ unsafe because:
+    /// This is highly unsafe, due to the number of invariants that aren't
+    /// checked:
     ///
-    /// * We call `Vec::from_raw_parts` to get a `Vec<u8>`. Therefore, this
-    ///   function inherits all of its unsafety, see [its
-    ///   documentation](../vec/struct.Vec.html#method.from_raw_parts)
-    ///   for the invariants it expects, they also apply to this function.
-    /// * We assume that the `Vec` contains valid UTF-8.
+    /// * The memory at `ptr` needs to have been previously allocated by the
+    ///   same allocator the standard library uses.
+    /// * `length` needs to be less than or equal to `capacity`.
+    /// * `capacity` needs to be the correct value.
+    ///
+    /// Violating these may cause problems like corrupting the allocator's
+    /// internal datastructures.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// use std::mem;
+    ///
+    /// unsafe {
+    ///     let s = String::from("hello");
+    ///     let ptr = s.as_ptr();
+    ///     let len = s.len();
+    ///     let capacity = s.capacity();
+    ///
+    ///     mem::forget(s);
+    ///
+    ///     let s = String::from_raw_parts(ptr as *mut _, len, capacity);
+    ///
+    ///     assert_eq!(String::from("hello"), s);
+    /// }
+    /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String {
@@ -633,15 +693,16 @@ impl String {
     /// Converts a vector of bytes to a `String` without checking that the
     /// string contains valid UTF-8.
     ///
-    /// See the safe version, [`from_utf8()`][fromutf8], for more.
+    /// See the safe version, [`from_utf8()`], for more details.
     ///
-    /// [fromutf8]: struct.String.html#method.from_utf8
+    /// [`from_utf8()`]: struct.String.html#method.from_utf8
     ///
     /// # Safety
     ///
-    /// This function is unsafe because it does not check that the bytes passed to
-    /// it are valid UTF-8. If this constraint is violated, undefined behavior
-    /// results, as the rest of Rust assumes that `String`s are valid UTF-8.
+    /// This function is unsafe because it does not check that the bytes passed
+    /// to it are valid UTF-8. If this constraint is violated, it may cause
+    /// memory unsafety issues with future users of the `String`, as the rest of
+    /// the standard library assumes that `String`s are valid UTF-8.
     ///
     /// # Examples
     ///
@@ -663,14 +724,19 @@ impl String {
         String { vec: bytes }
     }
 
-    /// Returns the underlying byte buffer, encoded as UTF-8.
+    /// Converts a `String` into a byte vector.
+    ///
+    /// This consumes the `String`, so we do not need to copy its contents.
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let s = String::from("hello");
     /// let bytes = s.into_bytes();
-    /// assert_eq!(bytes, [104, 101, 108, 108, 111]);
+    ///
+    /// assert_eq!(&[104, 101, 108, 108, 111][..], &bytes[..]);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -687,14 +753,18 @@ impl String {
         self
     }
 
-    /// Pushes the given string onto this string buffer.
+    /// Appends a given string slice onto the end of this `String`.
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let mut s = String::from("foo");
+    ///
     /// s.push_str("bar");
-    /// assert_eq!(s, "foobar");
+    ///
+    /// assert_eq!("foobar", s);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -702,13 +772,15 @@ impl String {
         self.vec.extend_from_slice(string.as_bytes())
     }
 
-    /// Returns the number of bytes that this string buffer can hold without
-    /// reallocating.
+    /// Returns this `String`'s capacity, in bytes.
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let s = String::with_capacity(10);
+    ///
     /// assert!(s.capacity() >= 10);
     /// ```
     #[inline]
@@ -717,9 +789,16 @@ impl String {
         self.vec.capacity()
     }
 
-    /// Reserves capacity for at least `additional` more bytes to be inserted
-    /// in the given `String`. The collection may reserve more space to avoid
-    /// frequent reallocations.
+    /// Ensures that this `String`'s capacity is at least `additional` bytes
+    /// larger than its length.
+    ///
+    /// The capacity may be increased by more than `additional` bytes if it
+    /// chooses, to prevent frequent reallocations.
+    ///
+    /// If you do not want this "at least" behavior, see the [`reserve_exact()`]
+    /// method.
+    ///
+    /// [`reserve_exact()`]: #method.reserve_exact
     ///
     /// # Panics
     ///
@@ -727,24 +806,46 @@ impl String {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let mut s = String::new();
+    ///
     /// s.reserve(10);
+    ///
     /// assert!(s.capacity() >= 10);
     /// ```
+    ///
+    /// This may not actually increase the capacity:
+    ///
+    /// ```
+    /// let mut s = String::with_capacity(10);
+    /// s.push('a');
+    /// s.push('b');
+    ///
+    /// // s now has a length of 2 and a capacity of 10
+    /// assert_eq!(2, s.len());
+    /// assert_eq!(10, s.capacity());
+    ///
+    /// // Since we already have an extra 8 capacity, calling this...
+    /// s.reserve(8);
+    ///
+    /// // ... doesn't actually increase.
+    /// assert_eq!(10, s.capacity());
+    /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn reserve(&mut self, additional: usize) {
         self.vec.reserve(additional)
     }
 
-    /// Reserves the minimum capacity for exactly `additional` more bytes to be
-    /// inserted in the given `String`. Does nothing if the capacity is already
-    /// sufficient.
+    /// Ensures that this `String`'s capacity is `additional` bytes
+    /// larger than its length.
     ///
-    /// Note that the allocator may give the collection more space than it
-    /// requests. Therefore capacity can not be relied upon to be precisely
-    /// minimal. Prefer `reserve` if future insertions are expected.
+    /// Consider using the [`reserve()`] method unless you absolutely know
+    /// better than the allocator.
+    ///
+    /// [`reserve()`]: #method.reserve
     ///
     /// # Panics
     ///
@@ -752,27 +853,53 @@ impl String {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let mut s = String::new();
+    ///
     /// s.reserve_exact(10);
+    ///
     /// assert!(s.capacity() >= 10);
     /// ```
+    ///
+    /// This may not actually increase the capacity:
+    ///
+    /// ```
+    /// let mut s = String::with_capacity(10);
+    /// s.push('a');
+    /// s.push('b');
+    ///
+    /// // s now has a length of 2 and a capacity of 10
+    /// assert_eq!(2, s.len());
+    /// assert_eq!(10, s.capacity());
+    ///
+    /// // Since we already have an extra 8 capacity, calling this...
+    /// s.reserve_exact(8);
+    ///
+    /// // ... doesn't actually increase.
+    /// assert_eq!(10, s.capacity());
+    /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn reserve_exact(&mut self, additional: usize) {
         self.vec.reserve_exact(additional)
     }
 
-    /// Shrinks the capacity of this string buffer to match its length.
+    /// Shrinks the capacity of this `String` to match its length.
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let mut s = String::from("foo");
+    ///
     /// s.reserve(100);
     /// assert!(s.capacity() >= 100);
+    ///
     /// s.shrink_to_fit();
-    /// assert_eq!(s.capacity(), 3);
+    /// assert_eq!(3, s.capacity());
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -780,16 +907,20 @@ impl String {
         self.vec.shrink_to_fit()
     }
 
-    /// Adds the given character to the end of the string.
+    /// Appends the given `char` to the end of this `String`.
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let mut s = String::from("abc");
+    ///
     /// s.push('1');
     /// s.push('2');
     /// s.push('3');
-    /// assert_eq!(s, "abc123");
+    ///
+    /// assert_eq!("abc123", s);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -815,13 +946,16 @@ impl String {
         }
     }
 
-    /// Works with the underlying buffer as a byte slice.
+    /// Returns a byte slice of this `String`'s contents.
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let s = String::from("hello");
-    /// assert_eq!(s.as_bytes(), [104, 101, 108, 108, 111]);
+    ///
+    /// assert_eq!(&[104, 101, 108, 108, 111], s.as_bytes());
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -829,19 +963,25 @@ impl String {
         &self.vec
     }
 
-    /// Shortens a string to the specified length.
+    /// Shortens this `String` to the specified length.
     ///
     /// # Panics
     ///
-    /// Panics if `new_len` > current length,
-    /// or if `new_len` is not a character boundary.
+    /// Panics if `new_len` > current length, or if `new_len` does not lie on a
+    /// [`char`] boundary.
+    ///
+    /// [`char`]: ../primitive.char.html
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let mut s = String::from("hello");
+    ///
     /// s.truncate(2);
-    /// assert_eq!(s, "he");
+    ///
+    /// assert_eq!("he", s);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -851,15 +991,20 @@ impl String {
     }
 
     /// Removes the last character from the string buffer and returns it.
-    /// Returns `None` if this string buffer is empty.
+    ///
+    /// Returns `None` if this `String` is empty.
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let mut s = String::from("foo");
+    ///
     /// assert_eq!(s.pop(), Some('o'));
     /// assert_eq!(s.pop(), Some('o'));
     /// assert_eq!(s.pop(), Some('f'));
+    ///
     /// assert_eq!(s.pop(), None);
     /// ```
     #[inline]
@@ -877,23 +1022,25 @@ impl String {
         Some(ch)
     }
 
-    /// Removes the character from the string buffer at byte position `idx` and
-    /// returns it.
-    ///
-    /// # Warning
+    /// Removes a `char` from this `String` at a byte position and returns it.
     ///
-    /// This is an O(n) operation as it requires copying every element in the
+    /// This is an `O(n)` operation, as it requires copying every element in the
     /// buffer.
     ///
     /// # Panics
     ///
-    /// If `idx` does not lie on a character boundary, or if it is out of
-    /// bounds, then this function will panic.
+    /// Panics if `idx` is larger than the `String`'s length, or if it does not
+    /// lie on a [`char`] boundary.
+    ///
+    /// [`char`]: ../primitive.char.html
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let mut s = String::from("foo");
+    ///
     /// assert_eq!(s.remove(0), 'f');
     /// assert_eq!(s.remove(1), 'o');
     /// assert_eq!(s.remove(0), 'o');
@@ -915,17 +1062,31 @@ impl String {
         ch
     }
 
-    /// Inserts a character into the string buffer at byte position `idx`.
+    /// Inserts a character into this `String` at a byte position.
     ///
-    /// # Warning
-    ///
-    /// This is an O(n) operation as it requires copying every element in the
+    /// This is an `O(n)` operation as it requires copying every element in the
     /// buffer.
     ///
     /// # Panics
     ///
-    /// If `idx` does not lie on a character boundary or is out of bounds, then
-    /// this function will panic.
+    /// Panics if `idx` is larger than the `String`'s length, or if it does not
+    /// lie on a [`char`] boundary.
+    ///
+    /// [`char`]: ../primitive.char.html
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// let mut s = String::with_capacity(3);
+    ///
+    /// s.insert(0, 'f');
+    /// s.insert(1, 'o');
+    /// s.insert(2, 'o');
+    ///
+    /// assert_eq!("foo", s);
+    /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn insert(&mut self, idx: usize, ch: char) {
@@ -947,18 +1108,26 @@ impl String {
         }
     }
 
-    /// Views the string buffer as a mutable sequence of bytes.
+    /// Returns a mutable reference to the contents of this `String`.
     ///
-    /// This is unsafe because it does not check
-    /// to ensure that the resulting string will be valid UTF-8.
+    /// # Safety
+    ///
+    /// This function is unsafe because it does not check that the bytes passed
+    /// to it are valid UTF-8. If this constraint is violated, it may cause
+    /// memory unsafety issues with future users of the `String`, as the rest of
+    /// the standard library assumes that `String`s are valid UTF-8.
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let mut s = String::from("hello");
+    ///
     /// unsafe {
     ///     let vec = s.as_mut_vec();
-    ///     assert!(vec == &[104, 101, 108, 108, 111]);
+    ///     assert_eq!(&[104, 101, 108, 108, 111][..], &vec[..]);
+    ///
     ///     vec.reverse();
     /// }
     /// assert_eq!(s, "olleh");
@@ -969,12 +1138,15 @@ impl String {
         &mut self.vec
     }
 
-    /// Returns the number of bytes in this string.
+    /// Returns the length of this `String`, in bytes.
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
-    /// let a = "foo".to_string();
+    /// let a = String::from("foo");
+    ///
     /// assert_eq!(a.len(), 3);
     /// ```
     #[inline]
@@ -983,13 +1155,18 @@ impl String {
         self.vec.len()
     }
 
-    /// Returns true if the string contains no bytes
+    /// Returns `true` if this `String` has a length of zero.
+    ///
+    /// Returns `false` otherwise.
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let mut v = String::new();
     /// assert!(v.is_empty());
+    ///
     /// v.push('a');
     /// assert!(!v.is_empty());
     /// ```
@@ -999,14 +1176,23 @@ impl String {
         self.len() == 0
     }
 
-    /// Truncates the string, returning it to 0 length.
+    /// Truncates this `String`, removing all contents.
+    ///
+    /// While this means the `String` will have a length of zero, it does not
+    /// touch its capacity.
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
-    /// let mut s = "foo".to_string();
+    /// let mut s = String::from("foo");
+    ///
     /// s.clear();
+    ///
     /// assert!(s.is_empty());
+    /// assert_eq!(0, s.len());
+    /// assert_eq!(3, s.capacity());
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -1020,11 +1206,15 @@ impl String {
     ///
     /// # Panics
     ///
-    /// Panics if the starting point or end point are not on character boundaries,
-    /// or if they are out of bounds.
+    /// Panics if the starting point or end point do not lie on a [`char`]
+    /// boundary, or if they're out of bounds.
+    ///
+    /// [`char`]: ../primitive.char.html
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let mut s = String::from("α is alpha, β is beta");
     /// let beta_offset = s.find('β').unwrap_or(s.len());
@@ -1066,25 +1256,24 @@ impl String {
         }
     }
 
-    /// Converts the string into `Box<str>`.
+    /// Converts this `String` into a `Box<str>`.
+    ///
+    /// This will drop any excess capacity.
+    ///
+    /// # Examples
     ///
-    /// Note that this will drop any excess capacity.
+    /// Basic usage:
+    ///
+    /// ```
+    /// let s = String::from("hello");
+    ///
+    /// let b = s.into_boxed_str();
+    /// ```
     #[stable(feature = "box_str", since = "1.4.0")]
     pub fn into_boxed_str(self) -> Box<str> {
         let slice = self.vec.into_boxed_slice();
         unsafe { mem::transmute::<Box<[u8]>, Box<str>>(slice) }
     }
-
-    /// Converts the string into `Box<str>`.
-    ///
-    /// Note that this will drop any excess capacity.
-    #[unstable(feature = "box_str2",
-               reason = "recently added, matches RFC",
-               issue = "27785")]
-    #[rustc_deprecated(since = "1.4.0", reason = "renamed to `into_boxed_str`")]
-    pub fn into_boxed_slice(self) -> Box<str> {
-        self.into_boxed_str()
-    }
 }
 
 impl FromUtf8Error {
diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs
index 53597f566b8..0ca4ce2dddf 100644
--- a/src/libcollections/vec_deque.rs
+++ b/src/libcollections/vec_deque.rs
@@ -1115,15 +1115,6 @@ impl<T> VecDeque<T> {
         self.pop_back()
     }
 
-    /// deprecated
-    #[unstable(feature = "deque_extras",
-               reason = "the naming of this function may be altered",
-               issue = "27788")]
-    #[rustc_deprecated(since = "1.5.0", reason = "renamed to swap_remove_back")]
-    pub fn swap_back_remove(&mut self, index: usize) -> Option<T> {
-        self.swap_remove_back(index)
-    }
-
     /// Removes an element from anywhere in the `VecDeque` and returns it,
     /// replacing it with the first element.
     ///
@@ -1158,15 +1149,6 @@ impl<T> VecDeque<T> {
         self.pop_front()
     }
 
-    /// deprecated
-    #[unstable(feature = "deque_extras",
-               reason = "the naming of this function may be altered",
-               issue = "27788")]
-    #[rustc_deprecated(since = "1.5.0", reason = "renamed to swap_remove_front")]
-    pub fn swap_front_remove(&mut self, index: usize) -> Option<T> {
-        self.swap_remove_front(index)
-    }
-
     /// Inserts an element at `index` within the `VecDeque`. Whichever
     /// end is closer to the insertion point will be moved to make room,
     /// and all the affected elements will be moved to new positions.
@@ -2178,7 +2160,7 @@ mod tests {
                             tester.push_front(i);
                         }
                         for i in 0..len {
-                            assert_eq!(tester.swap_back_remove(i), Some(len * 2 - 1 - i));
+                            assert_eq!(tester.swap_remove_back(i), Some(len * 2 - 1 - i));
                         }
                     } else {
                         for i in 0..len * 2 {
@@ -2186,7 +2168,7 @@ mod tests {
                         }
                         for i in 0..len {
                             let idx = tester.len() - 1 - i;
-                            assert_eq!(tester.swap_front_remove(idx), Some(len * 2 - 1 - i));
+                            assert_eq!(tester.swap_remove_front(idx), Some(len * 2 - 1 - i));
                         }
                     }
                     assert!(tester.tail < tester.cap());
diff --git a/src/libcollectionstest/binary_heap.rs b/src/libcollectionstest/binary_heap.rs
index 303a0ce811d..cc4366e8ae4 100644
--- a/src/libcollectionstest/binary_heap.rs
+++ b/src/libcollectionstest/binary_heap.rs
@@ -14,7 +14,7 @@ use std::collections::BinaryHeap;
 fn test_iterator() {
     let data = vec![5, 9, 3];
     let iterout = [9, 5, 3];
-    let heap = BinaryHeap::from_vec(data);
+    let heap = BinaryHeap::from(data);
     let mut i = 0;
     for el in &heap {
         assert_eq!(*el, iterout[i]);
@@ -26,7 +26,7 @@ fn test_iterator() {
 fn test_iterator_reverse() {
     let data = vec![5, 9, 3];
     let iterout = vec![3, 5, 9];
-    let pq = BinaryHeap::from_vec(data);
+    let pq = BinaryHeap::from(data);
 
     let v: Vec<_> = pq.iter().rev().cloned().collect();
     assert_eq!(v, iterout);
@@ -36,7 +36,7 @@ fn test_iterator_reverse() {
 fn test_move_iter() {
     let data = vec![5, 9, 3];
     let iterout = vec![9, 5, 3];
-    let pq = BinaryHeap::from_vec(data);
+    let pq = BinaryHeap::from(data);
 
     let v: Vec<_> = pq.into_iter().collect();
     assert_eq!(v, iterout);
@@ -45,7 +45,7 @@ fn test_move_iter() {
 #[test]
 fn test_move_iter_size_hint() {
     let data = vec![5, 9];
-    let pq = BinaryHeap::from_vec(data);
+    let pq = BinaryHeap::from(data);
 
     let mut it = pq.into_iter();
 
@@ -63,7 +63,7 @@ fn test_move_iter_size_hint() {
 fn test_move_iter_reverse() {
     let data = vec![5, 9, 3];
     let iterout = vec![3, 5, 9];
-    let pq = BinaryHeap::from_vec(data);
+    let pq = BinaryHeap::from(data);
 
     let v: Vec<_> = pq.into_iter().rev().collect();
     assert_eq!(v, iterout);
@@ -74,7 +74,7 @@ fn test_peek_and_pop() {
     let data = vec![2, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];
     let mut sorted = data.clone();
     sorted.sort();
-    let mut heap = BinaryHeap::from_vec(data);
+    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());
@@ -83,7 +83,7 @@ fn test_peek_and_pop() {
 
 #[test]
 fn test_push() {
-    let mut heap = BinaryHeap::from_vec(vec![2, 4, 9]);
+    let mut heap = BinaryHeap::from(vec![2, 4, 9]);
     assert_eq!(heap.len(), 3);
     assert!(*heap.peek().unwrap() == 9);
     heap.push(11);
@@ -105,7 +105,7 @@ fn test_push() {
 
 #[test]
 fn test_push_unique() {
-    let mut heap = BinaryHeap::<Box<_>>::from_vec(vec![box 2, box 4, box 9]);
+    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);
@@ -127,7 +127,7 @@ fn test_push_unique() {
 
 #[test]
 fn test_push_pop() {
-    let mut heap = BinaryHeap::from_vec(vec![5, 5, 2, 1, 3]);
+    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);
@@ -141,7 +141,7 @@ fn test_push_pop() {
 
 #[test]
 fn test_replace() {
-    let mut heap = BinaryHeap::from_vec(vec![5, 5, 2, 1, 3]);
+    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);
@@ -154,7 +154,7 @@ fn test_replace() {
 }
 
 fn check_to_vec(mut data: Vec<i32>) {
-    let heap = BinaryHeap::from_vec(data.clone());
+    let heap = BinaryHeap::from(data.clone());
     let mut v = heap.clone().into_vec();
     v.sort();
     data.sort();
diff --git a/src/libcollectionstest/btree/map.rs b/src/libcollectionstest/btree/map.rs
index 846353cc4e7..dfb72d78d46 100644
--- a/src/libcollectionstest/btree/map.rs
+++ b/src/libcollectionstest/btree/map.rs
@@ -11,7 +11,6 @@
 use std::collections::BTreeMap;
 use std::collections::Bound::{Excluded, Included, Unbounded, self};
 use std::collections::btree_map::Entry::{Occupied, Vacant};
-use std::iter::range_inclusive;
 use std::rc::Rc;
 
 #[test]
@@ -188,7 +187,7 @@ fn test_range() {
     for i in 0..size {
         for j in i..size {
             let mut kvs = map.range(Included(&i), Included(&j)).map(|(&k, &v)| (k, v));
-            let mut pairs = range_inclusive(i, j).map(|i| (i, i));
+            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);
diff --git a/src/libcollectionstest/slice.rs b/src/libcollectionstest/slice.rs
index 80dcd48fbfa..f86c016921e 100644
--- a/src/libcollectionstest/slice.rs
+++ b/src/libcollectionstest/slice.rs
@@ -867,17 +867,6 @@ fn test_vec_default() {
 }
 
 #[test]
-fn test_bytes_set_memory() {
-    use std::slice::bytes::MutableByteVector;
-
-    let mut values = [1,2,3,4,5];
-    values[0..5].set_memory(0xAB);
-    assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
-    values[2..4].set_memory(0xFF);
-    assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
-}
-
-#[test]
 #[should_panic]
 fn test_overflow_does_not_cause_segfault() {
     let mut v = vec![];
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 959b6a97c5c..f063c6b0676 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -4750,87 +4750,3 @@ impl<T> ExactSizeIterator for Once<T> {
 pub fn once<T>(value: T) -> Once<T> {
     Once { inner: Some(value).into_iter() }
 }
-
-/// Functions for lexicographical ordering of sequences.
-///
-/// Lexicographical ordering through `<`, `<=`, `>=`, `>` requires
-/// that the elements implement both `PartialEq` and `PartialOrd`.
-///
-/// If two sequences are equal up until the point where one ends,
-/// the shorter sequence compares less.
-#[rustc_deprecated(since = "1.4.0", reason = "use the equivalent methods on `Iterator` instead")]
-#[unstable(feature = "iter_order_deprecated", reason = "needs review and revision",
-           issue = "27737")]
-pub mod order {
-    use cmp;
-    use cmp::{Eq, Ord, PartialOrd, PartialEq};
-    use option::Option;
-    use super::Iterator;
-
-    /// Compare `a` and `b` for equality using `Eq`
-    pub fn equals<A, L, R>(a: L, b: R) -> bool where
-        A: Eq,
-        L: Iterator<Item=A>,
-        R: Iterator<Item=A>,
-    {
-        a.eq(b)
-    }
-
-    /// Order `a` and `b` lexicographically using `Ord`
-    pub fn cmp<A, L, R>(a: L, b: R) -> cmp::Ordering where
-        A: Ord,
-        L: Iterator<Item=A>,
-        R: Iterator<Item=A>,
-    {
-        a.cmp(b)
-    }
-
-    /// Order `a` and `b` lexicographically using `PartialOrd`
-    pub fn partial_cmp<L: Iterator, R: Iterator>(a: L, b: R) -> Option<cmp::Ordering> where
-        L::Item: PartialOrd<R::Item>
-    {
-        a.partial_cmp(b)
-    }
-
-    /// Compare `a` and `b` for equality (Using partial equality, `PartialEq`)
-    pub fn eq<L: Iterator, R: Iterator>(a: L, b: R) -> bool where
-        L::Item: PartialEq<R::Item>,
-    {
-        a.eq(b)
-    }
-
-    /// Compares `a` and `b` for nonequality (Using partial equality, `PartialEq`)
-    pub fn ne<L: Iterator, R: Iterator>(a: L, b: R) -> bool where
-        L::Item: PartialEq<R::Item>,
-    {
-        a.ne(b)
-    }
-
-    /// Returns `a` < `b` lexicographically (Using partial order, `PartialOrd`)
-    pub fn lt<L: Iterator, R: Iterator>(a: L, b: R) -> bool where
-        L::Item: PartialOrd<R::Item>,
-    {
-        a.lt(b)
-    }
-
-    /// Returns `a` <= `b` lexicographically (Using partial order, `PartialOrd`)
-    pub fn le<L: Iterator, R: Iterator>(a: L, b: R) -> bool where
-        L::Item: PartialOrd<R::Item>,
-    {
-        a.le(b)
-    }
-
-    /// Returns `a` > `b` lexicographically (Using partial order, `PartialOrd`)
-    pub fn gt<L: Iterator, R: Iterator>(a: L, b: R) -> bool where
-        L::Item: PartialOrd<R::Item>,
-    {
-        a.gt(b)
-    }
-
-    /// Returns `a` >= `b` lexicographically (Using partial order, `PartialOrd`)
-    pub fn ge<L: Iterator, R: Iterator>(a: L, b: R) -> bool where
-        L::Item: PartialOrd<R::Item>,
-    {
-        a.ge(b)
-    }
-}
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 86f2e3bcec3..454e2b02b1c 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -153,12 +153,6 @@ pub mod option;
 pub mod raw;
 pub mod result;
 
-#[cfg(stage0)]
-#[path = "simd_old.rs"]
-pub mod simd;
-#[cfg(not(stage0))]
-pub mod simd;
-
 pub mod slice;
 pub mod str;
 pub mod hash;
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 359d15640f9..8af1022acdf 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -15,11 +15,9 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use prelude::v1::*;
-
 use intrinsics;
 use mem;
-use num::{Float, ParseFloatError};
+use num::Float;
 use num::FpCategory as Fp;
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -163,8 +161,6 @@ impl Float for f32 {
     #[inline]
     fn one() -> f32 { 1.0 }
 
-    from_str_radix_float_impl! { f32 }
-
     /// Returns `true` if the number is NaN.
     #[inline]
     fn is_nan(self) -> bool { self != self }
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 1a6acc5f4ab..9486e4337bf 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -15,12 +15,10 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use prelude::v1::*;
-
 use intrinsics;
 use mem;
 use num::FpCategory as Fp;
-use num::{Float, ParseFloatError};
+use num::Float;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow(missing_docs)]
@@ -163,8 +161,6 @@ impl Float for f64 {
     #[inline]
     fn one() -> f64 { 1.0 }
 
-    from_str_radix_float_impl! { f64 }
-
     /// Returns `true` if the number is NaN.
     #[inline]
     fn is_nan(self) -> bool { self != self }
diff --git a/src/libcore/num/float_macros.rs b/src/libcore/num/float_macros.rs
index 88c3b756793..b3adef53dab 100644
--- a/src/libcore/num/float_macros.rs
+++ b/src/libcore/num/float_macros.rs
@@ -18,144 +18,3 @@ macro_rules! assert_approx_eq {
                 "{} is not approximately equal to {}", *a, *b);
     })
 }
-
-macro_rules! from_str_radix_float_impl {
-    ($T:ty) => {
-        fn from_str_radix(src: &str, radix: u32)
-                          -> Result<$T, ParseFloatError> {
-            use num::dec2flt::{pfe_empty, pfe_invalid};
-
-            // Special values
-            match src {
-                "inf"   => return Ok(Float::infinity()),
-                "-inf"  => return Ok(Float::neg_infinity()),
-                "NaN"   => return Ok(Float::nan()),
-                _       => {},
-            }
-
-            let (is_positive, src) =  match src.slice_shift_char() {
-                None             => return Err(pfe_empty()),
-                Some(('-', ""))  => return Err(pfe_empty()),
-                Some(('-', src)) => (false, src),
-                Some((_, _))     => (true,  src),
-            };
-
-            // The significand to accumulate
-            let mut sig = if is_positive { 0.0 } else { -0.0 };
-            // Necessary to detect overflow
-            let mut prev_sig = sig;
-            let mut cs = src.chars().enumerate();
-            // Exponent prefix and exponent index offset
-            let mut exp_info = None::<(char, usize)>;
-
-            // Parse the integer part of the significand
-            for (i, c) in cs.by_ref() {
-                match c.to_digit(radix) {
-                    Some(digit) => {
-                        // shift significand one digit left
-                        sig = sig * (radix as $T);
-
-                        // add/subtract current digit depending on sign
-                        if is_positive {
-                            sig = sig + ((digit as isize) as $T);
-                        } else {
-                            sig = sig - ((digit as isize) as $T);
-                        }
-
-                        // Detect overflow by comparing to last value, except
-                        // if we've not seen any non-zero digits.
-                        if prev_sig != 0.0 {
-                            if is_positive && sig <= prev_sig
-                                { return Ok(Float::infinity()); }
-                            if !is_positive && sig >= prev_sig
-                                { return Ok(Float::neg_infinity()); }
-
-                            // Detect overflow by reversing the shift-and-add process
-                            if is_positive && (prev_sig != (sig - digit as $T) / radix as $T)
-                                { return Ok(Float::infinity()); }
-                            if !is_positive && (prev_sig != (sig + digit as $T) / radix as $T)
-                                { return Ok(Float::neg_infinity()); }
-                        }
-                        prev_sig = sig;
-                    },
-                    None => match c {
-                        'e' | 'E' | 'p' | 'P' => {
-                            exp_info = Some((c, i + 1));
-                            break;  // start of exponent
-                        },
-                        '.' => {
-                            break;  // start of fractional part
-                        },
-                        _ => {
-                            return Err(pfe_invalid())
-                        },
-                    },
-                }
-            }
-
-            // If we are not yet at the exponent parse the fractional
-            // part of the significand
-            if exp_info.is_none() {
-                let mut power = 1.0;
-                for (i, c) in cs.by_ref() {
-                    match c.to_digit(radix) {
-                        Some(digit) => {
-                            // Decrease power one order of magnitude
-                            power = power / (radix as $T);
-                            // add/subtract current digit depending on sign
-                            sig = if is_positive {
-                                sig + (digit as $T) * power
-                            } else {
-                                sig - (digit as $T) * power
-                            };
-                            // Detect overflow by comparing to last value
-                            if is_positive && sig < prev_sig
-                                { return Ok(Float::infinity()); }
-                            if !is_positive && sig > prev_sig
-                                { return Ok(Float::neg_infinity()); }
-                            prev_sig = sig;
-                        },
-                        None => match c {
-                            'e' | 'E' | 'p' | 'P' => {
-                                exp_info = Some((c, i + 1));
-                                break; // start of exponent
-                            },
-                            _ => {
-                                return Err(pfe_invalid())
-                            },
-                        },
-                    }
-                }
-            }
-
-            // Parse and calculate the exponent
-            let exp = match exp_info {
-                Some((c, offset)) => {
-                    let base = match c {
-                        'E' | 'e' if radix == 10 => 10.0,
-                        'P' | 'p' if radix == 16 => 2.0,
-                        _ => return Err(pfe_invalid()),
-                    };
-
-                    // Parse the exponent as decimal integer
-                    let src = &src[offset..];
-                    let (is_positive, exp) = match src.slice_shift_char() {
-                        Some(('-', src)) => (false, src.parse::<usize>()),
-                        Some(('+', src)) => (true,  src.parse::<usize>()),
-                        Some((_, _))     => (true,  src.parse::<usize>()),
-                        None             => return Err(pfe_invalid()),
-                    };
-
-                    match (is_positive, exp) {
-                        (true,  Ok(exp)) => base.powi(exp as i32),
-                        (false, Ok(exp)) => 1.0 / base.powi(exp as i32),
-                        (_, Err(_))      => return Err(pfe_invalid()),
-                    }
-                },
-                None => 1.0, // no exponent
-            };
-
-            Ok(sig * exp)
-        }
-    }
-}
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index e1e5c01adb7..4f3c1256709 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -1771,12 +1771,6 @@ pub trait Float: Sized {
     #[unstable(feature = "float_extras", reason = "needs removal",
                issue = "27752")]
     fn one() -> Self;
-    /// Parses the string `s` with the radix `r` as a float.
-    #[unstable(feature = "float_from_str_radix", reason = "recently moved API",
-               issue = "27736")]
-    #[rustc_deprecated(since = "1.4.0",
-                 reason = "unclear how useful or correct this is")]
-    fn from_str_radix(s: &str, r: u32) -> Result<Self, ParseFloatError>;
 
     /// Returns true if this value is NaN and false otherwise.
     #[stable(feature = "core", since = "1.6.0")]
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 209cebeaf1b..aca36d85626 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -154,7 +154,6 @@ use mem;
 use ops::FnOnce;
 use result::Result::{Ok, Err};
 use result::Result;
-use slice;
 
 // Note that this is not a lang item per se, but it has a hidden dependency on
 // `Iterator`, which is one. The compiler assumes that the `next` method of
@@ -269,47 +268,11 @@ impl<T> Option<T> {
         }
     }
 
-    /// Converts from `Option<T>` to `&mut [T]` (without copying)
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(as_slice)]
-    /// # #![allow(deprecated)]
-    ///
-    /// let mut x = Some("Diamonds");
-    /// {
-    ///     let v = x.as_mut_slice();
-    ///     assert!(v == ["Diamonds"]);
-    ///     v[0] = "Dirt";
-    ///     assert!(v == ["Dirt"]);
-    /// }
-    /// assert_eq!(x, Some("Dirt"));
-    /// ```
-    #[inline]
-    #[unstable(feature = "as_slice",
-               reason = "waiting for mut conventions",
-               issue = "27776")]
-    #[rustc_deprecated(since = "1.4.0", reason = "niche API, unclear of usefulness")]
-    #[allow(deprecated)]
-    pub fn as_mut_slice(&mut self) -> &mut [T] {
-        match *self {
-            Some(ref mut x) => {
-                let result: &mut [T] = slice::mut_ref_slice(x);
-                result
-            }
-            None => {
-                let result: &mut [T] = &mut [];
-                result
-            }
-        }
-    }
-
     /////////////////////////////////////////////////////////////////////////
     // Getting to contained values
     /////////////////////////////////////////////////////////////////////////
 
-    /// Unwraps an option, yielding the content of a `Some`
+    /// Unwraps an option, yielding the content of a `Some`.
     ///
     /// # Panics
     ///
@@ -690,22 +653,6 @@ impl<T> Option<T> {
     pub fn take(&mut self) -> Option<T> {
         mem::replace(self, None)
     }
-
-    /// Converts from `Option<T>` to `&[T]` (without copying)
-    #[inline]
-    #[unstable(feature = "as_slice", reason = "unsure of the utility here",
-               issue = "27776")]
-    #[rustc_deprecated(since = "1.4.0", reason = "niche API, unclear of usefulness")]
-    #[allow(deprecated)]
-    pub fn as_slice(&self) -> &[T] {
-        match *self {
-            Some(ref x) => slice::ref_slice(x),
-            None => {
-                let result: &[_] = &[];
-                result
-            }
-        }
-    }
 }
 
 impl<'a, T: Clone> Option<&'a T> {
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 37c40f96b0f..015887e3772 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -240,7 +240,6 @@ use fmt;
 use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSizeIterator, IntoIterator};
 use ops::FnOnce;
 use option::Option::{self, None, Some};
-use slice;
 
 /// `Result` is a type that represents either success (`Ok`) or failure (`Err`).
 ///
@@ -406,58 +405,6 @@ impl<T, E> Result<T, E> {
         }
     }
 
-    /// Converts from `Result<T, E>` to `&[T]` (without copying)
-    #[inline]
-    #[unstable(feature = "as_slice", reason = "unsure of the utility here",
-               issue = "27776")]
-    #[rustc_deprecated(since = "1.4.0", reason = "niche API, unclear of usefulness")]
-    #[allow(deprecated)]
-    pub fn as_slice(&self) -> &[T] {
-        match *self {
-            Ok(ref x) => slice::ref_slice(x),
-            Err(_) => {
-                // work around lack of implicit coercion from fixed-size array to slice
-                let emp: &[_] = &[];
-                emp
-            }
-        }
-    }
-
-    /// Converts from `Result<T, E>` to `&mut [T]` (without copying)
-    ///
-    /// ```
-    /// #![feature(as_slice)]
-    /// # #![allow(deprecated)]
-    ///
-    /// let mut x: Result<&str, u32> = Ok("Gold");
-    /// {
-    ///     let v = x.as_mut_slice();
-    ///     assert!(v == ["Gold"]);
-    ///     v[0] = "Silver";
-    ///     assert!(v == ["Silver"]);
-    /// }
-    /// assert_eq!(x, Ok("Silver"));
-    ///
-    /// let mut x: Result<&str, u32> = Err(45);
-    /// assert!(x.as_mut_slice().is_empty());
-    /// ```
-    #[inline]
-    #[unstable(feature = "as_slice",
-               reason = "waiting for mut conventions",
-               issue = "27776")]
-    #[rustc_deprecated(since = "1.4.0", reason = "niche API, unclear of usefulness")]
-    #[allow(deprecated)]
-    pub fn as_mut_slice(&mut self) -> &mut [T] {
-        match *self {
-            Ok(ref mut x) => slice::mut_ref_slice(x),
-            Err(_) => {
-                // work around lack of implicit coercion from fixed-size array to slice
-                let emp: &mut [_] = &mut [];
-                emp
-            }
-        }
-    }
-
     /////////////////////////////////////////////////////////////////////////
     // Transforming contained values
     /////////////////////////////////////////////////////////////////////////
@@ -744,6 +691,8 @@ impl<T, E: fmt::Debug> Result<T, E> {
 
     /// Unwraps a result, yielding the content of an `Ok`.
     ///
+    /// # Panics
+    ///
     /// Panics if the value is an `Err`, with a panic message including the
     /// passed message, and the content of the `Err`.
     ///
diff --git a/src/libcore/simd.rs b/src/libcore/simd.rs
deleted file mode 100644
index 697f96ddefb..00000000000
--- a/src/libcore/simd.rs
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! SIMD vectors.
-//!
-//! These types can be used for accessing basic SIMD operations. Currently
-//! comparison operators are not implemented. To use SSE3+, you must enable
-//! the features, like `-C target-feature=sse3,sse4.1,sse4.2`, or a more
-//! specific `target-cpu`. No other SIMD intrinsics or high-level wrappers are
-//! provided beyond this module.
-//!
-//! # Stability Note
-//!
-//! These are all experimental. The interface may change entirely, without
-//! warning.
-
-#![unstable(feature = "core_simd",
-            reason = "needs an RFC to flesh out the design",
-            issue = "27731")]
-#![rustc_deprecated(since = "1.3.0",
-              reason = "use the external `simd` crate instead")]
-
-#![allow(non_camel_case_types)]
-#![allow(missing_docs)]
-#![allow(deprecated)]
-
-use ops::{Add, Sub, Mul, Div, Shl, Shr, BitAnd, BitOr, BitXor};
-
-// FIXME(stage0): the contents of macro can be inlined.
-// ABIs are verified as valid as soon as they are parsed, i.e. before
-// `cfg` stripping. The `platform-intrinsic` ABI is new, so stage0
-// doesn't know about it, but it still errors out when it hits it
-// (despite this being in a `cfg(not(stage0))` module).
-macro_rules! argh {
-    () => {
-        extern "platform-intrinsic" {
-            fn simd_add<T>(x: T, y: T) -> T;
-            fn simd_sub<T>(x: T, y: T) -> T;
-            fn simd_mul<T>(x: T, y: T) -> T;
-            fn simd_div<T>(x: T, y: T) -> T;
-            fn simd_shl<T>(x: T, y: T) -> T;
-            fn simd_shr<T>(x: T, y: T) -> T;
-            fn simd_and<T>(x: T, y: T) -> T;
-            fn simd_or<T>(x: T, y: T) -> T;
-            fn simd_xor<T>(x: T, y: T) -> T;
-        }
-    }
-}
-argh!();
-
-#[repr(simd)]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
-                 pub i8, pub i8, pub i8, pub i8,
-                 pub i8, pub i8, pub i8, pub i8,
-                 pub i8, pub i8, pub i8, pub i8);
-
-#[repr(simd)]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
-                 pub i16, pub i16, pub i16, pub i16);
-
-#[repr(simd)]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
-
-#[repr(simd)]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct i64x2(pub i64, pub i64);
-
-#[repr(simd)]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
-                 pub u8, pub u8, pub u8, pub u8,
-                 pub u8, pub u8, pub u8, pub u8,
-                 pub u8, pub u8, pub u8, pub u8);
-
-#[repr(simd)]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
-                 pub u16, pub u16, pub u16, pub u16);
-
-#[repr(simd)]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
-
-#[repr(simd)]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct u64x2(pub u64, pub u64);
-
-#[repr(simd)]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
-
-#[repr(simd)]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct f64x2(pub f64, pub f64);
-
-macro_rules! impl_traits {
-    ($($trayt: ident, $method: ident, $func: ident: $($ty: ty),*;)*) => {
-        $($(
-            impl $trayt<$ty> for $ty {
-                type Output = Self;
-                fn $method(self, other: Self) -> Self {
-                    unsafe {
-                        $func(self, other)
-                    }
-                }
-            }
-            )*)*
-    }
-}
-
-impl_traits! {
-    Add, add, simd_add: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2;
-    Sub, sub, simd_sub: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2;
-    Mul, mul, simd_mul: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2;
-
-    Div, div, simd_div: f32x4, f64x2;
-
-    Shl, shl, simd_shl: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2;
-    Shr, shr, simd_shr: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2;
-    BitAnd, bitand, simd_and: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2;
-    BitOr, bitor, simd_or: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2;
-    BitXor, bitxor, simd_xor: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2;
-}
diff --git a/src/libcore/simd_old.rs b/src/libcore/simd_old.rs
deleted file mode 100644
index 7ecd08bea35..00000000000
--- a/src/libcore/simd_old.rs
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! SIMD vectors.
-//!
-//! These types can be used for accessing basic SIMD operations. Each of them
-//! implements the standard arithmetic operator traits (Add, Sub, Mul, Div,
-//! Rem, Shl, Shr) through compiler magic, rather than explicitly. Currently
-//! comparison operators are not implemented. To use SSE3+, you must enable
-//! the features, like `-C target-feature=sse3,sse4.1,sse4.2`, or a more
-//! specific `target-cpu`. No other SIMD intrinsics or high-level wrappers are
-//! provided beyond this module.
-//!
-//! ```rust
-//! # #![feature(core_simd)]
-//! fn main() {
-//!     use std::simd::f32x4;
-//!     let a = f32x4(40.0, 41.0, 42.0, 43.0);
-//!     let b = f32x4(1.0, 1.1, 3.4, 9.8);
-//!     println!("{:?}", a + b);
-//! }
-//! ```
-//!
-//! # Stability Note
-//!
-//! These are all experimental. The interface may change entirely, without
-//! warning.
-
-#![unstable(feature = "core_simd",
-            reason = "needs an RFC to flesh out the design")]
-
-#![allow(non_camel_case_types)]
-#![allow(missing_docs)]
-
-#[simd]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
-                 pub i8, pub i8, pub i8, pub i8,
-                 pub i8, pub i8, pub i8, pub i8,
-                 pub i8, pub i8, pub i8, pub i8);
-
-#[simd]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
-                 pub i16, pub i16, pub i16, pub i16);
-
-#[simd]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
-
-#[simd]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct i64x2(pub i64, pub i64);
-
-#[simd]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
-                 pub u8, pub u8, pub u8, pub u8,
-                 pub u8, pub u8, pub u8, pub u8,
-                 pub u8, pub u8, pub u8, pub u8);
-
-#[simd]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
-                 pub u16, pub u16, pub u16, pub u16);
-
-#[simd]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
-
-#[simd]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct u64x2(pub u64, pub u64);
-
-#[simd]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
-
-#[simd]
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct f64x2(pub f64, pub f64);
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 70175086147..b17fac4d771 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -1380,24 +1380,6 @@ impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {}
 // Free functions
 //
 
-/// Converts a reference to A into a slice of length 1 (without copying).
-#[unstable(feature = "ref_slice", issue = "27774")]
-#[rustc_deprecated(since = "1.5.0", reason = "unclear whether belongs in libstd")]
-pub fn ref_slice<A>(s: &A) -> &[A] {
-    unsafe {
-        from_raw_parts(s, 1)
-    }
-}
-
-/// Converts a reference to A into a slice of length 1 (without copying).
-#[unstable(feature = "ref_slice", issue = "27774")]
-#[rustc_deprecated(since = "1.5.0", reason = "unclear whether belongs in libstd")]
-pub fn mut_ref_slice<A>(s: &mut A) -> &mut [A] {
-    unsafe {
-        from_raw_parts_mut(s, 1)
-    }
-}
-
 /// Forms a slice from a pointer and a length.
 ///
 /// The `len` argument is the number of **elements**, not the number of bytes.
diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs
index 9def44191db..ba308314e9e 100644
--- a/src/libcoretest/iter.rs
+++ b/src/libcoretest/iter.rs
@@ -830,18 +830,6 @@ fn test_range() {
 }
 
 #[test]
-fn test_range_inclusive() {
-    assert!(range_inclusive(0, 5).collect::<Vec<isize>>() ==
-            vec![0, 1, 2, 3, 4, 5]);
-    assert!(range_inclusive(0, 5).rev().collect::<Vec<isize>>() ==
-            vec![5, 4, 3, 2, 1, 0]);
-    assert_eq!(range_inclusive(200, -5).count(), 0);
-    assert_eq!(range_inclusive(200, -5).rev().count(), 0);
-    assert_eq!(range_inclusive(200, 200).collect::<Vec<isize>>(), [200]);
-    assert_eq!(range_inclusive(200, 200).rev().collect::<Vec<isize>>(), [200]);
-}
-
-#[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]);
diff --git a/src/libcoretest/lib.rs b/src/libcoretest/lib.rs
index 20da4a86bf5..88f1835d2cc 100644
--- a/src/libcoretest/lib.rs
+++ b/src/libcoretest/lib.rs
@@ -43,6 +43,7 @@
 #![feature(unboxed_closures)]
 #![feature(unicode)]
 #![feature(unique)]
+#![feature(clone_from_slice)]
 
 extern crate core;
 extern crate test;
diff --git a/src/libcoretest/num/flt2dec/mod.rs b/src/libcoretest/num/flt2dec/mod.rs
index 309bf6d8192..65b233ee92f 100644
--- a/src/libcoretest/num/flt2dec/mod.rs
+++ b/src/libcoretest/num/flt2dec/mod.rs
@@ -10,7 +10,6 @@
 
 use std::prelude::v1::*;
 use std::{str, mem, i16, f32, f64, fmt};
-use std::slice::bytes;
 use std::__rand as rand;
 use rand::{Rand, XorShiftRng};
 use rand::distributions::{IndependentSample, Range};
@@ -101,7 +100,7 @@ fn check_exact<F, T>(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16
 
     // check significant digits
     for i in 1..cut.unwrap_or(expected.len() - 1) {
-        bytes::copy_memory(&expected[..i], &mut expected_);
+        expected_.clone_from_slice(&expected[..i]);
         let mut expectedk_ = expectedk;
         if expected[i] >= b'5' {
             // check if this is a rounding-to-even case.
@@ -148,7 +147,7 @@ fn check_exact<F, T>(mut f: F, v: T, vstr: &str, expected: &[u8], expectedk: i16
     // check infinite zero digits
     if let Some(cut) = cut {
         for i in cut..expected.len()-1 {
-            bytes::copy_memory(&expected[..cut], &mut expected_);
+            expected_.clone_from_slice(&expected[..cut]);
             for c in &mut expected_[cut..i] { *c = b'0'; }
 
             try_exact!(f(&decoded) => &mut buf, &expected_[..i], expectedk;
diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs
index 738761f3911..09f2e326503 100644
--- a/src/libcoretest/num/mod.rs
+++ b/src/libcoretest/num/mod.rs
@@ -55,35 +55,6 @@ mod tests {
     use core::num::Float;
 
     #[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);
-        let s = "10000000000000000000000000000000000000000";
-        let f : Option<f32> = f32::from_str_radix(s, 10).ok();
-        assert_eq!(f, Some(Float::infinity()));
-        let fe : Option<f32> = f32::from_str_radix("1e40", 10).ok();
-        assert_eq!(fe, Some(Float::infinity()));
-    }
-
-    #[test]
-    fn test_from_str_radix_float() {
-        let x1 : Option<f64> = f64::from_str_radix("-123.456", 10).ok();
-        assert_eq!(x1, Some(-123.456));
-        let x2 : Option<f32> = f32::from_str_radix("123.456", 10).ok();
-        assert_eq!(x2, Some(123.456));
-        let x3 : Option<f32> = f32::from_str_radix("-0.0", 10).ok();
-        assert_eq!(x3, Some(-0.0));
-        let x4 : Option<f32> = f32::from_str_radix("0.0", 10).ok();
-        assert_eq!(x4, Some(0.0));
-        let x4 : Option<f32> = f32::from_str_radix("1.0", 10).ok();
-        assert_eq!(x4, Some(1.0));
-        let x5 : Option<f32> = f32::from_str_radix("-1.0", 10).ok();
-        assert_eq!(x5, Some(-1.0));
-    }
-
-    #[test]
     fn test_int_from_str_overflow() {
         let mut i8_val: i8 = 127;
         assert_eq!("127".parse::<i8>().ok(), Some(i8_val));
diff --git a/src/librand/chacha.rs b/src/librand/chacha.rs
index e2c157f98a6..cd099c69005 100644
--- a/src/librand/chacha.rs
+++ b/src/librand/chacha.rs
@@ -208,7 +208,6 @@ impl Rand for ChaChaRng {
 mod tests {
     use std::prelude::v1::*;
 
-    use core::iter::order;
     use {Rng, SeedableRng};
     use super::ChaChaRng;
 
@@ -217,8 +216,8 @@ mod tests {
         let s = ::test::rng().gen_iter::<u32>().take(8).collect::<Vec<u32>>();
         let mut ra: ChaChaRng = SeedableRng::from_seed(&*s);
         let mut rb: ChaChaRng = SeedableRng::from_seed(&*s);
-        assert!(order::equals(ra.gen_ascii_chars().take(100),
-                              rb.gen_ascii_chars().take(100)));
+        assert!(ra.gen_ascii_chars().take(100)
+                  .eq(rb.gen_ascii_chars().take(100)));
     }
 
     #[test]
@@ -226,8 +225,8 @@ mod tests {
         let seed: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
         let mut ra: ChaChaRng = SeedableRng::from_seed(seed);
         let mut rb: ChaChaRng = SeedableRng::from_seed(seed);
-        assert!(order::equals(ra.gen_ascii_chars().take(100),
-                              rb.gen_ascii_chars().take(100)));
+        assert!(ra.gen_ascii_chars().take(100)
+                  .eq(rb.gen_ascii_chars().take(100)));
     }
 
     #[test]
diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs
index 1f56a82eba8..dd99bc93ef3 100644
--- a/src/librand/isaac.rs
+++ b/src/librand/isaac.rs
@@ -544,7 +544,6 @@ impl Rand for Isaac64Rng {
 mod tests {
     use std::prelude::v1::*;
 
-    use core::iter::order;
     use {Rng, SeedableRng};
     use super::{IsaacRng, Isaac64Rng};
 
@@ -553,16 +552,16 @@ mod tests {
         let s = ::test::rng().gen_iter::<u32>().take(256).collect::<Vec<u32>>();
         let mut ra: IsaacRng = SeedableRng::from_seed(&s[..]);
         let mut rb: IsaacRng = SeedableRng::from_seed(&s[..]);
-        assert!(order::equals(ra.gen_ascii_chars().take(100),
-                              rb.gen_ascii_chars().take(100)));
+        assert!(ra.gen_ascii_chars().take(100)
+                  .eq(rb.gen_ascii_chars().take(100)));
     }
     #[test]
     fn test_rng_64_rand_seeded() {
         let s = ::test::rng().gen_iter::<u64>().take(256).collect::<Vec<u64>>();
         let mut ra: Isaac64Rng = SeedableRng::from_seed(&s[..]);
         let mut rb: Isaac64Rng = SeedableRng::from_seed(&s[..]);
-        assert!(order::equals(ra.gen_ascii_chars().take(100),
-                              rb.gen_ascii_chars().take(100)));
+        assert!(ra.gen_ascii_chars().take(100)
+                  .eq(rb.gen_ascii_chars().take(100)));
     }
 
     #[test]
@@ -570,16 +569,16 @@ mod tests {
         let seed: &[_] = &[1, 23, 456, 7890, 12345];
         let mut ra: IsaacRng = SeedableRng::from_seed(seed);
         let mut rb: IsaacRng = SeedableRng::from_seed(seed);
-        assert!(order::equals(ra.gen_ascii_chars().take(100),
-                              rb.gen_ascii_chars().take(100)));
+        assert!(ra.gen_ascii_chars().take(100)
+                  .eq(rb.gen_ascii_chars().take(100)));
     }
     #[test]
     fn test_rng_64_seeded() {
         let seed: &[_] = &[1, 23, 456, 7890, 12345];
         let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
         let mut rb: Isaac64Rng = SeedableRng::from_seed(seed);
-        assert!(order::equals(ra.gen_ascii_chars().take(100),
-                              rb.gen_ascii_chars().take(100)));
+        assert!(ra.gen_ascii_chars().take(100)
+                  .eq(rb.gen_ascii_chars().take(100)));
     }
 
     #[test]
diff --git a/src/librand/reseeding.rs b/src/librand/reseeding.rs
index 8ef94eb16f2..db5e0213726 100644
--- a/src/librand/reseeding.rs
+++ b/src/librand/reseeding.rs
@@ -122,7 +122,6 @@ impl Default for ReseedWithDefault {
 mod tests {
     use std::prelude::v1::*;
 
-    use core::iter::order;
     use super::{ReseedingRng, ReseedWithDefault};
     use {SeedableRng, Rng};
 
@@ -167,8 +166,8 @@ mod tests {
     fn test_rng_seeded() {
         let mut ra: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2));
         let mut rb: MyRng = SeedableRng::from_seed((ReseedWithDefault, 2));
-        assert!(order::equals(ra.gen_ascii_chars().take(100),
-                              rb.gen_ascii_chars().take(100)));
+        assert!(ra.gen_ascii_chars().take(100)
+                  .eq(rb.gen_ascii_chars().take(100)));
     }
 
     #[test]
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index d6932c7ca3c..9f75f9ebb9a 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -242,7 +242,7 @@ pub fn lookup_const_fn_by_id<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId)
     }
 }
 
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub enum ConstVal {
     Float(f64),
     Int(i64),
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 4efa7bfac18..22a4ddd2f68 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -28,6 +28,7 @@ use middle::def;
 use middle::lang_items;
 use middle::ty::{self, Ty};
 use middle::def_id::{DefId, DefIndex};
+use mir::repr::Mir;
 use session::Session;
 use session::search_paths::PathKind;
 use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
@@ -100,6 +101,7 @@ pub enum InlinedItem {
 }
 
 /// A borrowed version of `hir::InlinedItem`.
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 pub enum InlinedItemRef<'a> {
     Item(&'a hir::Item),
     TraitItem(DefId, &'a hir::TraitItem),
@@ -216,6 +218,8 @@ pub trait CrateStore<'tcx> : Any {
     // misc. metadata
     fn maybe_get_item_ast(&'tcx self, tcx: &ty::ctxt<'tcx>, def: DefId)
                           -> FoundAst<'tcx>;
+    fn maybe_get_item_mir(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                          -> Option<Mir<'tcx>>;
     // This is basically a 1-based range of ints, which is a little
     // silly - I may fix that.
     fn crates(&self) -> Vec<ast::CrateNum>;
@@ -235,6 +239,7 @@ pub trait CrateStore<'tcx> : Any {
                        item_symbols: &RefCell<NodeMap<String>>,
                        link_meta: &LinkMeta,
                        reachable: &NodeSet,
+                       mir_map: &NodeMap<Mir<'tcx>>,
                        krate: &hir::Crate) -> Vec<u8>;
     fn metadata_encoding_version(&self) -> &[u8];
 }
@@ -383,6 +388,9 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
     // misc. metadata
     fn maybe_get_item_ast(&'tcx self, tcx: &ty::ctxt<'tcx>, def: DefId)
                           -> FoundAst<'tcx> { unimplemented!() }
+    fn maybe_get_item_mir(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                          -> Option<Mir<'tcx>> { unimplemented!() }
+
     // This is basically a 1-based range of ints, which is a little
     // silly - I may fix that.
     fn crates(&self) -> Vec<ast::CrateNum> { vec![] }
@@ -404,6 +412,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
                        item_symbols: &RefCell<NodeMap<String>>,
                        link_meta: &LinkMeta,
                        reachable: &NodeSet,
+                       mir_map: &NodeMap<Mir<'tcx>>,
                        krate: &hir::Crate) -> Vec<u8> { vec![] }
     fn metadata_encoding_version(&self) -> &[u8] { unimplemented!() }
 }
diff --git a/src/librustc/middle/ty/sty.rs b/src/librustc/middle/ty/sty.rs
index 425a324c7e0..66b2a9d3ad0 100644
--- a/src/librustc/middle/ty/sty.rs
+++ b/src/librustc/middle/ty/sty.rs
@@ -10,6 +10,7 @@
 
 //! This module contains TypeVariants and its major components
 
+use middle::cstore;
 use middle::def_id::DefId;
 use middle::region;
 use middle::subst::{self, Substs};
@@ -26,6 +27,8 @@ use syntax::abi;
 use syntax::ast::{self, Name};
 use syntax::parse::token::special_idents;
 
+use serialize::{Decodable, Decoder};
+
 use rustc_front::hir;
 
 use self::FnOutput::*;
@@ -233,7 +236,7 @@ pub enum TypeVariants<'tcx> {
 /// closure C wind up influencing the decisions we ought to make for
 /// closure C (which would then require fixed point iteration to
 /// handle). Plus it fixes an ICE. :P
-#[derive(Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub struct ClosureSubsts<'tcx> {
     /// Lifetime and type parameters from the enclosing function.
     /// These are separated out because trans wants to pass them around
@@ -246,6 +249,23 @@ pub struct ClosureSubsts<'tcx> {
     pub upvar_tys: Vec<Ty<'tcx>>
 }
 
+impl<'tcx> Decodable for &'tcx ClosureSubsts<'tcx> {
+    fn decode<S: Decoder>(s: &mut S) -> Result<&'tcx ClosureSubsts<'tcx>, S::Error> {
+        let closure_substs = try! { Decodable::decode(s) };
+        let dummy_def_id: DefId = unsafe { mem::zeroed() };
+
+        cstore::tls::with_decoding_context(s, |dcx, _| {
+            // Intern the value
+            let ty = dcx.tcx().mk_closure_from_closure_substs(dummy_def_id,
+                                                              Box::new(closure_substs));
+            match ty.sty {
+                TyClosure(_, ref closure_substs) => Ok(&**closure_substs),
+                _ => unreachable!()
+            }
+        })
+    }
+}
+
 #[derive(Clone, PartialEq, Eq, Hash)]
 pub struct TraitTy<'tcx> {
     pub principal: ty::PolyTraitRef<'tcx>,
@@ -434,7 +454,7 @@ pub struct ClosureTy<'tcx> {
     pub sig: PolyFnSig<'tcx>,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub enum FnOutput<'tcx> {
     FnConverging(Ty<'tcx>),
     FnDiverging
@@ -632,7 +652,7 @@ pub struct DebruijnIndex {
 ///
 /// [1] http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
 /// [2] http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
-#[derive(Clone, PartialEq, Eq, Hash, Copy)]
+#[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable)]
 pub enum Region {
     // Region bound in a type or fn declaration which will be
     // substituted 'early' -- that is, at the same time when type
@@ -701,7 +721,7 @@ pub struct RegionVid {
     pub index: u32
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub struct SkolemizedRegionVid {
     pub index: u32
 }
diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs
index d5d8da248e0..049063f73a5 100644
--- a/src/librustc/mir/repr.rs
+++ b/src/librustc/mir/repr.rs
@@ -13,6 +13,7 @@ use middle::def_id::DefId;
 use middle::subst::Substs;
 use middle::ty::{AdtDef, ClosureSubsts, FnOutput, Region, Ty};
 use rustc_back::slice;
+use rustc_data_structures::tuple_slice::TupleSlice;
 use rustc_front::hir::InlineAsm;
 use syntax::ast::Name;
 use syntax::codemap::Span;
@@ -20,6 +21,7 @@ use std::fmt::{Debug, Formatter, Error};
 use std::u32;
 
 /// Lowered representation of a single function.
+#[derive(RustcEncodable, RustcDecodable)]
 pub struct Mir<'tcx> {
     /// List of basic blocks. References to basic block use a newtyped index type `BasicBlock`
     /// that indexes into this vector.
@@ -70,13 +72,13 @@ impl<'tcx> Mir<'tcx> {
 ///////////////////////////////////////////////////////////////////////////
 // Mutability and borrow kinds
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub enum Mutability {
     Mut,
     Not,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub enum BorrowKind {
     /// Data must be immutable and is aliasable.
     Shared,
@@ -127,6 +129,7 @@ pub enum BorrowKind {
 
 // A "variable" is a binding declared by the user as part of the fn
 // decl, a let, etc.
+#[derive(RustcEncodable, RustcDecodable)]
 pub struct VarDecl<'tcx> {
     pub mutability: Mutability,
     pub name: Name,
@@ -135,6 +138,7 @@ pub struct VarDecl<'tcx> {
 
 // A "temp" is a temporary that we place on the stack. They are
 // anonymous, always mutable, and have only a type.
+#[derive(RustcEncodable, RustcDecodable)]
 pub struct TempDecl<'tcx> {
     pub ty: Ty<'tcx>,
 }
@@ -150,6 +154,7 @@ pub struct TempDecl<'tcx> {
 //
 // there is only one argument, of type `(i32, u32)`, but two bindings
 // (`x` and `y`).
+#[derive(RustcEncodable, RustcDecodable)]
 pub struct ArgDecl<'tcx> {
     pub ty: Ty<'tcx>,
 }
@@ -161,7 +166,7 @@ pub struct ArgDecl<'tcx> {
 /// list of the `Mir`.
 ///
 /// (We use a `u32` internally just to save memory.)
-#[derive(Copy, Clone, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub struct BasicBlock(u32);
 
 impl BasicBlock {
@@ -185,12 +190,13 @@ impl Debug for BasicBlock {
 ///////////////////////////////////////////////////////////////////////////
 // BasicBlock and Terminator
 
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable, RustcDecodable)]
 pub struct BasicBlockData<'tcx> {
     pub statements: Vec<Statement<'tcx>>,
     pub terminator: Terminator<'tcx>,
 }
 
+#[derive(RustcEncodable, RustcDecodable)]
 pub enum Terminator<'tcx> {
     /// block should have one successor in the graph; we jump there
     Goto {
@@ -206,7 +212,7 @@ pub enum Terminator<'tcx> {
     /// jump to branch 0 if this lvalue evaluates to true
     If {
         cond: Operand<'tcx>,
-        targets: [BasicBlock; 2],
+        targets: (BasicBlock, BasicBlock),
     },
 
     /// lvalue evaluates to some enum; jump depending on the branch
@@ -254,7 +260,7 @@ pub enum Terminator<'tcx> {
     /// unwinding.
     Call {
         data: CallData<'tcx>,
-        targets: [BasicBlock; 2],
+        targets: (BasicBlock, BasicBlock),
     },
 }
 
@@ -264,12 +270,12 @@ impl<'tcx> Terminator<'tcx> {
         match *self {
             Goto { target: ref b } => slice::ref_slice(b),
             Panic { target: ref b } => slice::ref_slice(b),
-            If { cond: _, targets: ref b } => b,
+            If { cond: _, targets: ref b } => b.as_slice(),
             Switch { targets: ref b, .. } => b,
             SwitchInt { targets: ref b, .. } => b,
             Diverge => &[],
             Return => &[],
-            Call { data: _, targets: ref b } => b,
+            Call { data: _, targets: ref b } => b.as_slice(),
         }
     }
 
@@ -278,17 +284,17 @@ impl<'tcx> Terminator<'tcx> {
         match *self {
             Goto { target: ref mut b } => slice::mut_ref_slice(b),
             Panic { target: ref mut b } => slice::mut_ref_slice(b),
-            If { cond: _, targets: ref mut b } => b,
+            If { cond: _, targets: ref mut b } => b.as_mut_slice(),
             Switch { targets: ref mut b, .. } => b,
             SwitchInt { targets: ref mut b, .. } => b,
             Diverge => &mut [],
             Return => &mut [],
-            Call { data: _, targets: ref mut b } => b,
+            Call { data: _, targets: ref mut b } => b.as_mut_slice(),
         }
     }
 }
 
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable, RustcDecodable)]
 pub struct CallData<'tcx> {
     /// where the return value is written to
     pub destination: Lvalue<'tcx>,
@@ -345,18 +351,19 @@ impl<'tcx> Debug for Terminator<'tcx> {
 ///////////////////////////////////////////////////////////////////////////
 // Statements
 
+#[derive(RustcEncodable, RustcDecodable)]
 pub struct Statement<'tcx> {
     pub span: Span,
     pub kind: StatementKind<'tcx>,
 }
 
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable, RustcDecodable)]
 pub enum StatementKind<'tcx> {
     Assign(Lvalue<'tcx>, Rvalue<'tcx>),
     Drop(DropKind, Lvalue<'tcx>),
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub enum DropKind {
     Free, // free a partially constructed box, should go away eventually
     Deep
@@ -377,7 +384,7 @@ impl<'tcx> Debug for Statement<'tcx> {
 
 /// A path to a value; something that can be evaluated without
 /// changing or disturbing program state.
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
 pub enum Lvalue<'tcx> {
     /// local variable declared by the user
     Var(u32),
@@ -403,13 +410,13 @@ pub enum Lvalue<'tcx> {
 /// or `*B` or `B[index]`. Note that it is parameterized because it is
 /// shared between `Constant` and `Lvalue`. See the aliases
 /// `LvalueProjection` etc below.
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
 pub struct Projection<'tcx, B, V> {
     pub base: B,
     pub elem: ProjectionElem<'tcx, V>,
 }
 
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
 pub enum ProjectionElem<'tcx, V> {
     Deref,
     Field(Field),
@@ -447,7 +454,7 @@ pub type LvalueElem<'tcx> =
     ProjectionElem<'tcx,Operand<'tcx>>;
 
 /// Index into the list of fields found in a `VariantDef`
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub struct Field(u32);
 
 impl Field {
@@ -523,7 +530,7 @@ impl<'tcx> Debug for Lvalue<'tcx> {
 // lvalue). They are intentionally limited to prevent rvalues from
 // being nested in one another.
 
-#[derive(Clone, PartialEq)]
+#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable)]
 pub enum Operand<'tcx> {
     Consume(Lvalue<'tcx>),
     Constant(Constant<'tcx>),
@@ -542,7 +549,7 @@ impl<'tcx> Debug for Operand<'tcx> {
 ///////////////////////////////////////////////////////////////////////////
 // Rvalues
 
-#[derive(Clone)]
+#[derive(Clone, RustcEncodable, RustcDecodable)]
 pub enum Rvalue<'tcx> {
     // x (either a move or copy, depending on type of x)
     Use(Operand<'tcx>),
@@ -583,10 +590,10 @@ pub enum Rvalue<'tcx> {
         from_end: usize,
     },
 
-    InlineAsm(&'tcx InlineAsm),
+    InlineAsm(InlineAsm),
 }
 
-#[derive(Clone, Debug, PartialEq, Eq)]
+#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub enum CastKind {
     Misc,
 
@@ -604,7 +611,7 @@ pub enum CastKind {
     Unsize,
 }
 
-#[derive(Clone, Debug, PartialEq, Eq)]
+#[derive(Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub enum AggregateKind<'tcx> {
     Vec,
     Tuple,
@@ -612,7 +619,7 @@ pub enum AggregateKind<'tcx> {
     Closure(DefId, &'tcx ClosureSubsts<'tcx>),
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub enum BinOp {
     /// The `+` operator (addition)
     Add,
@@ -648,7 +655,7 @@ pub enum BinOp {
     Gt,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
 pub enum UnOp {
     /// The `!` operator for logical inversion
     Not,
@@ -684,14 +691,14 @@ impl<'tcx> Debug for Rvalue<'tcx> {
 // this does not necessarily mean that they are "==" in Rust -- in
 // particular one must be wary of `NaN`!
 
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
 pub struct Constant<'tcx> {
     pub span: Span,
     pub ty: Ty<'tcx>,
     pub literal: Literal<'tcx>,
 }
 
-#[derive(Clone, Debug, PartialEq)]
+#[derive(Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
 pub enum Literal<'tcx> {
     Item {
         def_id: DefId,
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index ac4f54b4b49..00d21d3c16e 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -8,8 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use middle::def_id::DefId;
 use middle::ty::Region;
 use mir::repr::*;
+use rustc_data_structures::tuple_slice::TupleSlice;
+use syntax::codemap::Span;
 
 pub trait Visitor<'tcx> {
     // Override these, and call `self.super_xxx` to revert back to the
@@ -55,6 +58,18 @@ pub trait Visitor<'tcx> {
         self.super_constant(constant);
     }
 
+    fn visit_literal(&mut self, literal: &Literal<'tcx>) {
+        self.super_literal(literal);
+    }
+
+    fn visit_def_id(&mut self, def_id: DefId) {
+        self.super_def_id(def_id);
+    }
+
+    fn visit_span(&mut self, span: Span) {
+        self.super_span(span);
+    }
+
     // The `super_xxx` methods comprise the default behavior and are
     // not meant to be overidden.
 
@@ -73,6 +88,8 @@ pub trait Visitor<'tcx> {
     }
 
     fn super_statement(&mut self, block: BasicBlock, statement: &Statement<'tcx>) {
+        self.visit_span(statement.span);
+
         match statement.kind {
             StatementKind::Assign(ref lvalue, ref rvalue) => {
                 self.visit_assign(block, lvalue, rvalue);
@@ -97,7 +114,7 @@ pub trait Visitor<'tcx> {
 
             Terminator::If { ref cond, ref targets } => {
                 self.visit_operand(cond);
-                for &target in &targets[..] {
+                for &target in targets.as_slice() {
                     self.visit_branch(block, target);
                 }
             }
@@ -126,7 +143,7 @@ pub trait Visitor<'tcx> {
                 for arg in &data.args {
                     self.visit_operand(arg);
                 }
-                for &target in &targets[..] {
+                for &target in targets.as_slice() {
                     self.visit_branch(block, target);
                 }
             }
@@ -217,7 +234,26 @@ pub trait Visitor<'tcx> {
     fn super_branch(&mut self, _source: BasicBlock, _target: BasicBlock) {
     }
 
-    fn super_constant(&mut self, _constant: &Constant<'tcx>) {
+    fn super_constant(&mut self, constant: &Constant<'tcx>) {
+        self.visit_span(constant.span);
+        self.visit_literal(&constant.literal);
+    }
+
+    fn super_literal(&mut self, literal: &Literal<'tcx>) {
+        match *literal {
+            Literal::Item { def_id, .. } => {
+                self.visit_def_id(def_id);
+            },
+            Literal::Value { .. } => {
+                // Nothing to do
+            }
+        }
+    }
+
+    fn super_def_id(&mut self, _def_id: DefId) {
+    }
+
+    fn super_span(&mut self, _span: Span) {
     }
 }
 
@@ -244,3 +280,277 @@ pub enum LvalueContext {
     // Consumed as part of an operand
     Consume,
 }
+
+pub trait MutVisitor<'tcx> {
+    // Override these, and call `self.super_xxx` to revert back to the
+    // default behavior.
+
+    fn visit_mir(&mut self, mir: &mut Mir<'tcx>) {
+        self.super_mir(mir);
+    }
+
+    fn visit_basic_block_data(&mut self,
+                              block: BasicBlock,
+                              data: &mut BasicBlockData<'tcx>) {
+        self.super_basic_block_data(block, data);
+    }
+
+    fn visit_statement(&mut self,
+                       block: BasicBlock,
+                       statement: &mut Statement<'tcx>) {
+        self.super_statement(block, statement);
+    }
+
+    fn visit_assign(&mut self,
+                    block: BasicBlock,
+                    lvalue: &mut Lvalue<'tcx>,
+                    rvalue: &mut Rvalue<'tcx>) {
+        self.super_assign(block, lvalue, rvalue);
+    }
+
+    fn visit_terminator(&mut self,
+                        block: BasicBlock,
+                        terminator: &mut Terminator<'tcx>) {
+        self.super_terminator(block, terminator);
+    }
+
+    fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>) {
+        self.super_rvalue(rvalue);
+    }
+
+    fn visit_operand(&mut self, operand: &mut Operand<'tcx>) {
+        self.super_operand(operand);
+    }
+
+    fn visit_lvalue(&mut self,
+                    lvalue: &mut Lvalue<'tcx>,
+                    context: LvalueContext) {
+        self.super_lvalue(lvalue, context);
+    }
+
+    fn visit_branch(&mut self, source: BasicBlock, target: BasicBlock) {
+        self.super_branch(source, target);
+    }
+
+    fn visit_constant(&mut self, constant: &mut Constant<'tcx>) {
+        self.super_constant(constant);
+    }
+
+    fn visit_literal(&mut self, literal: &mut Literal<'tcx>) {
+        self.super_literal(literal);
+    }
+
+    fn visit_def_id(&mut self, def_id: &mut DefId) {
+        self.super_def_id(def_id);
+    }
+
+    fn visit_span(&mut self, span: &mut Span) {
+        self.super_span(span);
+    }
+
+    // The `super_xxx` methods comprise the default behavior and are
+    // not meant to be overidden.
+
+    fn super_mir(&mut self, mir: &mut Mir<'tcx>) {
+        for block in mir.all_basic_blocks() {
+            let data = mir.basic_block_data_mut(block);
+            self.visit_basic_block_data(block, data);
+        }
+    }
+
+    fn super_basic_block_data(&mut self,
+                              block: BasicBlock,
+                              data: &mut BasicBlockData<'tcx>) {
+        for statement in &mut data.statements {
+            self.visit_statement(block, statement);
+        }
+        self.visit_terminator(block, &mut data.terminator);
+    }
+
+    fn super_statement(&mut self,
+                       block: BasicBlock,
+                       statement: &mut Statement<'tcx>) {
+        self.visit_span(&mut statement.span);
+
+        match statement.kind {
+            StatementKind::Assign(ref mut lvalue, ref mut rvalue) => {
+                self.visit_assign(block, lvalue, rvalue);
+            }
+            StatementKind::Drop(_, ref mut lvalue) => {
+                self.visit_lvalue(lvalue, LvalueContext::Drop);
+            }
+        }
+    }
+
+    fn super_assign(&mut self,
+                    _block: BasicBlock,
+                    lvalue: &mut Lvalue<'tcx>,
+                    rvalue: &mut Rvalue<'tcx>) {
+        self.visit_lvalue(lvalue, LvalueContext::Store);
+        self.visit_rvalue(rvalue);
+    }
+
+    fn super_terminator(&mut self,
+                        block: BasicBlock,
+                        terminator: &mut Terminator<'tcx>) {
+        match *terminator {
+            Terminator::Goto { target } |
+            Terminator::Panic { target } => {
+                self.visit_branch(block, target);
+            }
+
+            Terminator::If { ref mut cond, ref mut targets } => {
+                self.visit_operand(cond);
+                for &target in targets.as_slice() {
+                    self.visit_branch(block, target);
+                }
+            }
+
+            Terminator::Switch { ref mut discr, adt_def: _, ref targets } => {
+                self.visit_lvalue(discr, LvalueContext::Inspect);
+                for &target in targets {
+                    self.visit_branch(block, target);
+                }
+            }
+
+            Terminator::SwitchInt { ref mut discr, switch_ty: _, values: _, ref targets } => {
+                self.visit_lvalue(discr, LvalueContext::Inspect);
+                for &target in targets {
+                    self.visit_branch(block, target);
+                }
+            }
+
+            Terminator::Diverge |
+            Terminator::Return => {
+            }
+
+            Terminator::Call { ref mut data, ref mut targets } => {
+                self.visit_lvalue(&mut data.destination, LvalueContext::Store);
+                self.visit_operand(&mut data.func);
+                for arg in &mut data.args {
+                    self.visit_operand(arg);
+                }
+                for &target in targets.as_slice() {
+                    self.visit_branch(block, target);
+                }
+            }
+        }
+    }
+
+    fn super_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>) {
+        match *rvalue {
+            Rvalue::Use(ref mut operand) => {
+                self.visit_operand(operand);
+            }
+
+            Rvalue::Repeat(ref mut value, ref mut len) => {
+                self.visit_operand(value);
+                self.visit_constant(len);
+            }
+
+            Rvalue::Ref(r, bk, ref mut path) => {
+                self.visit_lvalue(path, LvalueContext::Borrow {
+                    region: r,
+                    kind: bk
+                });
+            }
+
+            Rvalue::Len(ref mut path) => {
+                self.visit_lvalue(path, LvalueContext::Inspect);
+            }
+
+            Rvalue::Cast(_, ref mut operand, _) => {
+                self.visit_operand(operand);
+            }
+
+            Rvalue::BinaryOp(_, ref mut lhs, ref mut rhs) => {
+                self.visit_operand(lhs);
+                self.visit_operand(rhs);
+            }
+
+            Rvalue::UnaryOp(_, ref mut op) => {
+                self.visit_operand(op);
+            }
+
+            Rvalue::Box(_) => {
+            }
+
+            Rvalue::Aggregate(ref mut kind, ref mut operands) => {
+                match *kind {
+                    AggregateKind::Closure(ref mut def_id, _) => {
+                        self.visit_def_id(def_id);
+                    }
+                    _ => { /* nothing to do */ }
+                }
+
+                for operand in &mut operands[..] {
+                    self.visit_operand(operand);
+                }
+            }
+
+            Rvalue::Slice { ref mut input, from_start, from_end } => {
+                self.visit_lvalue(input, LvalueContext::Slice {
+                    from_start: from_start,
+                    from_end: from_end,
+                });
+            }
+
+            Rvalue::InlineAsm(_) => {
+            }
+        }
+    }
+
+    fn super_operand(&mut self, operand: &mut Operand<'tcx>) {
+        match *operand {
+            Operand::Consume(ref mut lvalue) => {
+                self.visit_lvalue(lvalue, LvalueContext::Consume);
+            }
+            Operand::Constant(ref mut constant) => {
+                self.visit_constant(constant);
+            }
+        }
+    }
+
+    fn super_lvalue(&mut self,
+                    lvalue: &mut Lvalue<'tcx>,
+                    _context: LvalueContext) {
+        match *lvalue {
+            Lvalue::Var(_) |
+            Lvalue::Temp(_) |
+            Lvalue::Arg(_) |
+            Lvalue::ReturnPointer => {
+            }
+            Lvalue::Static(ref mut def_id) => {
+                self.visit_def_id(def_id);
+            }
+            Lvalue::Projection(ref mut proj) => {
+                self.visit_lvalue(&mut proj.base, LvalueContext::Projection);
+            }
+        }
+    }
+
+    fn super_branch(&mut self, _source: BasicBlock, _target: BasicBlock) {
+    }
+
+    fn super_constant(&mut self, constant: &mut Constant<'tcx>) {
+        self.visit_span(&mut constant.span);
+        self.visit_literal(&mut constant.literal);
+    }
+
+    fn super_literal(&mut self, literal: &mut Literal<'tcx>) {
+        match *literal {
+            Literal::Item { ref mut def_id, .. } => {
+                self.visit_def_id(def_id);
+            },
+            Literal::Value { .. } => {
+                // Nothing to do
+            }
+        }
+    }
+
+    fn super_def_id(&mut self, _def_id: &mut DefId) {
+    }
+
+    fn super_span(&mut self, _span: &mut Span) {
+    }
+}
diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs
index 39b3842791f..0ea7cfa3902 100644
--- a/src/librustc_data_structures/lib.rs
+++ b/src/librustc_data_structures/lib.rs
@@ -42,6 +42,7 @@ pub mod snapshot_vec;
 pub mod transitive_relation;
 pub mod unify;
 pub mod fnv;
+pub mod tuple_slice;
 
 // See comments in src/librustc/lib.rs
 #[doc(hidden)]
diff --git a/src/librustc_data_structures/tuple_slice.rs b/src/librustc_data_structures/tuple_slice.rs
new file mode 100644
index 00000000000..f157d82eda1
--- /dev/null
+++ b/src/librustc_data_structures/tuple_slice.rs
@@ -0,0 +1,60 @@
+// 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::slice;
+
+/// Allows to view uniform tuples as slices
+pub trait TupleSlice<T> {
+    fn as_slice(&self) -> &[T];
+    fn as_mut_slice(&mut self) -> &mut [T];
+}
+
+macro_rules! impl_tuple_slice {
+    ($tuple_type:ty, $size:expr) => {
+        impl<T> TupleSlice<T> for $tuple_type {
+            fn as_slice(&self) -> &[T] {
+                unsafe {
+                    let ptr = &self.0 as *const T;
+                    slice::from_raw_parts(ptr, $size)
+                }
+            }
+
+            fn as_mut_slice(&mut self) -> &mut [T] {
+                unsafe {
+                    let ptr = &mut self.0 as *mut T;
+                    slice::from_raw_parts_mut(ptr, $size)
+                }
+            }
+        }
+    }
+}
+
+impl_tuple_slice!((T,T), 2);
+impl_tuple_slice!((T,T,T), 3);
+impl_tuple_slice!((T,T,T,T), 4);
+impl_tuple_slice!((T,T,T,T,T), 5);
+impl_tuple_slice!((T,T,T,T,T,T), 6);
+impl_tuple_slice!((T,T,T,T,T,T,T), 7);
+impl_tuple_slice!((T,T,T,T,T,T,T,T), 8);
+
+#[test]
+fn test_sliced_tuples() {
+    let t2 = (100i32, 101i32);
+    assert_eq!(t2.as_slice(), &[100i32, 101i32]);
+
+    let t3 = (102i32, 103i32, 104i32);
+    assert_eq!(t3.as_slice(), &[102i32, 103i32, 104i32]);
+
+    let t4 = (105i32, 106i32, 107i32, 108i32);
+    assert_eq!(t4.as_slice(), &[105i32, 106i32, 107i32, 108i32]);
+
+    let t5 = (109i32, 110i32, 111i32, 112i32, 113i32);
+    assert_eq!(t5.as_slice(), &[109i32, 110i32, 111i32, 112i32, 113i32]);
+}
diff --git a/src/librustc_front/intravisit.rs b/src/librustc_front/intravisit.rs
index e93f5cbd0fb..cb7c5be6529 100644
--- a/src/librustc_front/intravisit.rs
+++ b/src/librustc_front/intravisit.rs
@@ -10,7 +10,7 @@
 
 //! HIR walker. Each overridden visit method has full control over what
 //! happens with its node, it can do its own traversal of the node's children,
-//! call `visit::walk_*` to apply the default traversal algorithm, or prevent
+//! call `intravisit::walk_*` to apply the default traversal algorithm, or prevent
 //! deeper traversal by doing nothing.
 //!
 //! When visiting the HIR, the contents of nested items are NOT visited
@@ -45,7 +45,7 @@ pub enum FnKind<'a> {
 /// Each method of the Visitor trait is a hook to be potentially
 /// overridden.  Each method's default implementation recursively visits
 /// the substructure of the input via the corresponding `walk` method;
-/// e.g. the `visit_mod` method by default calls `visit::walk_mod`.
+/// e.g. the `visit_mod` method by default calls `intravisit::walk_mod`.
 ///
 /// Note that this visitor does NOT visit nested items by default
 /// (this is why the module is called `intravisit`, to distinguish it
diff --git a/src/librustc_metadata/common.rs b/src/librustc_metadata/common.rs
index b6454a4c81a..5186c969133 100644
--- a/src/librustc_metadata/common.rs
+++ b/src/librustc_metadata/common.rs
@@ -120,7 +120,8 @@ enum_from_u32! {
 
         tag_tree = 0x51,
 
-        // GAP 0x52
+        tag_mir = 0x52,
+
         tag_table = 0x53,
         // GAP 0x54, 0x55
         tag_table_def = 0x56,
diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs
index aae3a762c19..ad00ef29e5f 100644
--- a/src/librustc_metadata/csearch.rs
+++ b/src/librustc_metadata/csearch.rs
@@ -22,6 +22,7 @@ use middle::ty::{self, Ty};
 use middle::def_id::{DefId, DefIndex};
 
 use rustc::front::map as hir_map;
+use rustc::mir::repr::Mir;
 use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet};
 
 use std::cell::RefCell;
@@ -421,6 +422,12 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         decoder::maybe_get_item_ast(&*cdata, tcx, def.index, decode_inlined_item)
     }
 
+    fn maybe_get_item_mir(&self, tcx: &ty::ctxt<'tcx>, def: DefId)
+                          -> Option<Mir<'tcx>> {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::maybe_get_item_mir(&*cdata, tcx, def.index)
+    }
+
     fn crates(&self) -> Vec<ast::CrateNum>
     {
         let mut result = vec![];
@@ -473,6 +480,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
                        item_symbols: &RefCell<NodeMap<String>>,
                        link_meta: &LinkMeta,
                        reachable: &NodeSet,
+                       mir_map: &NodeMap<Mir<'tcx>>,
                        krate: &hir::Crate) -> Vec<u8>
     {
         let encode_inlined_item: encoder::EncodeInlinedItem =
@@ -486,7 +494,8 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
             link_meta: link_meta,
             cstore: self,
             encode_inlined_item: encode_inlined_item,
-            reachable: reachable
+            reachable: reachable,
+            mir_map: mir_map,
         };
         encoder::encode_metadata(encode_params, krate)
 
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index c139ec4f62a..d1917b29b9f 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -18,6 +18,7 @@ use cstore::{self, crate_metadata};
 use common::*;
 use encoder::def_to_u64;
 use index;
+use tls_context;
 use tydecode::TyDecoder;
 
 use rustc::back::svh::Svh;
@@ -26,7 +27,7 @@ use rustc::util::nodemap::FnvHashMap;
 use rustc_front::hir;
 
 use middle::cstore::{LOCAL_CRATE, FoundAst, InlinedItem, LinkagePreference};
-use middle::cstore::{DefLike, DlDef, DlField, DlImpl};
+use middle::cstore::{DefLike, DlDef, DlField, DlImpl, tls};
 use middle::def;
 use middle::def_id::{DefId, DefIndex};
 use middle::lang_items;
@@ -34,6 +35,9 @@ use middle::subst;
 use middle::ty::{ImplContainer, TraitContainer};
 use middle::ty::{self, RegionEscape, Ty};
 
+use rustc::mir;
+use rustc::mir::visit::MutVisitor;
+
 use std::cell::{Cell, RefCell};
 use std::io::prelude::*;
 use std::io;
@@ -48,7 +52,7 @@ use syntax::parse::token::{IdentInterner, special_idents};
 use syntax::parse::token;
 use syntax::ast;
 use syntax::abi;
-use syntax::codemap;
+use syntax::codemap::{self, Span};
 use syntax::print::pprust;
 use syntax::ptr::P;
 
@@ -783,6 +787,56 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: DefIndex,
     }
 }
 
+pub fn maybe_get_item_mir<'tcx>(cdata: Cmd,
+                                tcx: &ty::ctxt<'tcx>,
+                                id: DefIndex)
+                                -> Option<mir::repr::Mir<'tcx>> {
+    let item_doc = cdata.lookup_item(id);
+
+    return reader::maybe_get_doc(item_doc, tag_mir as usize).map(|mir_doc| {
+        let dcx = tls_context::DecodingContext {
+            crate_metadata: cdata,
+            tcx: tcx,
+        };
+        let mut decoder = reader::Decoder::new(mir_doc);
+
+        let mut mir = tls::enter_decoding_context(&dcx, &mut decoder, |_, decoder| {
+            Decodable::decode(decoder).unwrap()
+        });
+
+        let mut def_id_and_span_translator = MirDefIdAndSpanTranslator {
+            crate_metadata: cdata,
+            codemap: tcx.sess.codemap(),
+            last_filemap_index_hint: Cell::new(0),
+        };
+
+        def_id_and_span_translator.visit_mir(&mut mir);
+
+        mir
+    });
+
+    struct MirDefIdAndSpanTranslator<'cdata, 'codemap> {
+        crate_metadata: Cmd<'cdata>,
+        codemap: &'codemap codemap::CodeMap,
+        last_filemap_index_hint: Cell<usize>
+    }
+
+    impl<'v, 'cdata, 'codemap> mir::visit::MutVisitor<'v>
+        for MirDefIdAndSpanTranslator<'cdata, 'codemap>
+    {
+        fn visit_def_id(&mut self, def_id: &mut DefId) {
+            *def_id = translate_def_id(self.crate_metadata, *def_id);
+        }
+
+        fn visit_span(&mut self, span: &mut Span) {
+            *span = translate_span(self.crate_metadata,
+                                   self.codemap,
+                                   &self.last_filemap_index_hint,
+                                   *span);
+        }
+    }
+}
+
 fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory {
     fn get_mutability(ch: u8) -> hir::Mutability {
         match ch as char {
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 448a64c93c1..a627eeb6880 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -30,6 +30,7 @@ use middle::ty::{self, Ty};
 use rustc::back::svh::Svh;
 use rustc::front::map::{LinkedPath, PathElem, PathElems};
 use rustc::front::map as ast_map;
+use rustc::mir::repr::Mir;
 use rustc::session::config;
 use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet};
 
@@ -64,6 +65,7 @@ pub struct EncodeParams<'a, 'tcx: 'a> {
     pub cstore: &'a cstore::CStore,
     pub encode_inlined_item: EncodeInlinedItem<'a>,
     pub reachable: &'a NodeSet,
+    pub mir_map: &'a NodeMap<Mir<'tcx>>,
 }
 
 pub struct EncodeContext<'a, 'tcx: 'a> {
@@ -76,6 +78,7 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
     pub encode_inlined_item: RefCell<EncodeInlinedItem<'a>>,
     pub type_abbrevs: tyencode::abbrev_map<'tcx>,
     pub reachable: &'a NodeSet,
+    pub mir_map: &'a NodeMap<Mir<'tcx>>,
 }
 
 impl<'a, 'tcx> EncodeContext<'a,'tcx> {
@@ -840,7 +843,24 @@ fn encode_inlined_item(ecx: &EncodeContext,
                        ii: InlinedItemRef) {
     let mut eii = ecx.encode_inlined_item.borrow_mut();
     let eii: &mut EncodeInlinedItem = &mut *eii;
-    eii(ecx, rbml_w, ii)
+    eii(ecx, rbml_w, ii);
+
+    encode_mir(ecx, rbml_w, ii);
+}
+
+fn encode_mir(ecx: &EncodeContext, rbml_w: &mut Encoder, ii: InlinedItemRef) {
+    let id = match ii {
+        InlinedItemRef::Item(item) => item.id,
+        InlinedItemRef::TraitItem(_, trait_item) => trait_item.id,
+        InlinedItemRef::ImplItem(_, impl_item) => impl_item.id,
+        InlinedItemRef::Foreign(foreign_item) => foreign_item.id
+    };
+
+    if let Some(mir) = ecx.mir_map.get(&id) {
+        rbml_w.start_tag(tag_mir as usize);
+        Encodable::encode(mir, rbml_w).unwrap();
+        rbml_w.end_tag();
+    }
 }
 
 const FN_FAMILY: char = 'f';
@@ -1884,6 +1904,7 @@ pub fn encode_metadata(parms: EncodeParams, krate: &hir::Crate) -> Vec<u8> {
         encode_inlined_item,
         link_meta,
         reachable,
+        mir_map,
         ..
     } = parms;
     let ecx = EncodeContext {
@@ -1896,6 +1917,7 @@ pub fn encode_metadata(parms: EncodeParams, krate: &hir::Crate) -> Vec<u8> {
         encode_inlined_item: RefCell::new(encode_inlined_item),
         type_abbrevs: RefCell::new(FnvHashMap()),
         reachable: reachable,
+        mir_map: mir_map,
     };
 
     let mut wr = Cursor::new(Vec::new());
diff --git a/src/librustc_mir/build/expr/as_lvalue.rs b/src/librustc_mir/build/expr/as_lvalue.rs
index 697799efd14..1c96addcea0 100644
--- a/src/librustc_mir/build/expr/as_lvalue.rs
+++ b/src/librustc_mir/build/expr/as_lvalue.rs
@@ -69,7 +69,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                 this.cfg.terminate(block,
                                    Terminator::If {
                                        cond: Operand::Consume(lt),
-                                       targets: [success, failure],
+                                       targets: (success, failure),
                                    });
                 this.panic(failure);
                 success.and(slice.index(idx))
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index 7f69b9a521f..2f57dd22454 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -40,7 +40,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                 this.in_scope(extent, block, |this| this.as_rvalue(block, value))
             }
             ExprKind::InlineAsm { asm } => {
-                block.and(Rvalue::InlineAsm(asm))
+                block.and(Rvalue::InlineAsm(asm.clone()))
             }
             ExprKind::Repeat { value, count } => {
                 let value_operand = unpack!(block = this.as_operand(block, value));
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs
index ac3e87e6b62..802c55ce764 100644
--- a/src/librustc_mir/build/expr/into.rs
+++ b/src/librustc_mir/build/expr/into.rs
@@ -53,7 +53,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                 let mut else_block = this.cfg.start_new_block();
                 this.cfg.terminate(block, Terminator::If {
                     cond: operand,
-                    targets: [then_block, else_block]
+                    targets: (then_block, else_block)
                 });
 
                 unpack!(then_block = this.into(destination, then_block, then_expr));
@@ -84,15 +84,15 @@ impl<'a,'tcx> Builder<'a,'tcx> {
 
                 let lhs = unpack!(block = this.as_operand(block, lhs));
                 let blocks = match op {
-                    LogicalOp::And => [else_block, false_block],
-                    LogicalOp::Or => [true_block, else_block],
+                    LogicalOp::And => (else_block, false_block),
+                    LogicalOp::Or => (true_block, else_block),
                 };
                 this.cfg.terminate(block, Terminator::If { cond: lhs, targets: blocks });
 
                 let rhs = unpack!(else_block = this.as_operand(else_block, rhs));
                 this.cfg.terminate(else_block, Terminator::If {
                     cond: rhs,
-                    targets: [true_block, false_block]
+                    targets: (true_block, false_block)
                 });
 
                 this.cfg.push_assign_constant(
@@ -149,7 +149,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                         this.cfg.terminate(loop_block_end,
                                            Terminator::If {
                                                cond: cond,
-                                               targets: [body_block, exit_block]
+                                               targets: (body_block, exit_block)
                                            });
                     } else {
                         body_block = loop_block;
@@ -225,7 +225,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                                            func: fun,
                                            args: args,
                                        },
-                                       targets: [success, panic],
+                                       targets: (success, panic),
                                    });
                 success.unit()
             }
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index 0248f2fc49a..f8385d58170 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -555,7 +555,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
             let cond = unpack!(block = self.as_operand(block, guard));
             let otherwise = self.cfg.start_new_block();
             self.cfg.terminate(block, Terminator::If { cond: cond,
-                                                       targets: [arm_block, otherwise]});
+                                                       targets: (arm_block, otherwise)});
             Some(otherwise)
         } else {
             self.cfg.terminate(block, Terminator::Goto { target: arm_block });
diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs
index 968514cd05c..7b329fc4d52 100644
--- a/src/librustc_mir/build/matches/test.rs
+++ b/src/librustc_mir/build/matches/test.rs
@@ -232,7 +232,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                                                  self.cfg.start_new_block()];
                 self.cfg.terminate(block, Terminator::If {
                     cond: Operand::Consume(result),
-                    targets: [target_blocks[0], target_blocks[1]]
+                    targets: (target_blocks[0], target_blocks[1])
                 });
 
                 target_blocks
@@ -252,7 +252,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
         let bool_ty = self.hir.bool_ty();
         let eq_result = self.temp(bool_ty);
         let func = self.item_ref_operand(span, item_ref);
-        let call_blocks = [self.cfg.start_new_block(), self.diverge_cleanup()];
+        let call_blocks = (self.cfg.start_new_block(), self.diverge_cleanup());
         self.cfg.terminate(block,
                            Terminator::Call {
                                data: CallData {
@@ -264,10 +264,10 @@ impl<'a,'tcx> Builder<'a,'tcx> {
                            });
 
         // check the result
-        self.cfg.terminate(call_blocks[0],
+        self.cfg.terminate(call_blocks.0,
                            Terminator::If {
                                cond: Operand::Consume(eq_result),
-                               targets: [target_blocks[0], target_blocks[1]],
+                               targets: (target_blocks[0], target_blocks[1]),
                            });
 
         target_blocks
diff --git a/src/librustc_mir/transform/simplify_cfg.rs b/src/librustc_mir/transform/simplify_cfg.rs
index 558276a13a8..d0c0afc80a6 100644
--- a/src/librustc_mir/transform/simplify_cfg.rs
+++ b/src/librustc_mir/transform/simplify_cfg.rs
@@ -96,9 +96,9 @@ impl SimplifyCfg {
             mem::swap(&mut terminator, &mut mir.basic_block_data_mut(bb).terminator);
 
             mir.basic_block_data_mut(bb).terminator = match terminator {
-                Terminator::If { ref targets, .. } if targets[0] == targets[1] => {
+                Terminator::If { ref targets, .. } if targets.0 == targets.1 => {
                     changed = true;
-                    Terminator::Goto { target: targets[0] }
+                    Terminator::Goto { target: targets.0 }
                 }
                 Terminator::If { ref targets, cond: Operand::Constant(Constant {
                     literal: Literal::Value {
@@ -106,8 +106,11 @@ impl SimplifyCfg {
                     }, ..
                 }) } => {
                     changed = true;
-                    let target_idx = if cond { 0 } else { 1 };
-                    Terminator::Goto { target: targets[target_idx] }
+                    if cond {
+                        Terminator::Goto { target: targets.0 }
+                    } else {
+                        Terminator::Goto { target: targets.1 }
+                    }
                 }
                 Terminator::SwitchInt { ref targets, .. }  if targets.len() == 1 => {
                     Terminator::Goto { target: targets[0] }
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index dde6e3935b2..838a5435d4f 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -2760,7 +2760,11 @@ fn register_method(ccx: &CrateContext,
     }
 }
 
-pub fn write_metadata(cx: &SharedCrateContext, krate: &hir::Crate, reachable: &NodeSet) -> Vec<u8> {
+pub fn write_metadata<'a, 'tcx>(cx: &SharedCrateContext<'a, 'tcx>,
+                                krate: &hir::Crate,
+                                reachable: &NodeSet,
+                                mir_map: &MirMap<'tcx>)
+                                -> Vec<u8> {
     use flate;
 
     let any_library = cx.sess()
@@ -2773,9 +2777,13 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &hir::Crate, reachable: &N
     }
 
     let cstore = &cx.tcx().sess.cstore;
-    let metadata = cstore.encode_metadata(
-        cx.tcx(), cx.export_map(), cx.item_symbols(), cx.link_meta(), reachable,
-        krate);
+    let metadata = cstore.encode_metadata(cx.tcx(),
+                                          cx.export_map(),
+                                          cx.item_symbols(),
+                                          cx.link_meta(),
+                                          reachable,
+                                          mir_map,
+                                          krate);
     let mut compressed = cstore.metadata_encoding_version().to_vec();
     compressed.extend_from_slice(&flate::deflate_bytes(&metadata));
 
@@ -3045,7 +3053,7 @@ pub fn trans_crate<'tcx>(tcx: &ty::ctxt<'tcx>,
     let reachable_symbol_ids = filter_reachable_ids(&shared_ccx);
 
     // Translate the metadata.
-    let metadata = write_metadata(&shared_ccx, krate, &reachable_symbol_ids);
+    let metadata = write_metadata(&shared_ccx, krate, &reachable_symbol_ids, mir_map);
 
     if shared_ccx.sess().trans_stats() {
         let stats = shared_ccx.stats();
diff --git a/src/librustc_trans/trans/mir/block.rs b/src/librustc_trans/trans/mir/block.rs
index 3ce08fb2f60..b58b51f5a2b 100644
--- a/src/librustc_trans/trans/mir/block.rs
+++ b/src/librustc_trans/trans/mir/block.rs
@@ -39,7 +39,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                 unimplemented!()
             }
 
-            mir::Terminator::If { ref cond, targets: [true_bb, false_bb] } => {
+            mir::Terminator::If { ref cond, targets: (true_bb, false_bb) } => {
                 let cond = self.trans_operand(bcx, cond);
                 let lltrue = self.llblock(true_bb);
                 let llfalse = self.llblock(false_bb);
diff --git a/src/librustc_trans/trans/mir/rvalue.rs b/src/librustc_trans/trans/mir/rvalue.rs
index 17e4ec8e827..529e65dace0 100644
--- a/src/librustc_trans/trans/mir/rvalue.rs
+++ b/src/librustc_trans/trans/mir/rvalue.rs
@@ -120,7 +120,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                 bcx
             }
 
-            mir::Rvalue::InlineAsm(inline_asm) => {
+            mir::Rvalue::InlineAsm(ref inline_asm) => {
                 asm::trans_inline_asm(bcx, inline_asm)
             }
 
diff --git a/src/librustc_unicode/char.rs b/src/librustc_unicode/char.rs
index 3824dd0e436..455e2feee4c 100644
--- a/src/librustc_unicode/char.rs
+++ b/src/librustc_unicode/char.rs
@@ -386,9 +386,10 @@ impl char {
     /// Returns the number of 16-bit code units this `char` would need if
     /// encoded in UTF-16.
     ///
-    /// See the documentation for [`len_utf8()`][len_utf8] for more explanation
-    /// of this concept. This function is a mirror, but for UTF-16 instead of
-    /// UTF-8.
+    /// See the documentation for [`len_utf8()`] for more explanation of this
+    /// concept. This function is a mirror, but for UTF-16 instead of UTF-8.
+    ///
+    /// [`len_utf8()`]: #method.len_utf8
     ///
     /// # Examples
     ///
diff --git a/src/librustc_unicode/lib.rs b/src/librustc_unicode/lib.rs
index e440b117186..8bde24d2b0c 100644
--- a/src/librustc_unicode/lib.rs
+++ b/src/librustc_unicode/lib.rs
@@ -48,8 +48,8 @@ pub mod char;
 #[allow(deprecated)]
 pub mod str {
     pub use u_str::{UnicodeStr, SplitWhitespace};
-    pub use u_str::{utf8_char_width, is_utf16, Utf16Items, Utf16Item};
-    pub use u_str::{utf16_items, Utf16Encoder};
+    pub use u_str::{utf8_char_width, is_utf16};
+    pub use u_str::{Utf16Encoder};
 }
 
 // For use in libcollections, not re-exported in libstd.
diff --git a/src/librustc_unicode/u_str.rs b/src/librustc_unicode/u_str.rs
index 4d9f5d5fdd4..f65c05672f6 100644
--- a/src/librustc_unicode/u_str.rs
+++ b/src/librustc_unicode/u_str.rs
@@ -13,10 +13,8 @@
 //! This module provides functionality to `str` that requires the Unicode
 //! methods provided by the unicode parts of the CharExt trait.
 
-use char::{DecodeUtf16, decode_utf16};
 use core::char;
-use core::iter::{Cloned, Filter};
-use core::slice;
+use core::iter::Filter;
 use core::str::Split;
 
 /// An iterator over the non-whitespace substrings of a string,
@@ -127,97 +125,6 @@ pub fn is_utf16(v: &[u16]) -> bool {
     }
 }
 
-/// An iterator that decodes UTF-16 encoded codepoints from a vector
-/// of `u16`s.
-#[rustc_deprecated(since = "1.4.0", reason = "renamed to `char::DecodeUtf16`")]
-#[unstable(feature = "decode_utf16", reason = "not exposed in std", issue = "27830")]
-#[allow(deprecated)]
-#[derive(Clone)]
-pub struct Utf16Items<'a> {
-    decoder: DecodeUtf16<Cloned<slice::Iter<'a, u16>>>,
-}
-
-/// The possibilities for values decoded from a `u16` stream.
-#[rustc_deprecated(since = "1.4.0",
-                   reason = "`char::DecodeUtf16` uses `Result<char, u16>` instead")]
-#[unstable(feature = "decode_utf16", reason = "not exposed in std", issue = "27830")]
-#[allow(deprecated)]
-#[derive(Copy, PartialEq, Eq, Clone, Debug)]
-pub enum Utf16Item {
-    /// A valid codepoint.
-    ScalarValue(char),
-    /// An invalid surrogate without its pair.
-    LoneSurrogate(u16),
-}
-
-#[allow(deprecated)]
-impl Utf16Item {
-    /// Convert `self` to a `char`, taking `LoneSurrogate`s to the
-    /// replacement character (U+FFFD).
-    #[inline]
-    pub fn to_char_lossy(&self) -> char {
-        match *self {
-            Utf16Item::ScalarValue(c) => c,
-            Utf16Item::LoneSurrogate(_) => '\u{FFFD}',
-        }
-    }
-}
-
-#[rustc_deprecated(since = "1.4.0", reason = "use `char::DecodeUtf16` instead")]
-#[unstable(feature = "decode_utf16", reason = "not exposed in std", issue = "27830")]
-#[allow(deprecated)]
-impl<'a> Iterator for Utf16Items<'a> {
-    type Item = Utf16Item;
-
-    fn next(&mut self) -> Option<Utf16Item> {
-        self.decoder.next().map(|result| {
-            match result {
-                Ok(c) => Utf16Item::ScalarValue(c),
-                Err(s) => Utf16Item::LoneSurrogate(s),
-            }
-        })
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        self.decoder.size_hint()
-    }
-}
-
-/// Create an iterator over the UTF-16 encoded codepoints in `v`,
-/// returning invalid surrogates as `LoneSurrogate`s.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(unicode, decode_utf16)]
-/// # #![allow(deprecated)]
-///
-/// extern crate rustc_unicode;
-///
-/// use rustc_unicode::str::Utf16Item::{ScalarValue, LoneSurrogate};
-///
-/// fn main() {
-///     // 𝄞mus<invalid>ic<invalid>
-///     let v = [0xD834, 0xDD1E, 0x006d, 0x0075,
-///              0x0073, 0xDD1E, 0x0069, 0x0063,
-///              0xD834];
-///
-///     assert_eq!(rustc_unicode::str::utf16_items(&v).collect::<Vec<_>>(),
-///                vec![ScalarValue('𝄞'),
-///                     ScalarValue('m'), ScalarValue('u'), ScalarValue('s'),
-///                     LoneSurrogate(0xDD1E),
-///                     ScalarValue('i'), ScalarValue('c'),
-///                     LoneSurrogate(0xD834)]);
-/// }
-/// ```
-#[rustc_deprecated(since = "1.4.0", reason = "renamed to `char::decode_utf16`")]
-#[unstable(feature = "decode_utf16", reason = "not exposed in std", issue = "27830")]
-#[allow(deprecated)]
-pub fn utf16_items<'a>(v: &'a [u16]) -> Utf16Items<'a> {
-    Utf16Items { decoder: decode_utf16(v.iter().cloned()) }
-}
-
 /// Iterator adaptor for encoding `char`s to UTF-16.
 #[derive(Clone)]
 pub struct Utf16Encoder<I> {
diff --git a/src/libstd/collections/hash/bench.rs b/src/libstd/collections/hash/bench.rs
index ac21ae0f0aa..9fae9af2d54 100644
--- a/src/libstd/collections/hash/bench.rs
+++ b/src/libstd/collections/hash/bench.rs
@@ -14,7 +14,6 @@ extern crate test;
 use prelude::v1::*;
 
 use self::test::Bencher;
-use iter::range_inclusive;
 
 #[bench]
 fn new_drop(b : &mut Bencher) {
@@ -43,7 +42,7 @@ fn grow_by_insertion(b: &mut Bencher) {
 
     let mut m = HashMap::new();
 
-    for i in range_inclusive(1, 1000) {
+    for i in 1..1001 {
         m.insert(i, i);
     }
 
@@ -61,12 +60,12 @@ fn find_existing(b: &mut Bencher) {
 
     let mut m = HashMap::new();
 
-    for i in range_inclusive(1, 1000) {
+    for i in 1..1001 {
         m.insert(i, i);
     }
 
     b.iter(|| {
-        for i in range_inclusive(1, 1000) {
+        for i in 1..1001 {
             m.contains_key(&i);
         }
     });
@@ -78,12 +77,12 @@ fn find_nonexisting(b: &mut Bencher) {
 
     let mut m = HashMap::new();
 
-    for i in range_inclusive(1, 1000) {
+    for i in 1..1001 {
         m.insert(i, i);
     }
 
     b.iter(|| {
-        for i in range_inclusive(1001, 2000) {
+        for i in 1001..2001 {
             m.contains_key(&i);
         }
     });
@@ -95,7 +94,7 @@ fn hashmap_as_queue(b: &mut Bencher) {
 
     let mut m = HashMap::new();
 
-    for i in range_inclusive(1, 1000) {
+    for i in 1..1001 {
         m.insert(i, i);
     }
 
@@ -114,7 +113,7 @@ fn get_remove_insert(b: &mut Bencher) {
 
     let mut m = HashMap::new();
 
-    for i in range_inclusive(1, 1000) {
+    for i in 1..1001 {
         m.insert(i, i);
     }
 
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 77c4149f992..38c080febf1 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -1681,7 +1681,6 @@ mod test_map {
 
     use super::HashMap;
     use super::Entry::{Occupied, Vacant};
-    use iter::range_inclusive;
     use cell::RefCell;
     use rand::{thread_rng, Rng};
 
@@ -1877,42 +1876,42 @@ mod test_map {
         for _ in 0..10 {
             assert!(m.is_empty());
 
-            for i in range_inclusive(1, 1000) {
+            for i in 1..1001 {
                 assert!(m.insert(i, i).is_none());
 
-                for j in range_inclusive(1, i) {
+                for j in 1..i+1 {
                     let r = m.get(&j);
                     assert_eq!(r, Some(&j));
                 }
 
-                for j in range_inclusive(i+1, 1000) {
+                for j in i+1..1001 {
                     let r = m.get(&j);
                     assert_eq!(r, None);
                 }
             }
 
-            for i in range_inclusive(1001, 2000) {
+            for i in 1001..2001 {
                 assert!(!m.contains_key(&i));
             }
 
             // remove forwards
-            for i in range_inclusive(1, 1000) {
+            for i in 1..1001 {
                 assert!(m.remove(&i).is_some());
 
-                for j in range_inclusive(1, i) {
+                for j in 1..i+1 {
                     assert!(!m.contains_key(&j));
                 }
 
-                for j in range_inclusive(i+1, 1000) {
+                for j in i+1..1001 {
                     assert!(m.contains_key(&j));
                 }
             }
 
-            for i in range_inclusive(1, 1000) {
+            for i in 1..1001 {
                 assert!(!m.contains_key(&i));
             }
 
-            for i in range_inclusive(1, 1000) {
+            for i in 1..1001 {
                 assert!(m.insert(i, i).is_none());
             }
 
@@ -1920,11 +1919,11 @@ mod test_map {
             for i in (1..1001).rev() {
                 assert!(m.remove(&i).is_some());
 
-                for j in range_inclusive(i, 1000) {
+                for j in i..1001 {
                     assert!(!m.contains_key(&j));
                 }
 
-                for j in range_inclusive(1, i-1) {
+                for j in 1..i {
                     assert!(m.contains_key(&j));
                 }
             }
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 40fb450bea1..318ff410cba 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -211,18 +211,6 @@ impl CString {
     /// The only appropriate argument is a pointer obtained by calling
     /// `into_raw`. The length of the string will be recalculated
     /// using the pointer.
-    #[unstable(feature = "cstr_memory2", reason = "recently added",
-               issue = "27769")]
-    #[rustc_deprecated(since = "1.4.0", reason = "renamed to from_raw")]
-    pub unsafe fn from_ptr(ptr: *const c_char) -> CString {
-        CString::from_raw(ptr as *mut _)
-    }
-
-    /// Retakes ownership of a CString that was transferred to C.
-    ///
-    /// The only appropriate argument is a pointer obtained by calling
-    /// `into_raw`. The length of the string will be recalculated
-    /// using the pointer.
     #[stable(feature = "cstr_memory", since = "1.4.0")]
     pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
         let len = libc::strlen(ptr) + 1; // Including the NUL byte
@@ -238,21 +226,6 @@ impl CString {
     /// this string.
     ///
     /// Failure to call `from_raw` will lead to a memory leak.
-    #[unstable(feature = "cstr_memory2", reason = "recently added",
-               issue = "27769")]
-    #[rustc_deprecated(since = "1.4.0", reason = "renamed to into_raw")]
-    pub fn into_ptr(self) -> *const c_char {
-        self.into_raw() as *const _
-    }
-
-    /// Transfers ownership of the string to a C caller.
-    ///
-    /// The pointer must be returned to Rust and reconstituted using
-    /// `from_raw` to be properly deallocated. Specifically, one
-    /// should *not* use the standard C `free` function to deallocate
-    /// this string.
-    ///
-    /// Failure to call `from_raw` will lead to a memory leak.
     #[stable(feature = "cstr_memory", since = "1.4.0")]
     pub fn into_raw(self) -> *mut c_char {
         Box::into_raw(self.inner) as *mut c_char
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index bfad2248359..25a05efd026 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -1178,85 +1178,6 @@ impl Iterator for WalkDir {
     }
 }
 
-/// Utility methods for paths.
-#[unstable(feature = "path_ext_deprecated",
-           reason = "The precise set of methods exposed on this trait may \
-                     change and some methods may be removed.  For stable code, \
-                     see the std::fs::metadata function.",
-           issue = "27725")]
-#[rustc_deprecated(since = "1.5.0", reason = "replaced with inherent methods")]
-pub trait PathExt {
-    /// Gets information on the file, directory, etc at this path.
-    ///
-    /// Consult the `fs::metadata` documentation for more info.
-    ///
-    /// This call preserves identical runtime/error semantics with
-    /// `fs::metadata`.
-    fn metadata(&self) -> io::Result<Metadata>;
-
-    /// Gets information on the file, directory, etc at this path.
-    ///
-    /// Consult the `fs::symlink_metadata` documentation for more info.
-    ///
-    /// This call preserves identical runtime/error semantics with
-    /// `fs::symlink_metadata`.
-    fn symlink_metadata(&self) -> io::Result<Metadata>;
-
-    /// Returns the canonical form of a path, normalizing all components and
-    /// eliminate all symlinks.
-    ///
-    /// This call preserves identical runtime/error semantics with
-    /// `fs::canonicalize`.
-    fn canonicalize(&self) -> io::Result<PathBuf>;
-
-    /// Reads the symlink at this path.
-    ///
-    /// For more information see `fs::read_link`.
-    fn read_link(&self) -> io::Result<PathBuf>;
-
-    /// Reads the directory at this path.
-    ///
-    /// For more information see `fs::read_dir`.
-    fn read_dir(&self) -> io::Result<ReadDir>;
-
-    /// Boolean value indicator whether the underlying file exists on the local
-    /// filesystem. Returns false in exactly the cases where `fs::metadata`
-    /// fails.
-    fn exists(&self) -> bool;
-
-    /// Whether the underlying implementation (be it a file path, or something
-    /// else) points at a "regular file" on the FS. Will return false for paths
-    /// to non-existent locations or directories or other non-regular files
-    /// (named pipes, etc). Follows links when making this determination.
-    fn is_file(&self) -> bool;
-
-    /// Whether the underlying implementation (be it a file path, or something
-    /// else) is pointing at a directory in the underlying FS. Will return
-    /// false for paths to non-existent locations or if the item is not a
-    /// directory (eg files, named pipes, etc). Follows links when making this
-    /// determination.
-    fn is_dir(&self) -> bool;
-}
-
-#[allow(deprecated)]
-#[unstable(feature = "path_ext_deprecated", issue = "27725")]
-impl PathExt for Path {
-    fn metadata(&self) -> io::Result<Metadata> { metadata(self) }
-    fn symlink_metadata(&self) -> io::Result<Metadata> { symlink_metadata(self) }
-    fn canonicalize(&self) -> io::Result<PathBuf> { canonicalize(self) }
-    fn read_link(&self) -> io::Result<PathBuf> { read_link(self) }
-    fn read_dir(&self) -> io::Result<ReadDir> { read_dir(self) }
-    fn exists(&self) -> bool { metadata(self).is_ok() }
-
-    fn is_file(&self) -> bool {
-        metadata(self).map(|s| s.is_file()).unwrap_or(false)
-    }
-
-    fn is_dir(&self) -> bool {
-        metadata(self).map(|s| s.is_dir()).unwrap_or(false)
-    }
-}
-
 /// Changes the permissions found on a file or a directory.
 ///
 /// # Examples
diff --git a/src/libstd/io/prelude.rs b/src/libstd/io/prelude.rs
index f588ec60589..8772d0f5b09 100644
--- a/src/libstd/io/prelude.rs
+++ b/src/libstd/io/prelude.rs
@@ -22,6 +22,3 @@
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use super::{Read, Write, BufRead, Seek};
-#[allow(deprecated)]
-#[unstable(feature = "path_ext_deprecated", issue = "27725")]
-pub use fs::PathExt;
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 8e6c32ff2fc..c8b8caee84e 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -233,7 +233,6 @@
 #![feature(const_fn)]
 #![feature(core_float)]
 #![feature(core_intrinsics)]
-#![feature(core_simd)]
 #![feature(decode_utf16)]
 #![feature(drop_in_place)]
 #![feature(dropck_parametricity)]
@@ -255,6 +254,7 @@
 #![feature(rand)]
 #![feature(range_inclusive)]
 #![feature(raw)]
+#![feature(repr_simd)]
 #![feature(reflect_marker)]
 #![feature(shared)]
 #![feature(slice_bytes)]
@@ -334,9 +334,6 @@ pub use core::ptr;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::raw;
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-pub use core::simd;
-#[stable(feature = "rust1", since = "1.0.0")]
 pub use core::result;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::option;
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index c87becd741e..30bee80fbf6 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -18,7 +18,7 @@
 use core::num;
 use intrinsics;
 use libc::c_int;
-use num::{FpCategory, ParseFloatError};
+use num::FpCategory;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON};
@@ -126,16 +126,6 @@ mod cmath {
 #[cfg(not(test))]
 #[lang = "f32"]
 impl f32 {
-    /// Parses a float as with a given radix
-    #[unstable(feature = "float_from_str_radix", reason = "recently moved API",
-               issue = "27736")]
-    #[rustc_deprecated(since = "1.4.0",
-                 reason = "unclear how useful or correct this is")]
-    #[allow(deprecated)]
-    pub fn from_str_radix(s: &str, radix: u32) -> Result<f32, ParseFloatError> {
-        num::Float::from_str_radix(s, radix)
-    }
-
     /// Returns `true` if this value is `NaN` and false otherwise.
     ///
     /// ```
@@ -1712,11 +1702,9 @@ mod tests {
 
     #[test]
     fn test_ldexp() {
-        // We have to use from_str until base-2 exponents
-        // are supported in floating-point literals
-        let f1: f32 = f32::from_str_radix("1p-123", 16).unwrap();
-        let f2: f32 = f32::from_str_radix("1p-111", 16).unwrap();
-        let f3: f32 = f32::from_str_radix("1.Cp-12", 16).unwrap();
+        let f1 = 2.0f32.powi(-123);
+        let f2 = 2.0f32.powi(-111);
+        let f3 = 1.75 * 2.0f32.powi(-12);
         assert_eq!(f32::ldexp(1f32, -123), f1);
         assert_eq!(f32::ldexp(1f32, -111), f2);
         assert_eq!(f32::ldexp(1.75f32, -12), f3);
@@ -1734,11 +1722,9 @@ mod tests {
 
     #[test]
     fn test_frexp() {
-        // We have to use from_str until base-2 exponents
-        // are supported in floating-point literals
-        let f1: f32 = f32::from_str_radix("1p-123", 16).unwrap();
-        let f2: f32 = f32::from_str_radix("1p-111", 16).unwrap();
-        let f3: f32 = f32::from_str_radix("1.Cp-123", 16).unwrap();
+        let f1 = 2.0f32.powi(-123);
+        let f2 = 2.0f32.powi(-111);
+        let f3 = 1.75 * 2.0f32.powi(-123);
         let (x1, exp1) = f1.frexp();
         let (x2, exp2) = f2.frexp();
         let (x3, exp3) = f3.frexp();
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index 6b9c753443b..d444b259445 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -18,7 +18,7 @@
 use core::num;
 use intrinsics;
 use libc::c_int;
-use num::{FpCategory, ParseFloatError};
+use num::FpCategory;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON};
@@ -83,16 +83,6 @@ mod cmath {
 #[cfg(not(test))]
 #[lang = "f64"]
 impl f64 {
-    /// Parses a float as with a given radix
-    #[unstable(feature = "float_from_str_radix", reason = "recently moved API",
-               issue = "27736")]
-    #[rustc_deprecated(since = "1.4.0",
-                 reason = "unclear how useful or correct this is")]
-    #[allow(deprecated)]
-    pub fn from_str_radix(s: &str, radix: u32) -> Result<f64, ParseFloatError> {
-        num::Float::from_str_radix(s, radix)
-    }
-
     /// Returns `true` if this value is `NaN` and false otherwise.
     ///
     /// ```
@@ -1569,11 +1559,9 @@ mod tests {
 
     #[test]
     fn test_ldexp() {
-        // We have to use from_str until base-2 exponents
-        // are supported in floating-point literals
-        let f1: f64 = f64::from_str_radix("1p-123", 16).unwrap();
-        let f2: f64 = f64::from_str_radix("1p-111", 16).unwrap();
-        let f3: f64 = f64::from_str_radix("1.Cp-12", 16).unwrap();
+        let f1 = 2.0f64.powi(-123);
+        let f2 = 2.0f64.powi(-111);
+        let f3 = 1.75 * 2.0f64.powi(-12);
         assert_eq!(f64::ldexp(1f64, -123), f1);
         assert_eq!(f64::ldexp(1f64, -111), f2);
         assert_eq!(f64::ldexp(1.75f64, -12), f3);
@@ -1591,11 +1579,9 @@ mod tests {
 
     #[test]
     fn test_frexp() {
-        // We have to use from_str until base-2 exponents
-        // are supported in floating-point literals
-        let f1: f64 = f64::from_str_radix("1p-123", 16).unwrap();
-        let f2: f64 = f64::from_str_radix("1p-111", 16).unwrap();
-        let f3: f64 = f64::from_str_radix("1.Cp-123", 16).unwrap();
+        let f1 = 2.0f64.powi(-123);
+        let f2 = 2.0f64.powi(-111);
+        let f3 = 1.75 * 2.0f64.powi(-123);
         let (x1, exp1) = f1.frexp();
         let (x2, exp2) = f2.frexp();
         let (x3, exp3) = f3.frexp();
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index fd422d3b397..afeb4231aba 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -350,7 +350,7 @@ mod prim_slice { }
 /// ```
 ///
 /// [`.as_ptr()`]: #method.as_ptr
-/// [`len()`]: # method.len
+/// [`len()`]: #method.len
 mod prim_str { }
 
 #[doc(primitive = "tuple")]
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index 7ef504fba81..5e0368f35cc 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -16,7 +16,10 @@ use os::raw::{c_int, c_uint, c_ulong, c_long, c_longlong, c_ushort};
 use os::raw::{c_char, c_short, c_ulonglong};
 use libc::{wchar_t, size_t, c_void};
 use ptr;
-use simd;
+
+#[cfg_attr(not(stage0), repr(simd))]
+#[repr(C)]
+struct u64x2(u64, u64);
 
 pub use self::GET_FILEEX_INFO_LEVELS::*;
 pub use self::FILE_INFO_BY_HANDLE_CLASS::*;
@@ -783,7 +786,7 @@ pub struct FLOATING_SAVE_AREA {
 #[cfg(target_arch = "x86_64")]
 #[repr(C)]
 pub struct CONTEXT {
-    _align_hack: [simd::u64x2; 0], // FIXME align on 16-byte
+    _align_hack: [u64x2; 0], // FIXME align on 16-byte
     pub P1Home: DWORDLONG,
     pub P2Home: DWORDLONG,
     pub P3Home: DWORDLONG,
@@ -843,7 +846,7 @@ pub struct CONTEXT {
 #[cfg(target_arch = "x86_64")]
 #[repr(C)]
 pub struct M128A {
-    _align_hack: [simd::u64x2; 0], // FIXME align on 16-byte
+    _align_hack: [u64x2; 0], // FIXME align on 16-byte
     pub Low:  c_ulonglong,
     pub High: c_longlong
 }
@@ -851,7 +854,7 @@ pub struct M128A {
 #[cfg(target_arch = "x86_64")]
 #[repr(C)]
 pub struct FLOATING_SAVE_AREA {
-    _align_hack: [simd::u64x2; 0], // FIXME align on 16-byte
+    _align_hack: [u64x2; 0], // FIXME align on 16-byte
     _Dummy: [u8; 512] // FIXME: Fill this out
 }
 
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index 119429cc584..870247f7e82 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -13,6 +13,7 @@
 #![unstable(feature = "thread_local_internals", issue = "0")]
 
 use cell::UnsafeCell;
+use mem;
 
 // Sure wish we had macro hygiene, no?
 #[doc(hidden)]
@@ -226,7 +227,21 @@ impl<T: 'static> LocalKey<T> {
         // just in case initialization fails.
         let value = (self.init)();
         let ptr = slot.get();
-        *ptr = Some(value);
+
+        // note that this can in theory just be `*ptr = Some(value)`, but due to
+        // the compiler will currently codegen that pattern with something like:
+        //
+        //      ptr::drop_in_place(ptr)
+        //      ptr::write(ptr, Some(value))
+        //
+        // Due to this pattern it's possible for the destructor of the value in
+        // `ptr` (e.g. if this is being recursively initialized) to re-access
+        // TLS, in which case there will be a `&` and `&mut` pointer to the same
+        // value (an aliasing violation). To avoid setting the "I'm running a
+        // destructor" flag we just use `mem::replace` which should sequence the
+        // operations a little differently and make this safe to call.
+        mem::replace(&mut *ptr, Some(value));
+
         (*ptr).as_ref().unwrap()
     }
 
diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs
deleted file mode 100644
index 21ac23253c8..00000000000
--- a/src/test/bench/shootout-mandelbrot.rs
+++ /dev/null
@@ -1,209 +0,0 @@
-// The Computer Language Benchmarks Game
-// http://benchmarksgame.alioth.debian.org/
-//
-// contributed by the Rust Project Developers
-
-// Copyright (c) 2012-2014 The Rust Project Developers
-//
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// - Redistributions of source code must retain the above copyright
-//   notice, this list of conditions and the following disclaimer.
-//
-// - Redistributions in binary form must reproduce the above copyright
-//   notice, this list of conditions and the following disclaimer in
-//   the documentation and/or other materials provided with the
-//   distribution.
-//
-// - Neither the name of "The Computer Language Benchmarks Game" nor
-//   the name of "The Computer Language Shootout Benchmarks" nor the
-//   names of its contributors may be used to endorse or promote
-//   products derived from this software without specific prior
-//   written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-// OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#![feature(core_simd, core)]
-
-// ignore-pretty very bad with line comments
-
-use std::env;
-use std::io::prelude::*;
-use std::io;
-use std::simd::f64x2;
-use std::sync::Arc;
-use std::thread;
-
-const ITER: usize = 50;
-const LIMIT: f64 = 2.0;
-const WORKERS: usize = 16;
-
-fn mandelbrot<W: Write>(w: usize, mut out: W) -> io::Result<()> {
-    assert_eq!(WORKERS % 2, 0);
-
-    // Ensure w and h are multiples of 8.
-    let w = (w + 7) / 8 * 8;
-    let h = w;
-
-    let chunk_size = h / WORKERS;
-
-    // Account for remainders in workload division, e.g. 1000 / 16 = 62.5
-    let last_chunk_size = if h % WORKERS != 0 {
-        chunk_size + h % WORKERS
-    } else {
-        chunk_size
-    };
-
-    // precalc values
-    let inverse_w_doubled = 2.0 / w as f64;
-    let inverse_h_doubled = 2.0 / h as f64;
-    let v_inverses = f64x2(inverse_w_doubled, inverse_h_doubled);
-    let v_consts = f64x2(1.5, 1.0);
-
-    // A lot of this code assumes this (so do other lang benchmarks)
-    assert_eq!(w, h);
-    let mut precalc_r = Vec::with_capacity(w);
-    let mut precalc_i = Vec::with_capacity(h);
-
-    let precalc_futures = (0..WORKERS).map(|i| {
-        thread::spawn(move|| {
-            let mut rs = Vec::with_capacity(w / WORKERS);
-            let mut is = Vec::with_capacity(w / WORKERS);
-
-            let start = i * chunk_size;
-            let end = if i == (WORKERS - 1) {
-                start + last_chunk_size
-            } else {
-                (i + 1) * chunk_size
-            };
-
-            // This assumes w == h
-            for x in start..end {
-                let xf = x as f64;
-                let xy = f64x2(xf, xf);
-
-                let f64x2(r, i) = xy * v_inverses - v_consts;
-                rs.push(r);
-                is.push(i);
-            }
-
-            (rs, is)
-        })
-    }).collect::<Vec<_>>();
-
-    for res in precalc_futures {
-        let (rs, is) = res.join().unwrap();
-        precalc_r.extend(rs);
-        precalc_i.extend(is);
-    }
-
-    assert_eq!(precalc_r.len(), w);
-    assert_eq!(precalc_i.len(), h);
-
-    let arc_init_r = Arc::new(precalc_r);
-    let arc_init_i = Arc::new(precalc_i);
-
-    let data = (0..WORKERS).map(|i| {
-        let vec_init_r = arc_init_r.clone();
-        let vec_init_i = arc_init_i.clone();
-
-        thread::spawn(move|| {
-            let mut res: Vec<u8> = Vec::with_capacity((chunk_size * w) / 8);
-            let init_r_slice = vec_init_r;
-
-            let start = i * chunk_size;
-            let end = if i == (WORKERS - 1) {
-                start + last_chunk_size
-            } else {
-                (i + 1) * chunk_size
-            };
-
-            for &init_i in &vec_init_i[start..end] {
-                write_line(init_i, &init_r_slice, &mut res);
-            }
-
-            res
-        })
-    }).collect::<Vec<_>>();
-
-    try!(writeln!(&mut out, "P4\n{} {}", w, h));
-    for res in data {
-        try!(out.write_all(&res.join().unwrap()));
-    }
-    out.flush()
-}
-
-fn write_line(init_i: f64, vec_init_r: &[f64], res: &mut Vec<u8>) {
-    let v_init_i : f64x2 = f64x2(init_i, init_i);
-    let v_2 : f64x2 = f64x2(2.0, 2.0);
-    const LIMIT_SQUARED: f64 = LIMIT * LIMIT;
-
-    for chunk_init_r in vec_init_r.chunks(8) {
-        let mut cur_byte = 0xff;
-        let mut i = 0;
-
-        while i < 8 {
-            let v_init_r = f64x2(chunk_init_r[i], chunk_init_r[i + 1]);
-            let mut cur_r = v_init_r;
-            let mut cur_i = v_init_i;
-            let mut r_sq = v_init_r * v_init_r;
-            let mut i_sq = v_init_i * v_init_i;
-
-            let mut b = 0;
-            for _ in 0..ITER {
-                let r = cur_r;
-                let i = cur_i;
-
-                cur_i = v_2 * r * i + v_init_i;
-                cur_r = r_sq - i_sq + v_init_r;
-
-                let f64x2(bit1, bit2) = r_sq + i_sq;
-
-                if bit1 > LIMIT_SQUARED {
-                    b |= 2;
-                    if b == 3 { break; }
-                }
-
-                if bit2 > LIMIT_SQUARED {
-                    b |= 1;
-                    if b == 3 { break; }
-                }
-
-                r_sq = cur_r * cur_r;
-                i_sq = cur_i * cur_i;
-            }
-
-            cur_byte = (cur_byte << 2) + b;
-            i += 2;
-        }
-
-        res.push(cur_byte^!0);
-    }
-}
-
-fn main() {
-    let mut args = env::args();
-    let res = if args.len() < 2 {
-        println!("Test mode: do not dump the image because it's not utf8, \
-                  which interferes with the test runner.");
-        mandelbrot(1000, io::sink())
-    } else {
-        mandelbrot(args.nth(1).unwrap().parse().unwrap(), io::stdout())
-    };
-    res.unwrap();
-}
diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs
deleted file mode 100644
index a6c77eaf7c6..00000000000
--- a/src/test/bench/shootout-spectralnorm.rs
+++ /dev/null
@@ -1,123 +0,0 @@
-// The Computer Language Benchmarks Game
-// http://benchmarksgame.alioth.debian.org/
-//
-// contributed by the Rust Project Developers
-
-// Copyright (c) 2012-2014 The Rust Project Developers
-//
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// - Redistributions of source code must retain the above copyright
-//   notice, this list of conditions and the following disclaimer.
-//
-// - Redistributions in binary form must reproduce the above copyright
-//   notice, this list of conditions and the following disclaimer in
-//   the documentation and/or other materials provided with the
-//   distribution.
-//
-// - Neither the name of "The Computer Language Benchmarks Game" nor
-//   the name of "The Computer Language Shootout Benchmarks" nor the
-//   names of its contributors may be used to endorse or promote
-//   products derived from this software without specific prior
-//   written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-// OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// no-pretty-expanded FIXME #15189
-
-#![allow(non_snake_case)]
-#![feature(unboxed_closures, iter_arith, core_simd, scoped)]
-
-use std::thread;
-use std::env;
-use std::simd::f64x2;
-
-fn main() {
-    let mut args = env::args();
-    let answer = spectralnorm(if env::var_os("RUST_BENCH").is_some() {
-        5500
-    } else if args.len() < 2 {
-        2000
-    } else {
-        args.nth(1).unwrap().parse().unwrap()
-    });
-    println!("{:.9}", answer);
-}
-
-fn spectralnorm(n: usize) -> f64 {
-    assert!(n % 2 == 0, "only even lengths are accepted");
-    let mut u = vec![1.0; n];
-    let mut v = u.clone();
-    let mut tmp = v.clone();
-    for _ in 0..10 {
-        mult_AtAv(&u, &mut v, &mut tmp);
-        mult_AtAv(&v, &mut u, &mut tmp);
-    }
-    (dot(&u, &v) / dot(&v, &v)).sqrt()
-}
-
-fn mult_AtAv(v: &[f64], out: &mut [f64], tmp: &mut [f64]) {
-    mult_Av(v, tmp);
-    mult_Atv(tmp, out);
-}
-
-fn mult_Av(v: &[f64], out: &mut [f64]) {
-    parallel(out, |start, out| mult(v, out, start, |i, j| A(i, j)));
-}
-
-fn mult_Atv(v: &[f64], out: &mut [f64]) {
-    parallel(out, |start, out| mult(v, out, start, |i, j| A(j, i)));
-}
-
-fn mult<F>(v: &[f64], out: &mut [f64], start: usize, a: F)
-           where F: Fn(usize, usize) -> f64 {
-    for (i, slot) in out.iter_mut().enumerate().map(|(i, s)| (i + start, s)) {
-        let mut sum = f64x2(0.0, 0.0);
-        for (j, chunk) in v.chunks(2).enumerate().map(|(j, s)| (2 * j, s)) {
-            let top = f64x2(chunk[0], chunk[1]);
-            let bot = f64x2(a(i, j), a(i, j + 1));
-            sum = sum + top / bot;
-        }
-        let f64x2(a, b) = sum;
-        *slot = a + b;
-    }
-}
-
-fn A(i: usize, j: usize) -> f64 {
-    ((i + j) * (i + j + 1) / 2 + i + 1) as f64
-}
-
-fn dot(v: &[f64], u: &[f64]) -> f64 {
-    v.iter().zip(u).map(|(a, b)| *a * *b).sum()
-}
-
-
-// Executes a closure in parallel over the given mutable slice. The closure `f`
-// is run in parallel and yielded the starting index within `v` as well as a
-// sub-slice of `v`.
-fn parallel<'a,T, F>(v: &mut [T], ref f: F)
-                  where T: Send + Sync + 'a,
-                        F: Fn(usize, &mut [T]) + Sync + 'a {
-    // FIXME: pick a more appropriate parallel factor
-    // FIXME: replace with thread::scoped when it exists again
-    let parallelism = 4;
-    let size = v.len() / parallelism + 1;
-    v.chunks_mut(size).enumerate().map(|(i, chunk)| {
-        f(i * size, chunk)
-    }).collect::<Vec<_>>();
-}
diff --git a/src/test/compile-fail/feature-gate-simd-ffi.rs b/src/test/compile-fail/feature-gate-simd-ffi.rs
index f7bd2fcbceb..31c055f229c 100644
--- a/src/test/compile-fail/feature-gate-simd-ffi.rs
+++ b/src/test/compile-fail/feature-gate-simd-ffi.rs
@@ -8,17 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(repr_simd, core_simd)]
-#![allow(dead_code, deprecated)]
+#![feature(repr_simd)]
+#![allow(dead_code)]
 
-use std::simd::f32x4;
-
-#[repr(simd)] #[derive(Copy, Clone)] #[repr(C)] struct LocalSimd(u8, u8);
+#[repr(simd)]
+#[derive(Copy, Clone)]
+#[repr(C)]
+struct LocalSimd(u8, u8);
 
 extern {
-    fn foo() -> f32x4; //~ ERROR use of SIMD type
-    fn bar(x: f32x4); //~ ERROR use of SIMD type
-
     fn baz() -> LocalSimd; //~ ERROR use of SIMD type
     fn qux(x: LocalSimd); //~ ERROR use of SIMD type
 }
diff --git a/src/test/compile-fail/issue-26656.rs b/src/test/compile-fail/issue-26656.rs
new file mode 100644
index 00000000000..e5fa65498de
--- /dev/null
+++ b/src/test/compile-fail/issue-26656.rs
@@ -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.
+
+// Issue #26656: Verify that trait objects cannot bypass dropck.
+
+// Using this instead of Fn etc. to take HRTB out of the equation.
+trait Trigger<B> { fn fire(&self, b: &mut B); }
+impl<B: Button> Trigger<B> for () {
+    fn fire(&self, b: &mut B) {
+        b.push();
+    }
+}
+
+// Still unsound Zook
+trait Button { fn push(&self); }
+struct Zook<B> { button: B, trigger: Box<Trigger<B>+'static> }
+
+impl<B> Drop for Zook<B> {
+    fn drop(&mut self) {
+        self.trigger.fire(&mut self.button);
+    }
+}
+
+// AND
+struct Bomb { usable: bool }
+impl Drop for Bomb { fn drop(&mut self) { self.usable = false; } }
+impl Bomb { fn activate(&self) { assert!(self.usable) } }
+
+enum B<'a> { HarmlessButton, BigRedButton(&'a Bomb) }
+impl<'a> Button for B<'a> {
+    fn push(&self) {
+        if let B::BigRedButton(borrowed) = *self {
+            borrowed.activate();
+        }
+    }
+}
+
+fn main() {
+    let (mut zook, ticking);
+    zook = Zook { button: B::HarmlessButton,
+                  trigger: Box::new(()) };
+    ticking = Bomb { usable: true };
+    zook.button = B::BigRedButton(&ticking);
+    //~^ ERROR `ticking` does not live long enough
+}
diff --git a/src/test/debuginfo/simd.rs b/src/test/debuginfo/simd.rs
index 24eb407612c..620e1a73b4d 100644
--- a/src/test/debuginfo/simd.rs
+++ b/src/test/debuginfo/simd.rs
@@ -43,9 +43,28 @@
 #![allow(unused_variables)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
-#![feature(core_simd)]
+#![feature(repr_simd)]
 
-use std::simd::{i8x16, i16x8,i32x4,i64x2,u8x16,u16x8,u32x4,u64x2,f32x4,f64x2};
+#[repr(simd)]
+struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8);
+#[repr(simd)]
+struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16);
+#[repr(simd)]
+struct i32x4(i32, i32, i32, i32);
+#[repr(simd)]
+struct i64x2(i64, i64);
+#[repr(simd)]
+struct u8x16(u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8);
+#[repr(simd)]
+struct u16x8(u16, u16, u16, u16, u16, u16, u16, u16);
+#[repr(simd)]
+struct u32x4(u32, u32, u32, u32);
+#[repr(simd)]
+struct u64x2(u64, u64);
+#[repr(simd)]
+struct f32x4(f32, f32, f32, f32);
+#[repr(simd)]
+struct f64x2(f64, f64);
 
 fn main() {
 
diff --git a/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs b/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs
index 405a3549cf1..562cfbe7a14 100644
--- a/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs
+++ b/src/test/run-pass/method-mut-self-modifies-mut-slice-lvalue.rs
@@ -12,8 +12,7 @@
 // type is `&mut [u8]`, passes in a pointer to the lvalue and not a
 // temporary. Issue #19147.
 
-
-#![feature(slice_bytes)]
+#![feature(clone_from_slice)]
 
 use std::slice;
 
@@ -23,7 +22,7 @@ trait MyWriter {
 
 impl<'a> MyWriter for &'a mut [u8] {
     fn my_write(&mut self, buf: &[u8]) -> Result<(), ()> {
-        slice::bytes::copy_memory(buf, *self);
+        self.clone_from_slice(buf);
 
         let write_len = buf.len();
         unsafe {
diff --git a/src/test/run-pass/simd-issue-10604.rs b/src/test/run-pass/simd-issue-10604.rs
deleted file mode 100644
index c3eef0f9c32..00000000000
--- a/src/test/run-pass/simd-issue-10604.rs
+++ /dev/null
@@ -1,17 +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.
-
-// pretty-expanded FIXME #23616
-
-#![feature(core_simd)]
-
-pub fn main() {
-    let _o = None::<std::simd::i32x4>;
-}
diff --git a/src/test/run-pass/sync-send-iterators-in-libcore.rs b/src/test/run-pass/sync-send-iterators-in-libcore.rs
index c4d070f8bfe..93178994815 100644
--- a/src/test/run-pass/sync-send-iterators-in-libcore.rs
+++ b/src/test/run-pass/sync-send-iterators-in-libcore.rs
@@ -14,11 +14,10 @@
 #![feature(iter_empty)]
 #![feature(iter_once)]
 #![feature(iter_unfold)]
-#![feature(range_inclusive)]
 #![feature(step_by)]
 #![feature(str_escape)]
 
-use std::iter::{empty, once, range_inclusive, repeat};
+use std::iter::{empty, once, repeat};
 
 fn is_sync<T>(_: T) where T: Sync {}
 fn is_send<T>(_: T) where T: Send {}
@@ -98,7 +97,6 @@ fn main() {
                    inspect(|_| ()));
 
     is_sync_send!((1..).step_by(2));
-    is_sync_send!(range_inclusive(1, 1));
     is_sync_send!((1..2).step_by(2));
     is_sync_send!((1..2));
     is_sync_send!((1..));
diff --git a/src/test/run-pass/tls-init-on-init.rs b/src/test/run-pass/tls-init-on-init.rs
new file mode 100644
index 00000000000..195b814492a
--- /dev/null
+++ b/src/test/run-pass/tls-init-on-init.rs
@@ -0,0 +1,51 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(thread_local_state)]
+
+use std::thread::{self, LocalKeyState};
+use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
+
+struct Foo { cnt: usize }
+
+thread_local!(static FOO: Foo = Foo::init());
+
+static CNT: AtomicUsize = ATOMIC_USIZE_INIT;
+
+impl Foo {
+    fn init() -> Foo {
+        let cnt = CNT.fetch_add(1, Ordering::SeqCst);
+        if cnt == 0 {
+            FOO.with(|_| {});
+        }
+        Foo { cnt: cnt }
+    }
+}
+
+impl Drop for Foo {
+    fn drop(&mut self) {
+        if self.cnt == 1 {
+            FOO.with(|foo| assert_eq!(foo.cnt, 0));
+        } else {
+            assert_eq!(self.cnt, 0);
+            match FOO.state() {
+                LocalKeyState::Valid => panic!("should not be in valid state"),
+                LocalKeyState::Uninitialized |
+                LocalKeyState::Destroyed => {}
+            }
+        }
+    }
+}
+
+fn main() {
+    thread::spawn(|| {
+        FOO.with(|_| {});
+    }).join().unwrap();
+}
diff --git a/src/test/run-pass/while-let.rs b/src/test/run-pass/while-let.rs
index efccff75a49..9ffba2c7999 100644
--- a/src/test/run-pass/while-let.rs
+++ b/src/test/run-pass/while-let.rs
@@ -14,7 +14,7 @@
 use std::collections::BinaryHeap;
 
 fn make_pq() -> BinaryHeap<isize> {
-    BinaryHeap::from_vec(vec![1,2,3])
+    BinaryHeap::from(vec![1,2,3])
 }
 
 pub fn main() {