about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-12-21 23:01:27 +0000
committerbors <bors@rust-lang.org>2017-12-21 23:01:27 +0000
commitba2741594ba2d4de2ad8cea69def6408ff5409af (patch)
tree2c17b5743bf95d61eef4f3c307bc2823520d768f
parent250b492052e94d76bd318a4b932159395da55981 (diff)
parent0787ad92614df48096dbb5cbd6f2cf7833c97293 (diff)
downloadrust-ba2741594ba2d4de2ad8cea69def6408ff5409af.tar.gz
rust-ba2741594ba2d4de2ad8cea69def6408ff5409af.zip
Auto merge of #46922 - kennytm:rollup, r=kennytm
Rollup of 14 pull requests

- Successful merges: #46636, #46780, #46784, #46809, #46814, #46820, #46839, #46847, #46858, #46878, #46884, #46890, #46898, #46918
- Failed merges:
-rw-r--r--CONTRIBUTING.md32
-rw-r--r--src/liballoc/vec.rs6
m---------src/libcompiler_builtins0
-rw-r--r--src/libcore/num/bignum.rs2
-rw-r--r--src/libcore/num/mod.rs219
-rw-r--r--src/libcore/ptr.rs12
-rw-r--r--src/libgraphviz/lib.rs83
-rw-r--r--src/librustc/ich/hcx.rs2
-rw-r--r--src/librustc/ich/impls_syntax.rs5
-rw-r--r--src/librustc/middle/expr_use_visitor.rs39
-rw-r--r--src/librustc/session/config.rs25
-rw-r--r--src/librustc/ty/layout.rs12
-rw-r--r--src/librustc_driver/driver.rs15
-rw-r--r--src/librustc_driver/lib.rs3
-rw-r--r--src/librustc_lint/builtin.rs22
-rw-r--r--src/librustc_metadata/decoder.rs2
-rw-r--r--src/librustc_metadata/encoder.rs7
-rw-r--r--src/librustc_mir/monomorphize/partitioning.rs11
-rw-r--r--src/librustdoc/html/render.rs7
-rw-r--r--src/librustdoc/test.rs4
-rw-r--r--src/libstd/io/buffered.rs2
-rw-r--r--src/libstd/time/duration.rs2
-rw-r--r--src/libsyntax/codemap.rs2
-rw-r--r--src/libsyntax/ext/expand.rs18
-rw-r--r--src/libsyntax_pos/lib.rs26
-rw-r--r--src/libtest/lib.rs50
-rw-r--r--src/test/COMPILER_TESTS.md46
-rw-r--r--src/test/compile-fail/external-doc-error.rs16
-rw-r--r--src/test/compile-fail/issue-46771.rs14
-rw-r--r--src/test/run-make/include_bytes_deps/Makefile2
-rw-r--r--src/test/run-make/include_bytes_deps/input.md1
-rw-r--r--src/test/run-make/include_bytes_deps/main.rs5
-rw-r--r--src/test/run-make/issue-19371/foo.rs2
-rw-r--r--src/test/run-make/output-filename-overwrites-input/Makefile10
-rw-r--r--src/test/run-make/output-filename-overwrites-input/foo.rs11
-rw-r--r--src/test/run-make/weird-output-filenames/Makefile4
-rw-r--r--src/test/run-pass/packed-struct-optimized-enum.rs13
-rw-r--r--src/test/rustdoc/auxiliary/external-cross.rs1
-rw-r--r--src/test/rustdoc/escape-deref-methods.rs45
-rw-r--r--src/tools/compiletest/src/main.rs2
40 files changed, 452 insertions, 328 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b8fea40090f..919d8329941 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -112,14 +112,17 @@ There are large number of options provided in this config file that will alter t
 configuration used in the build process. Some options to note:
 
 #### `[llvm]`:
+- `assertions = true` = This enables LLVM assertions, which makes LLVM misuse cause an assertion failure instead of weird misbehavior. This also slows down the compiler's runtime by ~20%.
 - `ccache = true` - Use ccache when building llvm
 
 #### `[build]`:
 - `compiler-docs = true` - Build compiler documentation
 
 #### `[rust]`:
-- `debuginfo = true` - Build a compiler with debuginfo
-- `optimize = false` - Disable optimizations to speed up compilation of stage1 rust
+- `debuginfo = true` - Build a compiler with debuginfo. Makes building rustc slower, but then you can use a debugger to debug `rustc`.
+- `debuginfo-lines = true` - An alternative to `debuginfo = true` that doesn't let you use a debugger, but doesn't make building rustc slower and still gives you line numbers in backtraces.
+- `debug-assertions = true` - Makes the log output of `debug!` work.
+- `optimize = false` - Disable optimizations to speed up compilation of stage1 rust, but makes the stage1 compiler x100 slower.
 
 For more options, the `config.toml` file contains commented out defaults, with
 descriptions of what each option will do.
@@ -273,6 +276,27 @@ build, you'll need to build rustdoc specially, since it's not normally built in
 stage 1. `python x.py build --stage 1 src/libstd src/tools/rustdoc` will build
 rustdoc and libstd, which will allow rustdoc to be run with that toolchain.)
 
+### Out-of-tree builds
+[out-of-tree-builds]: #out-of-tree-builds
+
+Rust's `x.py` script fully supports out-of-tree builds - it looks for
+the Rust source code from the directory `x.py` was found in, but it
+reads the `config.toml` configuration file from the directory it's
+run in, and places all build artifacts within a subdirectory named `build`.
+
+This means that if you want to do an out-of-tree build, you can just do it:
+```
+$ cd my/build/dir
+$ cp ~/my-config.toml config.toml # Or fill in config.toml otherwise
+$ path/to/rust/x.py build
+...
+$ # This will use the Rust source code in `path/to/rust`, but build
+$ # artifacts will now be in ./build
+```
+
+It's absolutely fine to have multiple build directories with different
+`config.toml` configurations using the same code.
+
 ## Pull Requests
 [pull-requests]: #pull-requests
 
@@ -446,14 +470,14 @@ failed to run: ~/rust/build/x86_64-unknown-linux-gnu/stage0/bin/cargo build --ma
 If you haven't used the `[patch]`
 section of `Cargo.toml` before, there is [some relevant documentation about it
 in the cargo docs](http://doc.crates.io/manifest.html#the-patch-section). In
-addition to that, you should read the 
+addition to that, you should read the
 [Overriding dependencies](http://doc.crates.io/specifying-dependencies.html#overriding-dependencies)
 section of the documentation as well.
 
 Specifically, the following [section in Overriding dependencies](http://doc.crates.io/specifying-dependencies.html#testing-a-bugfix) reveals what the problem is:
 
 > Next up we need to ensure that our lock file is updated to use this new version of uuid so our project uses the locally checked out copy instead of one from crates.io. The way [patch] works is that it'll load the dependency at ../path/to/uuid and then whenever crates.io is queried for versions of uuid it'll also return the local version.
-> 
+>
 > This means that the version number of the local checkout is significant and will affect whether the patch is used. Our manifest declared uuid = "1.0" which means we'll only resolve to >= 1.0.0, < 2.0.0, and Cargo's greedy resolution algorithm also means that we'll resolve to the maximum version within that range. Typically this doesn't matter as the version of the git repository will already be greater or match the maximum version published on crates.io, but it's important to keep this in mind!
 
 This says that when we updated the submodule, the version number in our
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 67ccb5cab6d..93d7e66b7b2 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -224,8 +224,10 @@ use Bound::{Excluded, Included, Unbounded};
 /// types inside a `Vec`, it will not allocate space for them. *Note that in this case
 /// the `Vec` may not report a [`capacity`] of 0*. `Vec` will allocate if and only
 /// if [`mem::size_of::<T>`]`() * capacity() > 0`. In general, `Vec`'s allocation
-/// details are subtle enough that it is strongly recommended that you only
-/// free memory allocated by a `Vec` by creating a new `Vec` and dropping it.
+/// details are very subtle &mdash; if you intend to allocate memory using a `Vec`
+/// and use it for something else (either to pass to unsafe code, or to build your
+/// own memory-backed collection), be sure to deallocate this memory by using
+/// `from_raw_parts` to recover the `Vec` and then dropping it.
 ///
 /// If a `Vec` *has* allocated memory, then the memory it points to is on the heap
 /// (as defined by the allocator Rust is configured to use by default), and its
diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins
-Subproject 18feaccbfd0dfbd5ab5d0a2a6eac9c04be66726
+Subproject 000d06a57a622eb4db4a15d0f76db48571f4d8e
diff --git a/src/libcore/num/bignum.rs b/src/libcore/num/bignum.rs
index b5553fb2947..732a02e8c42 100644
--- a/src/libcore/num/bignum.rs
+++ b/src/libcore/num/bignum.rs
@@ -114,7 +114,7 @@ macro_rules! define_bignum {
         /// copying it recklessly may result in the performance hit.
         /// Thus this is intentionally not `Copy`.
         ///
-        /// All operations available to bignums panic in the case of over/underflows.
+        /// All operations available to bignums panic in the case of overflows.
         /// The caller is responsible to use large enough bignum types.
         pub struct $name {
             /// One plus the offset to the maximum "digit" in use.
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 245ca83f28f..851c0a0dd6f 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -98,10 +98,7 @@ pub mod diy_float;
 
 // `Int` + `SignedInt` implemented for signed integers
 macro_rules! int_impl {
-    ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr,
-     $add_with_overflow:path,
-     $sub_with_overflow:path,
-     $mul_with_overflow:path) => {
+    ($SelfT:ty, $ActualT:ident, $UnsignedT:ty, $BITS:expr) => {
         /// Returns the smallest value that can be represented by this integer type.
         ///
         /// # Examples
@@ -402,7 +399,7 @@ macro_rules! int_impl {
         }
 
         /// Checked integer subtraction. Computes `self - rhs`, returning
-        /// `None` if underflow occurred.
+        /// `None` if overflow occurred.
         ///
         /// # Examples
         ///
@@ -420,7 +417,7 @@ macro_rules! int_impl {
         }
 
         /// Checked integer multiplication. Computes `self * rhs`, returning
-        /// `None` if underflow or overflow occurred.
+        /// `None` if overflow occurred.
         ///
         /// # Examples
         ///
@@ -438,7 +435,7 @@ macro_rules! int_impl {
         }
 
         /// Checked integer division. Computes `self / rhs`, returning `None`
-        /// if `rhs == 0` or the operation results in underflow or overflow.
+        /// if `rhs == 0` or the operation results in overflow.
         ///
         /// # Examples
         ///
@@ -460,7 +457,7 @@ macro_rules! int_impl {
         }
 
         /// Checked integer remainder. Computes `self % rhs`, returning `None`
-        /// if `rhs == 0` or the operation results in underflow or overflow.
+        /// if `rhs == 0` or the operation results in overflow.
         ///
         /// # Examples
         ///
@@ -865,11 +862,11 @@ macro_rules! int_impl {
         #[inline]
         #[stable(feature = "wrapping", since = "1.7.0")]
         pub fn overflowing_add(self, rhs: Self) -> (Self, bool) {
-            unsafe {
-                let (a, b) = $add_with_overflow(self as $ActualT,
-                                                rhs as $ActualT);
-                (a as Self, b)
-            }
+            let (a, b) = unsafe {
+                intrinsics::add_with_overflow(self as $ActualT,
+                                              rhs as $ActualT)
+            };
+            (a as Self, b)
         }
 
         /// Calculates `self` - `rhs`
@@ -891,11 +888,11 @@ macro_rules! int_impl {
         #[inline]
         #[stable(feature = "wrapping", since = "1.7.0")]
         pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
-            unsafe {
-                let (a, b) = $sub_with_overflow(self as $ActualT,
-                                                rhs as $ActualT);
-                (a as Self, b)
-            }
+            let (a, b) = unsafe {
+                intrinsics::sub_with_overflow(self as $ActualT,
+                                              rhs as $ActualT)
+            };
+            (a as Self, b)
         }
 
         /// Calculates the multiplication of `self` and `rhs`.
@@ -915,11 +912,11 @@ macro_rules! int_impl {
         #[inline]
         #[stable(feature = "wrapping", since = "1.7.0")]
         pub fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
-            unsafe {
-                let (a, b) = $mul_with_overflow(self as $ActualT,
-                                                rhs as $ActualT);
-                (a as Self, b)
-            }
+            let (a, b) = unsafe {
+                intrinsics::mul_with_overflow(self as $ActualT,
+                                              rhs as $ActualT)
+            };
+            (a as Self, b)
         }
 
         /// Calculates the divisor when `self` is divided by `rhs`.
@@ -1207,82 +1204,50 @@ macro_rules! int_impl {
 
 #[lang = "i8"]
 impl i8 {
-    int_impl! { i8, i8, u8, 8,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    int_impl! { i8, i8, u8, 8 }
 }
 
 #[lang = "i16"]
 impl i16 {
-    int_impl! { i16, i16, u16, 16,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    int_impl! { i16, i16, u16, 16 }
 }
 
 #[lang = "i32"]
 impl i32 {
-    int_impl! { i32, i32, u32, 32,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    int_impl! { i32, i32, u32, 32 }
 }
 
 #[lang = "i64"]
 impl i64 {
-    int_impl! { i64, i64, u64, 64,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    int_impl! { i64, i64, u64, 64 }
 }
 
 #[lang = "i128"]
 impl i128 {
-    int_impl! { i128, i128, u128, 128,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    int_impl! { i128, i128, u128, 128 }
 }
 
 #[cfg(target_pointer_width = "16")]
 #[lang = "isize"]
 impl isize {
-    int_impl! { isize, i16, u16, 16,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    int_impl! { isize, i16, u16, 16 }
 }
 
 #[cfg(target_pointer_width = "32")]
 #[lang = "isize"]
 impl isize {
-    int_impl! { isize, i32, u32, 32,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    int_impl! { isize, i32, u32, 32 }
 }
 
 #[cfg(target_pointer_width = "64")]
 #[lang = "isize"]
 impl isize {
-    int_impl! { isize, i64, u64, 64,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    int_impl! { isize, i64, u64, 64 }
 }
 
 // `Int` + `UnsignedInt` implemented for unsigned integers
 macro_rules! uint_impl {
-    ($SelfT:ty, $ActualT:ty, $BITS:expr,
-     $ctpop:path,
-     $ctlz:path,
-     $ctlz_nonzero:path,
-     $cttz:path,
-     $bswap:path,
-     $add_with_overflow:path,
-     $sub_with_overflow:path,
-     $mul_with_overflow:path) => {
+    ($SelfT:ty, $ActualT:ty, $BITS:expr) => {
         /// Returns the smallest value that can be represented by this integer type.
         ///
         /// # Examples
@@ -1346,7 +1311,7 @@ macro_rules! uint_impl {
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
         pub fn count_ones(self) -> u32 {
-            unsafe { $ctpop(self as $ActualT) as u32 }
+            unsafe { intrinsics::ctpop(self as $ActualT) as u32 }
         }
 
         /// Returns the number of zeros in the binary representation of `self`.
@@ -1381,7 +1346,7 @@ macro_rules! uint_impl {
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
         pub fn leading_zeros(self) -> u32 {
-            unsafe { $ctlz(self as $ActualT) as u32 }
+            unsafe { intrinsics::ctlz(self as $ActualT) as u32 }
         }
 
         /// Returns the number of trailing zeros in the binary representation
@@ -1480,7 +1445,7 @@ macro_rules! uint_impl {
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
         pub fn swap_bytes(self) -> Self {
-            unsafe { $bswap(self as $ActualT) as Self }
+            unsafe { intrinsics::bswap(self as $ActualT) as Self }
         }
 
         /// Converts an integer from big endian to the target's endianness.
@@ -1598,7 +1563,7 @@ macro_rules! uint_impl {
         }
 
         /// Checked integer subtraction. Computes `self - rhs`, returning
-        /// `None` if underflow occurred.
+        /// `None` if overflow occurred.
         ///
         /// # Examples
         ///
@@ -1616,7 +1581,7 @@ macro_rules! uint_impl {
         }
 
         /// Checked integer multiplication. Computes `self * rhs`, returning
-        /// `None` if underflow or overflow occurred.
+        /// `None` if overflow occurred.
         ///
         /// # Examples
         ///
@@ -1634,7 +1599,7 @@ macro_rules! uint_impl {
         }
 
         /// Checked integer division. Computes `self / rhs`, returning `None`
-        /// if `rhs == 0` or the operation results in underflow or overflow.
+        /// if `rhs == 0` or the operation results in overflow.
         ///
         /// # Examples
         ///
@@ -1654,7 +1619,7 @@ macro_rules! uint_impl {
         }
 
         /// Checked integer remainder. Computes `self % rhs`, returning `None`
-        /// if `rhs == 0` or the operation results in underflow or overflow.
+        /// if `rhs == 0` or the operation results in overflow.
         ///
         /// # Examples
         ///
@@ -1984,11 +1949,11 @@ macro_rules! uint_impl {
         #[inline]
         #[stable(feature = "wrapping", since = "1.7.0")]
         pub fn overflowing_add(self, rhs: Self) -> (Self, bool) {
-            unsafe {
-                let (a, b) = $add_with_overflow(self as $ActualT,
-                                                rhs as $ActualT);
-                (a as Self, b)
-            }
+            let (a, b) = unsafe {
+                intrinsics::add_with_overflow(self as $ActualT,
+                                              rhs as $ActualT)
+            };
+            (a as Self, b)
         }
 
         /// Calculates `self` - `rhs`
@@ -2010,11 +1975,11 @@ macro_rules! uint_impl {
         #[inline]
         #[stable(feature = "wrapping", since = "1.7.0")]
         pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
-            unsafe {
-                let (a, b) = $sub_with_overflow(self as $ActualT,
-                                                rhs as $ActualT);
-                (a as Self, b)
-            }
+            let (a, b) = unsafe {
+                intrinsics::sub_with_overflow(self as $ActualT,
+                                              rhs as $ActualT)
+            };
+            (a as Self, b)
         }
 
         /// Calculates the multiplication of `self` and `rhs`.
@@ -2034,11 +1999,11 @@ macro_rules! uint_impl {
         #[inline]
         #[stable(feature = "wrapping", since = "1.7.0")]
         pub fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
-            unsafe {
-                let (a, b) = $mul_with_overflow(self as $ActualT,
-                                                rhs as $ActualT);
-                (a as Self, b)
-            }
+            let (a, b) = unsafe {
+                intrinsics::mul_with_overflow(self as $ActualT,
+                                              rhs as $ActualT)
+            };
+            (a as Self, b)
         }
 
         /// Calculates the divisor when `self` is divided by `rhs`.
@@ -2223,7 +2188,7 @@ macro_rules! uint_impl {
             // (such as intel pre-haswell) have more efficient ctlz
             // intrinsics when the argument is non-zero.
             let p = self - 1;
-            let z = unsafe { $ctlz_nonzero(p) };
+            let z = unsafe { intrinsics::ctlz_nonzero(p) };
             <$SelfT>::max_value() >> z
         }
 
@@ -2270,15 +2235,7 @@ macro_rules! uint_impl {
 
 #[lang = "u8"]
 impl u8 {
-    uint_impl! { u8, u8, 8,
-        intrinsics::ctpop,
-        intrinsics::ctlz,
-        intrinsics::ctlz_nonzero,
-        intrinsics::cttz,
-        intrinsics::bswap,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    uint_impl! { u8, u8, 8 }
 
 
     /// Checks if the value is within the ASCII range.
@@ -2824,95 +2781,39 @@ impl u8 {
 
 #[lang = "u16"]
 impl u16 {
-    uint_impl! { u16, u16, 16,
-        intrinsics::ctpop,
-        intrinsics::ctlz,
-        intrinsics::ctlz_nonzero,
-        intrinsics::cttz,
-        intrinsics::bswap,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    uint_impl! { u16, u16, 16 }
 }
 
 #[lang = "u32"]
 impl u32 {
-    uint_impl! { u32, u32, 32,
-        intrinsics::ctpop,
-        intrinsics::ctlz,
-        intrinsics::ctlz_nonzero,
-        intrinsics::cttz,
-        intrinsics::bswap,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    uint_impl! { u32, u32, 32 }
 }
 
 #[lang = "u64"]
 impl u64 {
-    uint_impl! { u64, u64, 64,
-        intrinsics::ctpop,
-        intrinsics::ctlz,
-        intrinsics::ctlz_nonzero,
-        intrinsics::cttz,
-        intrinsics::bswap,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    uint_impl! { u64, u64, 64 }
 }
 
 #[lang = "u128"]
 impl u128 {
-    uint_impl! { u128, u128, 128,
-        intrinsics::ctpop,
-        intrinsics::ctlz,
-        intrinsics::ctlz_nonzero,
-        intrinsics::cttz,
-        intrinsics::bswap,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    uint_impl! { u128, u128, 128 }
 }
 
 #[cfg(target_pointer_width = "16")]
 #[lang = "usize"]
 impl usize {
-    uint_impl! { usize, u16, 16,
-        intrinsics::ctpop,
-        intrinsics::ctlz,
-        intrinsics::ctlz_nonzero,
-        intrinsics::cttz,
-        intrinsics::bswap,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    uint_impl! { usize, u16, 16 }
 }
 #[cfg(target_pointer_width = "32")]
 #[lang = "usize"]
 impl usize {
-    uint_impl! { usize, u32, 32,
-        intrinsics::ctpop,
-        intrinsics::ctlz,
-        intrinsics::ctlz_nonzero,
-        intrinsics::cttz,
-        intrinsics::bswap,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    uint_impl! { usize, u32, 32 }
 }
 
 #[cfg(target_pointer_width = "64")]
 #[lang = "usize"]
 impl usize {
-    uint_impl! { usize, u64, 64,
-        intrinsics::ctpop,
-        intrinsics::ctlz,
-        intrinsics::ctlz_nonzero,
-        intrinsics::cttz,
-        intrinsics::bswap,
-        intrinsics::add_with_overflow,
-        intrinsics::sub_with_overflow,
-        intrinsics::mul_with_overflow }
+    uint_impl! { usize, u64, 64 }
 }
 
 /// A classification of floating point numbers.
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 39cf2ec4c21..85bdeae442b 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -581,8 +581,7 @@ impl<T: ?Sized> *const T {
     /// * Both the starting and resulting pointer must be either in bounds or one
     ///   byte past the end of an allocated object.
     ///
-    /// * The computed offset, **in bytes**, cannot overflow or underflow an
-    ///   `isize`.
+    /// * The computed offset, **in bytes**, cannot overflow an `isize`.
     ///
     /// * The offset being in bounds cannot rely on "wrapping around" the address
     ///   space. That is, the infinite-precision sum, **in bytes** must fit in a usize.
@@ -714,8 +713,7 @@ impl<T: ?Sized> *const T {
     /// * Both the starting and resulting pointer must be either in bounds or one
     ///   byte past the end of an allocated object.
     ///
-    /// * The computed offset, **in bytes**, cannot overflow or underflow an
-    ///   `isize`.
+    /// * The computed offset, **in bytes**, cannot overflow an `isize`.
     ///
     /// * The offset being in bounds cannot rely on "wrapping around" the address
     ///   space. That is, the infinite-precision sum must fit in a `usize`.
@@ -1219,8 +1217,7 @@ impl<T: ?Sized> *mut T {
     /// * Both the starting and resulting pointer must be either in bounds or one
     ///   byte past the end of an allocated object.
     ///
-    /// * The computed offset, **in bytes**, cannot overflow or underflow an
-    ///   `isize`.
+    /// * The computed offset, **in bytes**, cannot overflow an `isize`.
     ///
     /// * The offset being in bounds cannot rely on "wrapping around" the address
     ///   space. That is, the infinite-precision sum, **in bytes** must fit in a usize.
@@ -1419,8 +1416,7 @@ impl<T: ?Sized> *mut T {
     /// * Both the starting and resulting pointer must be either in bounds or one
     ///   byte past the end of an allocated object.
     ///
-    /// * The computed offset, **in bytes**, cannot overflow or underflow an
-    ///   `isize`.
+    /// * The computed offset, **in bytes**, cannot overflow an `isize`.
     ///
     /// * The offset being in bounds cannot rely on "wrapping around" the address
     ///   space. That is, the infinite-precision sum must fit in a `usize`.
diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs
index 5b1cf2dee9a..110493bbec1 100644
--- a/src/libgraphviz/lib.rs
+++ b/src/libgraphviz/lib.rs
@@ -413,27 +413,14 @@ impl<'a> Id<'a> {
     /// quotes, ...) will return an empty `Err` value.
     pub fn new<Name: IntoCow<'a, str>>(name: Name) -> Result<Id<'a>, ()> {
         let name = name.into_cow();
-        {
-            let mut chars = name.chars();
-            match chars.next() {
-                Some(c) if is_letter_or_underscore(c) => {}
-                _ => return Err(()),
-            }
-            if !chars.all(is_constituent) {
-                return Err(());
-            }
-        }
-        return Ok(Id { name: name });
-
-        fn is_letter_or_underscore(c: char) -> bool {
-            in_range('a', c, 'z') || in_range('A', c, 'Z') || c == '_'
-        }
-        fn is_constituent(c: char) -> bool {
-            is_letter_or_underscore(c) || in_range('0', c, '9')
+        match name.chars().next() {
+            Some(c) if c.is_ascii_alphabetic() || c == '_' => {}
+            _ => return Err(()),
         }
-        fn in_range(low: char, c: char, high: char) -> bool {
-            low as usize <= c as usize && c as usize <= high as usize
+        if !name.chars().all(|c| c.is_ascii_alphanumeric() || c == '_' ) {
+            return Err(());
         }
+        return Ok(Id { name: name });
     }
 
     pub fn as_slice(&'a self) -> &'a str {
@@ -484,8 +471,7 @@ pub trait Labeller<'a> {
     /// Maps `e` to a label that will be used in the rendered output.
     /// The label need not be unique, and may be the empty string; the
     /// default is in fact the empty string.
-    fn edge_label(&'a self, e: &Self::Edge) -> LabelText<'a> {
-        let _ignored = e;
+    fn edge_label(&'a self, _e: &Self::Edge) -> LabelText<'a> {
         LabelStr("".into_cow())
     }
 
@@ -655,79 +641,58 @@ pub fn render_opts<'a, N, E, G, W>(g: &'a G,
           G: Labeller<'a, Node=N, Edge=E> + GraphWalk<'a, Node=N, Edge=E>,
           W: Write
 {
-    fn writeln<W: Write>(w: &mut W, arg: &[&str]) -> io::Result<()> {
-        for &s in arg {
-            w.write_all(s.as_bytes())?;
-        }
-        write!(w, "\n")
-    }
-
-    fn indent<W: Write>(w: &mut W) -> io::Result<()> {
-        w.write_all(b"    ")
-    }
-
-    writeln(w, &["digraph ", g.graph_id().as_slice(), " {"])?;
+    writeln!(w, "digraph {} {{", g.graph_id().as_slice())?;
     for n in g.nodes().iter() {
-        indent(w)?;
+        write!(w, "    ")?;
         let id = g.node_id(n);
 
         let escaped = &g.node_label(n).to_dot_string();
-        let shape;
 
-        let mut text = vec![id.as_slice()];
+        let mut text = Vec::new();
+        write!(text, "{}", id.as_slice()).unwrap();
 
         if !options.contains(&RenderOption::NoNodeLabels) {
-            text.push("[label=");
-            text.push(escaped);
-            text.push("]");
+            write!(text, "[label={}]", escaped).unwrap();
         }
 
         let style = g.node_style(n);
         if !options.contains(&RenderOption::NoNodeStyles) && style != Style::None {
-            text.push("[style=\"");
-            text.push(style.as_slice());
-            text.push("\"]");
+            write!(text, "[style=\"{}\"]", style.as_slice()).unwrap();
         }
 
         if let Some(s) = g.node_shape(n) {
-            shape = s.to_dot_string();
-            text.push("[shape=");
-            text.push(&shape);
-            text.push("]");
+            write!(text, "[shape={}]", &s.to_dot_string()).unwrap();
         }
 
-        text.push(";");
-        writeln(w, &text)?;
+        writeln!(text, ";").unwrap();
+        w.write_all(&text[..])?;
     }
 
     for e in g.edges().iter() {
         let escaped_label = &g.edge_label(e).to_dot_string();
-        indent(w)?;
+        write!(w, "    ")?;
         let source = g.source(e);
         let target = g.target(e);
         let source_id = g.node_id(&source);
         let target_id = g.node_id(&target);
 
-        let mut text = vec![source_id.as_slice(), " -> ", target_id.as_slice()];
+        let mut text = Vec::new();
+        write!(text, "{} -> {}", source_id.as_slice(), target_id.as_slice()).unwrap();
 
         if !options.contains(&RenderOption::NoEdgeLabels) {
-            text.push("[label=");
-            text.push(escaped_label);
-            text.push("]");
+            write!(text, "[label={}]", escaped_label).unwrap();
         }
 
         let style = g.edge_style(e);
         if !options.contains(&RenderOption::NoEdgeStyles) && style != Style::None {
-            text.push("[style=\"");
-            text.push(style.as_slice());
-            text.push("\"]");
+            write!(text, "[style=\"{}\"]", style.as_slice()).unwrap();
         }
 
-        text.push(";");
-        writeln(w, &text)?;
+        writeln!(text, ";").unwrap();
+        w.write_all(&text[..])?;
     }
 
-    writeln(w, &["}"])
+    writeln!(w, "}}")
 }
 
 pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
index 7099b951129..2945b1ab912 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc/ich/hcx.rs
@@ -341,7 +341,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Span {
         std_hash::Hash::hash(&TAG_VALID_SPAN, hasher);
         // We truncate the stable_id hash and line and col numbers. The chances
         // of causing a collision this way should be minimal.
-        std_hash::Hash::hash(&file_lo.name, hasher);
+        std_hash::Hash::hash(&(file_lo.name_hash as u64), hasher);
 
         let col = (col_lo.0 as u64) & 0xFF;
         let line = ((line_lo as u64) & 0xFF_FF_FF) << 8;
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index c25aa10eb1e..57120d61e7c 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -387,7 +387,8 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for FileMap {
                                           hcx: &mut StableHashingContext<'gcx>,
                                           hasher: &mut StableHasher<W>) {
         let FileMap {
-            ref name,
+            name: _, // We hash the smaller name_hash instead of this
+            name_hash,
             name_was_remapped,
             unmapped_path: _,
             crate_of_origin,
@@ -402,7 +403,7 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for FileMap {
             ref non_narrow_chars,
         } = *self;
 
-        name.hash_stable(hcx, hasher);
+        (name_hash as u64).hash_stable(hcx, hasher);
         name_was_remapped.hash_stable(hcx, hasher);
 
         DefId {
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 9018b9fe590..3bcde93fde5 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -558,24 +558,29 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
             }
             ty::TyError => { }
             _ => {
-                let def_id = self.mc.tables.type_dependent_defs()[call.hir_id].def_id();
-                let call_scope = region::Scope::Node(call.hir_id.local_id);
-                match OverloadedCallType::from_method_id(self.tcx(), def_id) {
-                    FnMutOverloadedCall => {
-                        let call_scope_r = self.tcx().mk_region(ty::ReScope(call_scope));
-                        self.borrow_expr(callee,
-                                         call_scope_r,
-                                         ty::MutBorrow,
-                                         ClosureInvocation);
-                    }
-                    FnOverloadedCall => {
-                        let call_scope_r = self.tcx().mk_region(ty::ReScope(call_scope));
-                        self.borrow_expr(callee,
-                                         call_scope_r,
-                                         ty::ImmBorrow,
-                                         ClosureInvocation);
+                if let Some(def) = self.mc.tables.type_dependent_defs().get(call.hir_id) {
+                    let def_id = def.def_id();
+                    let call_scope = region::Scope::Node(call.hir_id.local_id);
+                    match OverloadedCallType::from_method_id(self.tcx(), def_id) {
+                        FnMutOverloadedCall => {
+                            let call_scope_r = self.tcx().mk_region(ty::ReScope(call_scope));
+                            self.borrow_expr(callee,
+                                            call_scope_r,
+                                            ty::MutBorrow,
+                                            ClosureInvocation);
+                        }
+                        FnOverloadedCall => {
+                            let call_scope_r = self.tcx().mk_region(ty::ReScope(call_scope));
+                            self.borrow_expr(callee,
+                                            call_scope_r,
+                                            ty::ImmBorrow,
+                                            ClosureInvocation);
+                        }
+                        FnOnceOverloadedCall => self.consume_expr(callee),
                     }
-                    FnOnceOverloadedCall => self.consume_expr(callee),
+                } else {
+                    self.tcx().sess.delay_span_bug(call.span,
+                                                   "no type-dependent def for overloaded call");
                 }
             }
         }
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 6e0372f009e..7e80139b791 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -528,6 +528,25 @@ impl OutputFilenames {
     pub fn filestem(&self) -> String {
         format!("{}{}", self.out_filestem, self.extra)
     }
+
+    pub fn contains_path(&self, input_path: &PathBuf) -> bool {
+        let input_path = input_path.canonicalize().ok();
+        if input_path.is_none() {
+            return false
+        }
+        match self.single_output_file {
+            Some(ref output_path) => output_path.canonicalize().ok() == input_path,
+            None => {
+                for k in self.outputs.keys() {
+                    let output_path = self.path(k.to_owned());
+                    if output_path.canonicalize().ok() == input_path {
+                        return true;
+                    }
+                }
+                false
+            }
+        }
+    }
 }
 
 pub fn host_triple() -> &'static str {
@@ -596,6 +615,12 @@ impl Options {
             ).map(|(src, dst)| (src.clone(), dst.clone())).collect()
         )
     }
+
+    /// True if there will be an output file generated
+    pub fn will_create_output_file(&self) -> bool {
+        !self.debugging_opts.parse_only && // The file is just being parsed
+            !self.debugging_opts.ls // The file is just being queried
+    }
 }
 
 // The type of entry function, so
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index a2692fb8f5a..978c6c74233 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -1484,27 +1484,25 @@ impl<'a, 'tcx> LayoutDetails {
                                     Some(niche) => niche,
                                     None => continue
                                 };
+                            let mut align = dl.aggregate_align;
                             let st = variants.iter().enumerate().map(|(j, v)| {
                                 let mut st = univariant_uninterned(v,
                                     &def.repr, StructKind::AlwaysSized)?;
                                 st.variants = Variants::Single { index: j };
+
+                                align = align.max(st.align);
+
                                 Ok(st)
                             }).collect::<Result<Vec<_>, _>>()?;
 
                             let offset = st[i].fields.offset(field_index) + offset;
-                            let LayoutDetails { mut size, mut align, .. } = st[i];
+                            let size = st[i].size;
 
-                            let mut niche_align = niche.value.align(dl);
                             let abi = if offset.bytes() == 0 && niche.value.size(dl) == size {
                                 Abi::Scalar(niche.clone())
                             } else {
-                                if offset.abi_align(niche_align) != offset {
-                                    niche_align = dl.i8_align;
-                                }
                                 Abi::Aggregate { sized: true }
                             };
-                            align = align.max(niche_align);
-                            size = size.abi_align(align);
 
                             return Ok(tcx.intern_layout(LayoutDetails {
                                 variants: Variants::NicheFilling {
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 9e5de8d54e9..a288ff6316f 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -71,6 +71,7 @@ use profile;
 
 pub fn compile_input(sess: &Session,
                      cstore: &CStore,
+                     input_path: &Option<PathBuf>,
                      input: &Input,
                      outdir: &Option<PathBuf>,
                      output: &Option<PathBuf>,
@@ -142,6 +143,20 @@ pub fn compile_input(sess: &Session,
         };
 
         let outputs = build_output_filenames(input, outdir, output, &krate.attrs, sess);
+
+        // Ensure the source file isn't accidentally overwritten during compilation.
+        match *input_path {
+            Some(ref input_path) => {
+                if outputs.contains_path(input_path) && sess.opts.will_create_output_file() {
+                    sess.err(&format!(
+                        "the input file \"{}\" would be overwritten by the generated executable",
+                        input_path.display()));
+                    return Err(CompileIncomplete::Stopped);
+                }
+            },
+            None => {}
+        }
+
         let crate_name =
             ::rustc_trans_utils::link::find_crate_name(Some(sess), &krate.attrs, input);
         let ExpansionResult { expanded_crate, defs, analysis, resolutions, mut hir_forest } = {
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 29d3d31e451..60857505c7a 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -232,7 +232,7 @@ pub fn run_compiler<'a>(args: &[String],
     let loader = file_loader.unwrap_or(box RealFileLoader);
     let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping()));
     let mut sess = session::build_session_with_codemap(
-        sopts, input_file_path, descriptions, codemap, emitter_dest,
+        sopts, input_file_path.clone(), descriptions, codemap, emitter_dest,
     );
     rustc_trans::init(&sess);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
@@ -252,6 +252,7 @@ pub fn run_compiler<'a>(args: &[String],
     let control = callbacks.build_controller(&sess, &matches);
     (driver::compile_input(&sess,
                            &cstore,
+                           &input_file_path,
                            &input,
                            &odir,
                            &ofile,
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 81db44b0553..501f6bb0c0d 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -349,7 +349,27 @@ impl MissingDoc {
             }
         }
 
-        let has_doc = attrs.iter().any(|a| a.is_value_str() && a.check_name("doc"));
+        fn has_doc(attr: &ast::Attribute) -> bool {
+            if !attr.check_name("doc") {
+                return false;
+            }
+
+            if attr.is_value_str() {
+                return true;
+            }
+
+            if let Some(list) = attr.meta_item_list() {
+                for meta in list {
+                    if meta.check_name("include") {
+                        return true;
+                    }
+                }
+            }
+
+            false
+        }
+
+        let has_doc = attrs.iter().any(|a| has_doc(a));
         if !has_doc {
             cx.span_lint(MISSING_DOCS,
                          cx.tcx.sess.codemap().def_span(sp),
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 49a017535ff..0e9f4a8f178 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -1129,6 +1129,7 @@ impl<'a, 'tcx> CrateMetadata {
                                       lines,
                                       multibyte_chars,
                                       non_narrow_chars,
+                                      name_hash,
                                       .. } = filemap_to_import;
 
             let source_length = (end_pos - start_pos).to_usize();
@@ -1155,6 +1156,7 @@ impl<'a, 'tcx> CrateMetadata {
                                                                    name_was_remapped,
                                                                    self.cnum.as_u32(),
                                                                    src_hash,
+                                                                   name_hash,
                                                                    source_length,
                                                                    lines,
                                                                    multibyte_chars,
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 29369f9f8bb..5ddbb18450e 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -28,8 +28,10 @@ use rustc::ty::codec::{self as ty_codec, TyEncoder};
 use rustc::session::config::{self, CrateTypeProcMacro};
 use rustc::util::nodemap::{FxHashMap, NodeSet};
 
+use rustc_data_structures::stable_hasher::StableHasher;
 use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque};
 
+use std::hash::Hash;
 use std::io::prelude::*;
 use std::io::Cursor;
 use std::path::Path;
@@ -290,6 +292,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                         } else {
                             let mut adapted = (**filemap).clone();
                             adapted.name = Path::new(&working_dir).join(name).into();
+                            adapted.name_hash = {
+                                let mut hasher: StableHasher<u128> = StableHasher::new();
+                                adapted.name.hash(&mut hasher);
+                                hasher.finish()
+                            };
                             Rc::new(adapted)
                         }
                     },
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index e2640d695c6..b1fef274cba 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -377,6 +377,17 @@ fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning<
     assert!(target_cgu_count >= 1);
     let codegen_units = &mut initial_partitioning.codegen_units;
 
+    // Note that at this point in time the `codegen_units` here may not be in a
+    // deterministic order (but we know they're deterministically the same set).
+    // We want this merging to produce a deterministic ordering of codegen units
+    // from the input.
+    //
+    // Due to basically how we've implemented the merging below (merge the two
+    // smallest into each other) we're sure to start off with a deterministic
+    // order (sorted by name). This'll mean that if two cgus have the same size
+    // the stable sort below will keep everything nice and deterministic.
+    codegen_units.sort_by_key(|cgu| cgu.name().clone());
+
     // Merge the two smallest codegen units until the target size is reached.
     // Note that "size" is estimated here rather inaccurately as the number of
     // translation items in a given unit. This could be improved on.
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 515baa2c669..3be44f30958 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -3720,9 +3720,10 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
                     })).and_then(|did| c.impls.get(&did));
                     if let Some(impls) = inner_impl {
                         out.push_str("<a class=\"sidebar-title\" href=\"#deref-methods\">");
-                        out.push_str(&format!("Methods from {:#}&lt;Target={:#}&gt;",
-                                              impl_.inner_impl().trait_.as_ref().unwrap(),
-                                              target));
+                        out.push_str(&format!("Methods from {}&lt;Target={}&gt;",
+                                              Escape(&format!("{:#}",
+                                                     impl_.inner_impl().trait_.as_ref().unwrap())),
+                                              Escape(&format!("{:#}", target))));
                         out.push_str("</a>");
                         let ret = impls.iter()
                                        .filter(|i| i.inner_impl().trait_.is_none())
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index abb90200370..8e861f10dd8 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -263,7 +263,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, cfgs: Vec<String>,
     }
 
     let res = panic::catch_unwind(AssertUnwindSafe(|| {
-        driver::compile_input(&sess, &cstore, &input, &out, &None, None, &control)
+        driver::compile_input(&sess, &cstore, &None, &input, &out, &None, None, &control)
     }));
 
     let compile_result = match res {
@@ -533,7 +533,7 @@ impl Collector {
                 should_panic: testing::ShouldPanic::No,
                 allow_fail,
             },
-            testfn: testing::DynTestFn(box move |()| {
+            testfn: testing::DynTestFn(box move || {
                 let panic = io::set_panic(None);
                 let print = io::set_print(None);
                 match {
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 6d3fbc9d268..8308ab48d9c 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -263,7 +263,7 @@ impl<R: Seek> Seek for BufReader<R> {
     /// See `std::io::Seek` for more details.
     ///
     /// Note: In the edge case where you're seeking with `SeekFrom::Current(n)`
-    /// where `n` minus the internal buffer length underflows an `i64`, two
+    /// where `n` minus the internal buffer length overflows an `i64`, two
     /// seeks will be performed instead of one. If the second seek returns
     /// `Err`, the underlying reader will be left at the same position it would
     /// have if you seeked to `SeekFrom::Current(0)`.
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index a74e8a21c42..15ddb62bab5 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -290,7 +290,7 @@ impl Duration {
     }
 
     /// Checked `Duration` subtraction. Computes `self - other`, returning [`None`]
-    /// if the result would be negative or if underflow occurred.
+    /// if the result would be negative or if overflow occurred.
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
     ///
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 2c91d60ce9d..e49a7117192 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -246,6 +246,7 @@ impl CodeMap {
                                 name_was_remapped: bool,
                                 crate_of_origin: u32,
                                 src_hash: u128,
+                                name_hash: u128,
                                 source_len: usize,
                                 mut file_local_lines: Vec<BytePos>,
                                 mut file_local_multibyte_chars: Vec<MultiByteChar>,
@@ -282,6 +283,7 @@ impl CodeMap {
             lines: RefCell::new(file_local_lines),
             multibyte_chars: RefCell::new(file_local_multibyte_chars),
             non_narrow_chars: RefCell::new(file_local_non_narrow_chars),
+            name_hash,
         });
 
         files.push(filemap.clone());
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 07ea6a09086..81baa0c3954 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1115,15 +1115,19 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
                     match File::open(&filename).and_then(|mut f| f.read_to_end(&mut buf)) {
                         Ok(..) => {}
                         Err(e) => {
-                            self.cx.span_warn(at.span,
-                                              &format!("couldn't read {}: {}",
-                                                       filename.display(),
-                                                       e));
+                            self.cx.span_err(at.span,
+                                             &format!("couldn't read {}: {}",
+                                                      filename.display(),
+                                                      e));
                         }
                     }
 
                     match String::from_utf8(buf) {
                         Ok(src) => {
+                            // Add this input file to the code map to make it available as
+                            // dependency information
+                            self.cx.codemap().new_filemap_and_lines(&filename, &src);
+
                             let include_info = vec![
                                 dummy_spanned(ast::NestedMetaItemKind::MetaItem(
                                         attr::mk_name_value_item_str("file".into(),
@@ -1137,9 +1141,9 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
                                         attr::mk_list_item("include".into(), include_info))));
                         }
                         Err(_) => {
-                            self.cx.span_warn(at.span,
-                                              &format!("{} wasn't a utf-8 file",
-                                                       filename.display()));
+                            self.cx.span_err(at.span,
+                                             &format!("{} wasn't a utf-8 file",
+                                                      filename.display()));
                         }
                     }
                 } else {
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 8d5d7c81c0e..85f0925b982 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -30,7 +30,7 @@ use std::borrow::Cow;
 use std::cell::{Cell, RefCell};
 use std::cmp::{self, Ordering};
 use std::fmt;
-use std::hash::Hasher;
+use std::hash::{Hasher, Hash};
 use std::ops::{Add, Sub};
 use std::path::PathBuf;
 use std::rc::Rc;
@@ -691,6 +691,8 @@ pub struct FileMap {
     pub multibyte_chars: RefCell<Vec<MultiByteChar>>,
     /// Width of characters that are not narrow in the source code
     pub non_narrow_chars: RefCell<Vec<NonNarrowChar>>,
+    /// A hash of the filename, used for speeding up the incr. comp. hashing.
+    pub name_hash: u128,
 }
 
 impl Encodable for FileMap {
@@ -752,6 +754,9 @@ impl Encodable for FileMap {
             })?;
             s.emit_struct_field("non_narrow_chars", 8, |s| {
                 (*self.non_narrow_chars.borrow()).encode(s)
+            })?;
+            s.emit_struct_field("name_hash", 9, |s| {
+                self.name_hash.encode(s)
             })
         })
     }
@@ -801,6 +806,8 @@ impl Decodable for FileMap {
                 d.read_struct_field("multibyte_chars", 7, |d| Decodable::decode(d))?;
             let non_narrow_chars: Vec<NonNarrowChar> =
                 d.read_struct_field("non_narrow_chars", 8, |d| Decodable::decode(d))?;
+            let name_hash: u128 =
+                d.read_struct_field("name_hash", 9, |d| Decodable::decode(d))?;
             Ok(FileMap {
                 name,
                 name_was_remapped,
@@ -816,7 +823,8 @@ impl Decodable for FileMap {
                 external_src: RefCell::new(ExternalSource::AbsentOk),
                 lines: RefCell::new(lines),
                 multibyte_chars: RefCell::new(multibyte_chars),
-                non_narrow_chars: RefCell::new(non_narrow_chars)
+                non_narrow_chars: RefCell::new(non_narrow_chars),
+                name_hash,
             })
         })
     }
@@ -836,9 +844,16 @@ impl FileMap {
                start_pos: BytePos) -> FileMap {
         remove_bom(&mut src);
 
-        let mut hasher: StableHasher<u128> = StableHasher::new();
-        hasher.write(src.as_bytes());
-        let src_hash = hasher.finish();
+        let src_hash = {
+            let mut hasher: StableHasher<u128> = StableHasher::new();
+            hasher.write(src.as_bytes());
+            hasher.finish()
+        };
+        let name_hash = {
+            let mut hasher: StableHasher<u128> = StableHasher::new();
+            name.hash(&mut hasher);
+            hasher.finish()
+        };
         let end_pos = start_pos.to_usize() + src.len();
 
         FileMap {
@@ -854,6 +869,7 @@ impl FileMap {
             lines: RefCell::new(Vec::new()),
             multibyte_chars: RefCell::new(Vec::new()),
             non_narrow_chars: RefCell::new(Vec::new()),
+            name_hash,
         }
     }
 
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index bc96a5d6740..0d837c470a2 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -35,6 +35,7 @@
 #![deny(warnings)]
 
 #![feature(asm)]
+#![feature(fnbox)]
 #![cfg_attr(unix, feature(libc))]
 #![feature(set_stdio)]
 #![feature(panic_unwind)]
@@ -56,6 +57,7 @@ use self::OutputLocation::*;
 
 use std::panic::{catch_unwind, AssertUnwindSafe};
 use std::any::Any;
+use std::boxed::FnBox;
 use std::cmp;
 use std::collections::BTreeMap;
 use std::env;
@@ -133,16 +135,6 @@ pub trait TDynBenchFn: Send {
     fn run(&self, harness: &mut Bencher);
 }
 
-pub trait FnBox<T>: Send + 'static {
-    fn call_box(self: Box<Self>, t: T);
-}
-
-impl<T, F: FnOnce(T) + Send + 'static> FnBox<T> for F {
-    fn call_box(self: Box<F>, t: T) {
-        (*self)(t)
-    }
-}
-
 // A function that runs a test. If the function returns successfully,
 // the test succeeds; if the function panics then the test fails. We
 // may need to come up with a more clever definition of test in order
@@ -150,7 +142,7 @@ impl<T, F: FnOnce(T) + Send + 'static> FnBox<T> for F {
 pub enum TestFn {
     StaticTestFn(fn()),
     StaticBenchFn(fn(&mut Bencher)),
-    DynTestFn(Box<FnBox<()>>),
+    DynTestFn(Box<FnBox() + Send>),
     DynBenchFn(Box<TDynBenchFn + 'static>),
 }
 
@@ -1337,14 +1329,14 @@ pub fn convert_benchmarks_to_tests(tests: Vec<TestDescAndFn>) -> Vec<TestDescAnd
     tests.into_iter().map(|x| {
         let testfn = match x.testfn {
             DynBenchFn(bench) => {
-                DynTestFn(Box::new(move |()| {
+                DynTestFn(Box::new(move || {
                     bench::run_once(|b| {
                         __rust_begin_short_backtrace(|| bench.run(b))
                     })
                 }))
             }
             StaticBenchFn(benchfn) => {
-                DynTestFn(Box::new(move |()| {
+                DynTestFn(Box::new(move || {
                     bench::run_once(|b| {
                         __rust_begin_short_backtrace(|| benchfn(b))
                     })
@@ -1379,7 +1371,7 @@ pub fn run_test(opts: &TestOpts,
     fn run_test_inner(desc: TestDesc,
                       monitor_ch: Sender<MonitorMsg>,
                       nocapture: bool,
-                      testfn: Box<FnBox<()>>) {
+                      testfn: Box<FnBox() + Send>) {
         struct Sink(Arc<Mutex<Vec<u8>>>);
         impl Write for Sink {
             fn write(&mut self, data: &[u8]) -> io::Result<usize> {
@@ -1405,9 +1397,7 @@ pub fn run_test(opts: &TestOpts,
                 None
             };
 
-            let result = catch_unwind(AssertUnwindSafe(|| {
-                testfn.call_box(())
-            }));
+            let result = catch_unwind(AssertUnwindSafe(testfn));
 
             if let Some((printio, panicio)) = oldio {
                 io::set_print(printio);
@@ -1449,14 +1439,14 @@ pub fn run_test(opts: &TestOpts,
             return;
         }
         DynTestFn(f) => {
-            let cb = move |()| {
-                __rust_begin_short_backtrace(|| f.call_box(()))
+            let cb = move || {
+                __rust_begin_short_backtrace(f)
             };
             run_test_inner(desc, monitor_ch, opts.nocapture, Box::new(cb))
         }
         StaticTestFn(f) =>
             run_test_inner(desc, monitor_ch, opts.nocapture,
-                           Box::new(move |()| __rust_begin_short_backtrace(f))),
+                           Box::new(move || __rust_begin_short_backtrace(f))),
     }
 }
 
@@ -1720,7 +1710,7 @@ mod tests {
                 should_panic: ShouldPanic::No,
                 allow_fail: false,
             },
-            testfn: DynTestFn(Box::new(move |()| f())),
+            testfn: DynTestFn(Box::new(f)),
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
@@ -1738,7 +1728,7 @@ mod tests {
                 should_panic: ShouldPanic::No,
                 allow_fail: false,
             },
-            testfn: DynTestFn(Box::new(move |()| f())),
+            testfn: DynTestFn(Box::new(f)),
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
@@ -1758,7 +1748,7 @@ mod tests {
                 should_panic: ShouldPanic::Yes,
                 allow_fail: false,
             },
-            testfn: DynTestFn(Box::new(move |()| f())),
+            testfn: DynTestFn(Box::new(f)),
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
@@ -1778,7 +1768,7 @@ mod tests {
                 should_panic: ShouldPanic::YesWithMessage("error message"),
                 allow_fail: false,
             },
-            testfn: DynTestFn(Box::new(move |()| f())),
+            testfn: DynTestFn(Box::new(f)),
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
@@ -1800,7 +1790,7 @@ mod tests {
                 should_panic: ShouldPanic::YesWithMessage(expected),
                 allow_fail: false,
             },
-            testfn: DynTestFn(Box::new(move |()| f())),
+            testfn: DynTestFn(Box::new(f)),
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
@@ -1818,7 +1808,7 @@ mod tests {
                 should_panic: ShouldPanic::Yes,
                 allow_fail: false,
             },
-            testfn: DynTestFn(Box::new(move |()| f())),
+            testfn: DynTestFn(Box::new(f)),
         };
         let (tx, rx) = channel();
         run_test(&TestOpts::new(), false, desc, tx);
@@ -1852,7 +1842,7 @@ mod tests {
                                  should_panic: ShouldPanic::No,
                                  allow_fail: false,
                              },
-                             testfn: DynTestFn(Box::new(move |()| {})),
+                             testfn: DynTestFn(Box::new(move || {})),
                          },
                          TestDescAndFn {
                              desc: TestDesc {
@@ -1861,7 +1851,7 @@ mod tests {
                                  should_panic: ShouldPanic::No,
                                  allow_fail: false,
                              },
-                             testfn: DynTestFn(Box::new(move |()| {})),
+                             testfn: DynTestFn(Box::new(move || {})),
                          }];
         let filtered = filter_tests(&opts, tests);
 
@@ -1885,7 +1875,7 @@ mod tests {
                     should_panic: ShouldPanic::No,
                     allow_fail: false,
                 },
-                testfn: DynTestFn(Box::new(move |()| {}))
+                testfn: DynTestFn(Box::new(move || {}))
             })
             .collect()
         }
@@ -1967,7 +1957,7 @@ mod tests {
                         should_panic: ShouldPanic::No,
                         allow_fail: false,
                     },
-                    testfn: DynTestFn(Box::new(move |()| testfn())),
+                    testfn: DynTestFn(Box::new(testfn)),
                 };
                 tests.push(test);
             }
diff --git a/src/test/COMPILER_TESTS.md b/src/test/COMPILER_TESTS.md
index 021f27dacbe..c255294e790 100644
--- a/src/test/COMPILER_TESTS.md
+++ b/src/test/COMPILER_TESTS.md
@@ -35,20 +35,24 @@ The error levels that you can have are:
 ## Summary of Header Commands
 
 Header commands specify something about the entire test file as a
-whole, instead of just a few lines inside the test.
+whole. They are normally put right after the copyright comment, e.g.:
+
+```Rust
+// Copyright blah blah blah
+// except according to those terms.
+
+// ignore-test This doesn't actually work
+```
+
+### Ignoring tests
+
+These are used to ignore the test in some situations, which means the test won't
+be compiled or run.
 
 * `ignore-X` where `X` is a target detail or stage will ignore the test accordingly (see below)
 * `ignore-pretty` will not compile the pretty-printed test (this is done to test the pretty-printer, but might not always work)
 * `ignore-test` always ignores the test
-* `ignore-lldb` and `ignore-gdb` will skip the debuginfo tests
-* `min-{gdb,lldb}-version`
-* `should-fail` indicates that the test should fail; used for "meta testing",
-  where we test the compiletest program itself to check that it will generate
-  errors in appropriate scenarios. This header is ignored for pretty-printer tests.
-* `gate-test-X` where `X` is a feature marks the test as "gate test" for feature X.
-  Such tests are supposed to ensure that the compiler errors when usage of a gated
-  feature is attempted without the proper `#![feature(X)]` tag.
-  Each unstable lang feature is required to have a gate test.
+* `ignore-lldb` and `ignore-gdb` will skip a debuginfo test on that debugger.
 
 Some examples of `X` in `ignore-X`:
 
@@ -58,6 +62,22 @@ Some examples of `X` in `ignore-X`:
 * Pointer width: `32bit`, `64bit`.
 * Stage: `stage0`, `stage1`, `stage2`.
 
+### Other Header Commands
+
+* `min-{gdb,lldb}-version`
+* `min-llvm-version`
+* `must-compile-successfully` for UI tests, indicates that the test is supposed
+  to compile, as opposed to the default where the test is supposed to error out.
+* `compile-flags` passes extra command-line args to the compiler,
+  e.g. `compile-flags -g` which forces debuginfo to be enabled.
+* `should-fail` indicates that the test should fail; used for "meta testing",
+  where we test the compiletest program itself to check that it will generate
+  errors in appropriate scenarios. This header is ignored for pretty-printer tests.
+* `gate-test-X` where `X` is a feature marks the test as "gate test" for feature X.
+  Such tests are supposed to ensure that the compiler errors when usage of a gated
+  feature is attempted without the proper `#![feature(X)]` tag.
+  Each unstable lang feature is required to have a gate test.
+
 ## Revisions
 
 Certain classes of tests support "revisions" (as of the time of this
@@ -109,6 +129,12 @@ fails, we will print out the current output, but it is also saved in
 printed as part of the test failure message), so you can run `diff` and
 so forth.
 
+Normally, the test-runner checks that UI tests fail compilation. If you want
+to do a UI test for code that *compiles* (e.g. to test warnings, or if you
+have a collection of tests, only some of which error out), you can use the
+`// must-compile-successfully` header command to have the test runner instead
+check that the test compiles successfully.
+
 ### Editing and updating the reference files
 
 If you have changed the compiler's output intentionally, or you are
diff --git a/src/test/compile-fail/external-doc-error.rs b/src/test/compile-fail/external-doc-error.rs
new file mode 100644
index 00000000000..1ae0d0bd276
--- /dev/null
+++ b/src/test/compile-fail/external-doc-error.rs
@@ -0,0 +1,16 @@
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(external_doc)]
+
+#[doc(include = "not-a-file.md")] //~ ERROR: couldn't read
+pub struct SomeStruct;
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-46771.rs b/src/test/compile-fail/issue-46771.rs
new file mode 100644
index 00000000000..f8bcd8861f3
--- /dev/null
+++ b/src/test/compile-fail/issue-46771.rs
@@ -0,0 +1,14 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    struct Foo;
+    (1 .. 2).find(|_| Foo(0) == 0); //~ ERROR expected function, found `main::Foo`
+}
diff --git a/src/test/run-make/include_bytes_deps/Makefile b/src/test/run-make/include_bytes_deps/Makefile
index f7b1d21ace2..1293695b799 100644
--- a/src/test/run-make/include_bytes_deps/Makefile
+++ b/src/test/run-make/include_bytes_deps/Makefile
@@ -8,7 +8,7 @@ ifneq ($(shell uname),FreeBSD)
 ifndef IS_WINDOWS
 all:
 	$(RUSTC) --emit dep-info main.rs
-	$(CGREP) "input.txt" "input.bin" < $(TMPDIR)/main.d
+	$(CGREP) "input.txt" "input.bin" "input.md" < $(TMPDIR)/main.d
 else
 all:
 
diff --git a/src/test/run-make/include_bytes_deps/input.md b/src/test/run-make/include_bytes_deps/input.md
new file mode 100644
index 00000000000..2a19b7405f7
--- /dev/null
+++ b/src/test/run-make/include_bytes_deps/input.md
@@ -0,0 +1 @@
+# Hello, world!
diff --git a/src/test/run-make/include_bytes_deps/main.rs b/src/test/run-make/include_bytes_deps/main.rs
index 579b2a452a1..27ca1a46a50 100644
--- a/src/test/run-make/include_bytes_deps/main.rs
+++ b/src/test/run-make/include_bytes_deps/main.rs
@@ -8,6 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(external_doc)]
+
+#[doc(include="input.md")]
+pub struct SomeStruct;
+
 pub fn main() {
     const INPUT_TXT: &'static str = include_str!("input.txt");
     const INPUT_BIN: &'static [u8] = include_bytes!("input.bin");
diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make/issue-19371/foo.rs
index cfe8048638a..f0ab1d5dc0f 100644
--- a/src/test/run-make/issue-19371/foo.rs
+++ b/src/test/run-make/issue-19371/foo.rs
@@ -71,5 +71,5 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
     let (sess, cstore) = basic_sess(sysroot);
     let control = CompileController::basic();
     let input = Input::Str { name: FileName::Anon, input: code };
-    let _ = compile_input(&sess, &cstore, &input, &None, &Some(output), None, &control);
+    let _ = compile_input(&sess, &cstore, &None, &input, &None, &Some(output), None, &control);
 }
diff --git a/src/test/run-make/output-filename-overwrites-input/Makefile b/src/test/run-make/output-filename-overwrites-input/Makefile
new file mode 100644
index 00000000000..0554627d677
--- /dev/null
+++ b/src/test/run-make/output-filename-overwrites-input/Makefile
@@ -0,0 +1,10 @@
+-include ../tools.mk
+
+all:
+	cp foo.rs $(TMPDIR)/foo
+	$(RUSTC) $(TMPDIR)/foo 2>&1 \
+		| $(CGREP) -e "the input file \".*foo\" would be overwritten by the generated executable"
+	$(RUSTC) foo.rs 2>&1 && $(RUSTC) -Z ls $(TMPDIR)/foo 2>&1
+	cp foo.rs $(TMPDIR)/foo.rs
+	$(RUSTC) $(TMPDIR)/foo.rs -o $(TMPDIR)/foo.rs 2>&1 \
+		| $(CGREP) -e "the input file \".*foo.rs\" would be overwritten by the generated executable"
diff --git a/src/test/run-make/output-filename-overwrites-input/foo.rs b/src/test/run-make/output-filename-overwrites-input/foo.rs
new file mode 100644
index 00000000000..046d27a9f0f
--- /dev/null
+++ b/src/test/run-make/output-filename-overwrites-input/foo.rs
@@ -0,0 +1,11 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {}
diff --git a/src/test/run-make/weird-output-filenames/Makefile b/src/test/run-make/weird-output-filenames/Makefile
index a5543e3b2c4..f161fe9f8e8 100644
--- a/src/test/run-make/weird-output-filenames/Makefile
+++ b/src/test/run-make/weird-output-filenames/Makefile
@@ -7,8 +7,8 @@ all:
 	cp foo.rs $(TMPDIR)/.foo.bar
 	$(RUSTC) $(TMPDIR)/.foo.bar 2>&1 \
 		| $(CGREP) -e "invalid character.*in crate name:"
-	cp foo.rs $(TMPDIR)/+foo+bar
-	$(RUSTC) $(TMPDIR)/+foo+bar 2>&1 \
+	cp foo.rs $(TMPDIR)/+foo+bar.rs
+	$(RUSTC) $(TMPDIR)/+foo+bar.rs 2>&1 \
 		| $(CGREP) -e "invalid character.*in crate name:"
 	cp foo.rs $(TMPDIR)/-foo.rs
 	$(RUSTC) $(TMPDIR)/-foo.rs 2>&1 \
diff --git a/src/test/run-pass/packed-struct-optimized-enum.rs b/src/test/run-pass/packed-struct-optimized-enum.rs
index b8a1e6f2f54..7968ae2278a 100644
--- a/src/test/run-pass/packed-struct-optimized-enum.rs
+++ b/src/test/run-pass/packed-struct-optimized-enum.rs
@@ -19,7 +19,9 @@ impl<T: Copy> Clone for Packed<T> {
 fn sanity_check_size<T: Copy>(one: T) {
     let two = [one, one];
     let stride = (&two[1] as *const _ as usize) - (&two[0] as *const _ as usize);
-    assert_eq!(stride, std::mem::size_of_val(&one));
+    let (size, align) = (std::mem::size_of::<T>(), std::mem::align_of::<T>());
+    assert_eq!(stride, size);
+    assert_eq!(size % align, 0);
 }
 
 fn main() {
@@ -32,5 +34,12 @@ fn main() {
     // In #46769, `Option<(Packed<&()>, bool)>` was found to have
     // pointer alignment, without actually being aligned in size.
     // E.g. on 64-bit platforms, it had alignment `8` but size `9`.
-    sanity_check_size(Some((Packed(&()), true)));
+    type PackedRefAndBool<'a> = (Packed<&'a ()>, bool);
+    sanity_check_size::<Option<PackedRefAndBool>>(Some((Packed(&()), true)));
+
+    // Make sure we don't pay for the enum optimization in size,
+    // e.g. we shouldn't need extra padding after the packed data.
+    assert_eq!(std::mem::align_of::<Option<PackedRefAndBool>>(), 1);
+    assert_eq!(std::mem::size_of::<Option<PackedRefAndBool>>(),
+               std::mem::size_of::<PackedRefAndBool>());
 }
diff --git a/src/test/rustdoc/auxiliary/external-cross.rs b/src/test/rustdoc/auxiliary/external-cross.rs
index cb14fec7abe..767fb05313a 100644
--- a/src/test/rustdoc/auxiliary/external-cross.rs
+++ b/src/test/rustdoc/auxiliary/external-cross.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #![feature(external_doc)]
+#![deny(missing_doc)]
 
 #[doc(include="external-cross-doc.md")]
 pub struct NeedMoreDocs;
diff --git a/src/test/rustdoc/escape-deref-methods.rs b/src/test/rustdoc/escape-deref-methods.rs
new file mode 100644
index 00000000000..f31b0ddca9a
--- /dev/null
+++ b/src/test/rustdoc/escape-deref-methods.rs
@@ -0,0 +1,45 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_name = "foo"]
+
+use std::ops::{Deref, DerefMut};
+
+#[derive(Debug, Clone)]
+pub struct Title {
+    name: String,
+}
+
+#[derive(Debug, Clone)]
+pub struct TitleList {
+    pub members: Vec<Title>,
+}
+
+impl TitleList {
+    pub fn new() -> Self {
+        TitleList { members: Vec::new() }
+    }
+}
+
+impl Deref for TitleList {
+    type Target = Vec<Title>;
+
+    fn deref(&self) -> &Self::Target {
+        &self.members
+    }
+}
+
+// @has foo/struct.TitleList.html
+// @has - '//*[@class="sidebar-title"]' 'Methods from Deref<Target=Vec<Title>>'
+impl DerefMut for TitleList {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.members
+    }
+}
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 8546289fdec..80630b5e2cf 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -711,7 +711,7 @@ pub fn make_test_name(config: &Config, testpaths: &TestPaths) -> test::TestName
 pub fn make_test_closure(config: &Config, testpaths: &TestPaths) -> test::TestFn {
     let config = config.clone();
     let testpaths = testpaths.clone();
-    test::DynTestFn(Box::new(move |()| runtest::run(config, &testpaths)))
+    test::DynTestFn(Box::new(move || runtest::run(config, &testpaths)))
 }
 
 /// Returns (Path to GDB, GDB Version, GDB has Rust Support)