about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-01-12 20:28:19 +0000
committerbors <bors@rust-lang.org>2018-01-12 20:28:19 +0000
commit51b0b3734cbd0ca58c8be3512d53fce2d95f40dd (patch)
tree0f7929e306da4893a0db5671686f08d4443d8859 /src
parent0b90e4e8cd068910f604f3e1fb5d03cc01f1658f (diff)
parentc12eabfb11384dfd45cab87a809aa442203dcc53 (diff)
downloadrust-51b0b3734cbd0ca58c8be3512d53fce2d95f40dd.tar.gz
rust-51b0b3734cbd0ca58c8be3512d53fce2d95f40dd.zip
Auto merge of #47392 - kennytm:rollup, r=kennytm
Rollup of 24 pull requests

- Successful merges: #46985, #47069, #47081, #47185, #47282, #47283, #47288, #47289, #47298, #47305, #47306, #47307, #47310, #47324, #47328, #47331, #47340, #47343, #47344, #47352, #47357, #47365, #47375, #47382
- Failed merges: #47334
Diffstat (limited to 'src')
-rw-r--r--src/Cargo.lock10
-rwxr-xr-xsrc/bootstrap/configure.py2
-rw-r--r--src/bootstrap/native.rs2
-rw-r--r--src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile (renamed from src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile)19
-rw-r--r--src/ci/docker/scripts/musl.sh4
-rw-r--r--src/libarena/lib.rs35
-rw-r--r--src/libcore/tests/num/mod.rs1
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/lint/context.rs2
-rw-r--r--src/librustc/util/common.rs7
-rw-r--r--src/librustc_back/lib.rs1
-rw-r--r--src/librustc_back/target/i586_unknown_linux_musl.rs18
-rw-r--r--src/librustc_back/target/mod.rs13
-rw-r--r--src/librustc_const_eval/pattern.rs3
-rw-r--r--src/librustc_driver/driver.rs9
-rw-r--r--src/librustc_incremental/assert_dep_graph.rs4
-rw-r--r--src/librustc_incremental/lib.rs1
-rw-r--r--src/librustc_incremental/persist/file_format.rs8
-rw-r--r--src/librustc_incremental/persist/save.rs6
-rw-r--r--src/librustc_metadata/lib.rs1
-rw-r--r--src/librustc_metadata/locator.rs7
-rw-r--r--src/librustc_mir/dataflow/graphviz.rs4
-rw-r--r--src/librustc_mir/lib.rs1
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs54
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs8
-rw-r--r--src/librustc_trans/back/link.rs4
-rw-r--r--src/librustc_trans/back/write.rs15
-rw-r--r--src/librustc_trans/lib.rs1
-rw-r--r--src/librustdoc/externalfiles.rs17
-rw-r--r--src/librustdoc/html/render.rs20
-rw-r--r--src/librustdoc/lib.rs1
-rw-r--r--src/libstd/ffi/mod.rs2
-rw-r--r--src/libstd/ffi/os_str.rs7
-rw-r--r--src/libstd/fs.rs12
-rw-r--r--src/libstd/path.rs7
-rw-r--r--src/libstd/sync/rwlock.rs2
-rw-r--r--src/libstd/time/duration.rs4
-rw-r--r--src/libsyntax/parse/parser.rs12
-rw-r--r--src/libsyntax/tokenstream.rs30
-rw-r--r--src/libtest/lib.rs17
-rw-r--r--src/test/compile-fail/issue-39687.rs16
-rw-r--r--src/test/compile-fail/issue-43105.rs21
-rw-r--r--src/test/compile-fail/static-drop-scope.rs10
-rw-r--r--src/test/run-make/linker-output-non-utf8/Makefile16
-rw-r--r--src/test/run-pass/impl-trait/example-calendar.rs61
-rw-r--r--src/test/run-pass/issue-36792.rs17
-rw-r--r--src/test/run-pass/issue-38091.rs29
-rw-r--r--src/test/run-pass/issue-42148.rs (renamed from src/test/compile-fail/directory_ownership/backcompat-warnings.rs)11
-rw-r--r--src/test/run-pass/issue-42956.rs33
-rw-r--r--src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs (renamed from src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs)0
-rw-r--r--src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs (renamed from src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs)0
-rw-r--r--src/test/ui/non_modrs_mods/non_modrs_mods.stderr11
-rw-r--r--src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs (renamed from src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs)0
-rw-r--r--src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs (renamed from src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs)0
-rw-r--r--src/tools/build-manifest/src/main.rs1
-rw-r--r--src/tools/compiletest/src/runtest.rs115
56 files changed, 489 insertions, 224 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock
index f2fef632035..8fbf3535264 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -194,7 +194,7 @@ dependencies = [
  "hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "libgit2-sys 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -928,7 +928,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "jobserver"
-version = "0.1.8"
+version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1711,7 +1711,7 @@ dependencies = [
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fmt_macros 0.0.0",
  "graphviz 0.0.0",
- "jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_apfloat 0.0.0",
  "rustc_back 0.0.0",
@@ -2057,7 +2057,7 @@ dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
@@ -2862,7 +2862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3fcaf2365eb14b28ec7603c98c06cc531f19de9eb283d89a3dff8417c8c99f5"
 "checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21"
 "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c"
-"checksum jobserver 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "931b04e5e57d88cc909528f0d701db36a870b72a052648ded8baf80f9f445e0f"
+"checksum jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "565f6106bd87b394398f813bea4e5ecad6d6b0f6aa077592d088f882a506481d"
 "checksum json 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)" = "39ebf0fac977ee3a4a3242b6446004ff64514889e3e2730bbd4f764a67a2e483"
 "checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index 48ca2838e4f..aa9fe459e88 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -108,6 +108,8 @@ v("musl-root", "target.x86_64-unknown-linux-musl.musl-root",
   "MUSL root installation directory (deprecated)")
 v("musl-root-x86_64", "target.x86_64-unknown-linux-musl.musl-root",
   "x86_64-unknown-linux-musl install directory")
+v("musl-root-i586", "target.i586-unknown-linux-musl.musl-root",
+  "i586-unknown-linux-musl install directory")
 v("musl-root-i686", "target.i686-unknown-linux-musl.musl-root",
   "i686-unknown-linux-musl install directory")
 v("musl-root-arm", "target.arm-unknown-linux-musleabi.musl-root",
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index a5408ee381b..ba8cf3a8e2e 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -429,6 +429,8 @@ impl Step for Openssl {
             "arm-unknown-linux-gnueabihf" => "linux-armv4",
             "armv7-linux-androideabi" => "android-armv7",
             "armv7-unknown-linux-gnueabihf" => "linux-armv4",
+            "i586-unknown-linux-gnu" => "linux-elf",
+            "i586-unknown-linux-musl" => "linux-elf",
             "i686-apple-darwin" => "darwin-i386-cc",
             "i686-linux-android" => "android-x86",
             "i686-unknown-freebsd" => "BSD-x86-elf",
diff --git a/src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile b/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile
index c59476fab00..4c9d4b3ba78 100644
--- a/src/ci/docker/dist-i586-gnu-i686-musl/Dockerfile
+++ b/src/ci/docker/dist-i586-gnu-i586-i686-musl/Dockerfile
@@ -21,6 +21,9 @@ COPY scripts/musl.sh /build/
 RUN CC=gcc CFLAGS="-m32 -fPIC -Wa,-mrelax-relocations=no" \
     CXX=g++ CXXFLAGS="-m32 -Wa,-mrelax-relocations=no" \
     bash musl.sh i686 --target=i686 && \
+    CC=gcc CFLAGS="-march=pentium -m32 -fPIC -Wa,-mrelax-relocations=no" \
+    CXX=g++ CXXFLAGS="-march=pentium -m32 -Wa,-mrelax-relocations=no" \
+    bash musl.sh i586 --target=i586 && \
     rm -rf /build
 
 COPY scripts/sccache.sh /scripts/
@@ -28,6 +31,7 @@ RUN sh /scripts/sccache.sh
 
 ENV RUST_CONFIGURE_ARGS \
       --target=i686-unknown-linux-musl,i586-unknown-linux-gnu \
+      --musl-root-i586=/musl-i586 \
       --musl-root-i686=/musl-i686 \
       --enable-extended
 
@@ -38,12 +42,13 @@ ENV RUST_CONFIGURE_ARGS \
 # See: https://github.com/rust-lang/rust/issues/34978
 ENV CFLAGS_i686_unknown_linux_musl=-Wa,-mrelax-relocations=no
 ENV CFLAGS_i586_unknown_linux_gnu=-Wa,-mrelax-relocations=no
+# FIXME remove -Wl,-melf_i386 after cc is updated to include
+#       https://github.com/alexcrichton/cc-rs/pull/281
+ENV CFLAGS_i586_unknown_linux_musl="-Wa,-mrelax-relocations=no -Wl,-melf_i386"
+
+ENV TARGETS=i586-unknown-linux-gnu
+ENV TARGETS=$TARGETS,i686-unknown-linux-musl
 
 ENV SCRIPT \
-      python2.7 ../x.py test \
-          --target i686-unknown-linux-musl \
-          --target i586-unknown-linux-gnu \
-          && \
-      python2.7 ../x.py dist \
-          --target i686-unknown-linux-musl \
-          --target i586-unknown-linux-gnu
+      python2.7 ../x.py test --target $TARGETS && \
+      python2.7 ../x.py dist --target $TARGETS,i586-unknown-linux-musl
diff --git a/src/ci/docker/scripts/musl.sh b/src/ci/docker/scripts/musl.sh
index b704e37d592..7a7233216a3 100644
--- a/src/ci/docker/scripts/musl.sh
+++ b/src/ci/docker/scripts/musl.sh
@@ -30,7 +30,7 @@ exit 1
 TAG=$1
 shift
 
-MUSL=musl-1.1.17
+MUSL=musl-1.1.18
 
 # may have been downloaded in a previous run
 if [ ! -d $MUSL ]; then
@@ -39,7 +39,7 @@ fi
 
 cd $MUSL
 ./configure --disable-shared --prefix=/musl-$TAG $@
-if [ "$TAG" = "i686" ]; then
+if [ "$TAG" = "i586" -o "$TAG" = "i686" ]; then
   hide_output make -j$(nproc) AR=ar RANLIB=ranlib
 else
   hide_output make -j$(nproc)
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index e635df52040..72fa3148fe5 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -69,7 +69,9 @@ struct TypedArenaChunk<T> {
 impl<T> TypedArenaChunk<T> {
     #[inline]
     unsafe fn new(capacity: usize) -> TypedArenaChunk<T> {
-        TypedArenaChunk { storage: RawVec::with_capacity(capacity) }
+        TypedArenaChunk {
+            storage: RawVec::with_capacity(capacity),
+        }
     }
 
     /// Destroys this arena chunk.
@@ -132,7 +134,9 @@ impl<T> TypedArena<T> {
 
         unsafe {
             if mem::size_of::<T>() == 0 {
-                self.ptr.set(intrinsics::arith_offset(self.ptr.get() as *mut u8, 1) as *mut T);
+                self.ptr
+                    .set(intrinsics::arith_offset(self.ptr.get() as *mut u8, 1)
+                        as *mut T);
                 let ptr = mem::align_of::<T>() as *mut T;
                 // Don't drop the object. This `write` is equivalent to `forget`.
                 ptr::write(ptr, object);
@@ -157,7 +161,9 @@ impl<T> TypedArena<T> {
     ///  - Zero-length slices
     #[inline]
     pub fn alloc_slice(&self, slice: &[T]) -> &mut [T]
-        where T: Copy {
+    where
+        T: Copy,
+    {
         assert!(mem::size_of::<T>() != 0);
         assert!(slice.len() != 0);
 
@@ -321,7 +327,10 @@ impl DroplessArena {
             let (chunk, mut new_capacity);
             if let Some(last_chunk) = chunks.last_mut() {
                 let used_bytes = self.ptr.get() as usize - last_chunk.start() as usize;
-                if last_chunk.storage.reserve_in_place(used_bytes, needed_bytes) {
+                if last_chunk
+                    .storage
+                    .reserve_in_place(used_bytes, needed_bytes)
+                {
                     self.end.set(last_chunk.end());
                     return;
                 } else {
@@ -357,9 +366,9 @@ impl DroplessArena {
 
             let ptr = self.ptr.get();
             // Set the pointer past ourselves
-            self.ptr.set(intrinsics::arith_offset(
-                    self.ptr.get(), mem::size_of::<T>() as isize
-            ) as *mut u8);
+            self.ptr.set(
+                intrinsics::arith_offset(self.ptr.get(), mem::size_of::<T>() as isize) as *mut u8,
+            );
             // Write into uninitialized memory.
             ptr::write(ptr as *mut T, object);
             &mut *(ptr as *mut T)
@@ -375,7 +384,9 @@ impl DroplessArena {
     ///  - Zero-length slices
     #[inline]
     pub fn alloc_slice<T>(&self, slice: &[T]) -> &mut [T]
-        where T: Copy {
+    where
+        T: Copy,
+    {
         assert!(!mem::needs_drop::<T>());
         assert!(mem::size_of::<T>() != 0);
         assert!(slice.len() != 0);
@@ -391,7 +402,8 @@ impl DroplessArena {
         unsafe {
             let arena_slice = slice::from_raw_parts_mut(self.ptr.get() as *mut T, slice.len());
             self.ptr.set(intrinsics::arith_offset(
-                    self.ptr.get(), (slice.len() * mem::size_of::<T>()) as isize
+                self.ptr.get(),
+                (slice.len() * mem::size_of::<T>()) as isize,
             ) as *mut u8);
             arena_slice.copy_from_slice(slice);
             arena_slice
@@ -456,8 +468,9 @@ mod tests {
 
         let arena = Wrap(TypedArena::new());
 
-        let result =
-            arena.alloc_outer(|| Outer { inner: arena.alloc_inner(|| Inner { value: 10 }) });
+        let result = arena.alloc_outer(|| Outer {
+            inner: arena.alloc_inner(|| Inner { value: 10 }),
+        });
 
         assert_eq!(result.inner.value, 10);
     }
diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs
index 7eb5ff98857..587dcbe6d67 100644
--- a/src/libcore/tests/num/mod.rs
+++ b/src/libcore/tests/num/mod.rs
@@ -197,7 +197,6 @@ test_impl_from! { test_u16f64, u16, f64 }
 test_impl_from! { test_u32f64, u32, f64 }
 
 // Float -> Float
-#[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
 #[test]
 fn test_f32f64() {
     use core::f32;
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 44f23c11b04..075ee0b8c7c 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -48,6 +48,7 @@
 #![feature(drain_filter)]
 #![feature(dyn_trait)]
 #![feature(from_ref)]
+#![feature(fs_read_write)]
 #![feature(i128)]
 #![feature(i128_type)]
 #![feature(inclusive_range)]
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 32ab458cb91..5336c1944e8 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -1046,7 +1046,7 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) {
     // calculated the lint levels for all AST nodes.
     for (_id, lints) in cx.buffered.map {
         for early_lint in lints {
-            span_bug!(early_lint.span, "failed to process bufferd lint here");
+            span_bug!(early_lint.span, "failed to process buffered lint here");
         }
     }
 }
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index 29af9bb668e..2971f3e853a 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -218,13 +218,10 @@ pub fn record_time<T, F>(accu: &Cell<Duration>, f: F) -> T where
 // Memory reporting
 #[cfg(unix)]
 fn get_resident() -> Option<usize> {
-    use std::fs::File;
-    use std::io::Read;
+    use std::fs;
 
     let field = 1;
-    let mut f = File::open("/proc/self/statm").ok()?;
-    let mut contents = String::new();
-    f.read_to_string(&mut contents).ok()?;
+    let contents = fs::read_string("/proc/self/statm").ok()?;
     let s = contents.split_whitespace().nth(field)?;
     let npages = s.parse::<usize>().ok()?;
     Some(npages * 4096)
diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs
index ccf1db778d2..8bf60b091a7 100644
--- a/src/librustc_back/lib.rs
+++ b/src/librustc_back/lib.rs
@@ -28,6 +28,7 @@
 
 #![feature(box_syntax)]
 #![feature(const_fn)]
+#![feature(fs_read_write)]
 
 extern crate syntax;
 extern crate rand;
diff --git a/src/librustc_back/target/i586_unknown_linux_musl.rs b/src/librustc_back/target/i586_unknown_linux_musl.rs
new file mode 100644
index 00000000000..416eacf475b
--- /dev/null
+++ b/src/librustc_back/target/i586_unknown_linux_musl.rs
@@ -0,0 +1,18 @@
+// 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 target::TargetResult;
+
+pub fn target() -> TargetResult {
+    let mut base = super::i686_unknown_linux_musl::target()?;
+    base.options.cpu = "pentium".to_string();
+    base.llvm_target = "i586-unknown-linux-musl".to_string();
+    Ok(base)
+}
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index 6fcdedfb340..b65b18d0caa 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -47,7 +47,6 @@
 use serialize::json::{Json, ToJson};
 use std::collections::BTreeMap;
 use std::default::Default;
-use std::io::prelude::*;
 use syntax::abi::{Abi, lookup as lookup_abi};
 
 use {LinkerFlavor, PanicStrategy, RelroLevel};
@@ -147,6 +146,7 @@ supported_targets! {
     ("powerpc64-unknown-linux-gnu", powerpc64_unknown_linux_gnu),
     ("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu),
     ("s390x-unknown-linux-gnu", s390x_unknown_linux_gnu),
+    ("sparc64-unknown-linux-gnu", sparc64_unknown_linux_gnu),
     ("arm-unknown-linux-gnueabi", arm_unknown_linux_gnueabi),
     ("arm-unknown-linux-gnueabihf", arm_unknown_linux_gnueabihf),
     ("arm-unknown-linux-musleabi", arm_unknown_linux_musleabi),
@@ -156,16 +156,17 @@ supported_targets! {
     ("armv7-unknown-linux-gnueabihf", armv7_unknown_linux_gnueabihf),
     ("armv7-unknown-linux-musleabihf", armv7_unknown_linux_musleabihf),
     ("aarch64-unknown-linux-gnu", aarch64_unknown_linux_gnu),
+
     ("aarch64-unknown-linux-musl", aarch64_unknown_linux_musl),
     ("x86_64-unknown-linux-musl", x86_64_unknown_linux_musl),
     ("i686-unknown-linux-musl", i686_unknown_linux_musl),
+    ("i586-unknown-linux-musl", i586_unknown_linux_musl),
     ("mips-unknown-linux-musl", mips_unknown_linux_musl),
     ("mipsel-unknown-linux-musl", mipsel_unknown_linux_musl),
+
     ("mips-unknown-linux-uclibc", mips_unknown_linux_uclibc),
     ("mipsel-unknown-linux-uclibc", mipsel_unknown_linux_uclibc),
 
-    ("sparc64-unknown-linux-gnu", sparc64_unknown_linux_gnu),
-
     ("i686-linux-android", i686_linux_android),
     ("x86_64-linux-android", x86_64_linux_android),
     ("arm-linux-androideabi", arm_linux_androideabi),
@@ -809,14 +810,12 @@ impl Target {
     pub fn search(target: &str) -> Result<Target, String> {
         use std::env;
         use std::ffi::OsString;
-        use std::fs::File;
+        use std::fs;
         use std::path::{Path, PathBuf};
         use serialize::json;
 
         fn load_file(path: &Path) -> Result<Target, String> {
-            let mut f = File::open(path).map_err(|e| e.to_string())?;
-            let mut contents = Vec::new();
-            f.read_to_end(&mut contents).map_err(|e| e.to_string())?;
+            let contents = fs::read(path).map_err(|e| e.to_string())?;
             let obj = json::from_reader(&mut &contents[..])
                            .map_err(|e| e.to_string())?;
             Target::from_json(obj)
diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs
index cfbb9623f7d..3cfa1d6797d 100644
--- a/src/librustc_const_eval/pattern.rs
+++ b/src/librustc_const_eval/pattern.rs
@@ -280,7 +280,8 @@ impl<'a, 'tcx> Pattern<'tcx> {
         let mut pcx = PatternContext::new(tcx, param_env_and_substs, tables);
         let result = pcx.lower_pattern(pat);
         if !pcx.errors.is_empty() {
-            span_bug!(pat.span, "encountered errors lowering pattern: {:?}", pcx.errors)
+            let msg = format!("encountered errors lowering pattern: {:?}", pcx.errors);
+            tcx.sess.delay_span_bug(pat.span, &msg);
         }
         debug!("Pattern::from_hir({:?}) = {:?}", pat, result);
         result
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 8d3b2bc47ec..b7265762208 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -889,10 +889,11 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
     let dep_graph = match future_dep_graph {
         None => DepGraph::new_disabled(),
         Some(future) => {
-            let prev_graph = future
-                .open()
-                .expect("Could not join with background dep_graph thread")
-                .open(sess);
+            let prev_graph = time(time_passes, "blocked while dep-graph loading finishes", || {
+                future.open()
+                      .expect("Could not join with background dep_graph thread")
+                      .open(sess)
+            });
             DepGraph::new(prev_graph)
         }
     };
diff --git a/src/librustc_incremental/assert_dep_graph.rs b/src/librustc_incremental/assert_dep_graph.rs
index 9fa29380dc6..5976b80d90f 100644
--- a/src/librustc_incremental/assert_dep_graph.rs
+++ b/src/librustc_incremental/assert_dep_graph.rs
@@ -55,7 +55,7 @@ use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc::ich::{ATTR_IF_THIS_CHANGED, ATTR_THEN_THIS_WOULD_NEED};
 use graphviz::IntoCow;
 use std::env;
-use std::fs::File;
+use std::fs::{self, File};
 use std::io::Write;
 use syntax::ast;
 use syntax_pos::Span;
@@ -260,7 +260,7 @@ fn dump_graph(tcx: TyCtxt) {
         let dot_path = format!("{}.dot", path);
         let mut v = Vec::new();
         dot::render(&GraphvizDepGraph(nodes, edges), &mut v).unwrap();
-        File::create(&dot_path).and_then(|mut f| f.write_all(&v)).unwrap();
+        fs::write(dot_path, v).unwrap();
     }
 }
 
diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs
index 5eaf8553ee3..0b827a0ee98 100644
--- a/src/librustc_incremental/lib.rs
+++ b/src/librustc_incremental/lib.rs
@@ -16,6 +16,7 @@
 #![deny(warnings)]
 
 #![feature(conservative_impl_trait)]
+#![feature(fs_read_write)]
 #![feature(i128_type)]
 #![feature(inclusive_range_syntax)]
 #![feature(specialization)]
diff --git a/src/librustc_incremental/persist/file_format.rs b/src/librustc_incremental/persist/file_format.rs
index 108eccf047e..d45994adeb6 100644
--- a/src/librustc_incremental/persist/file_format.rs
+++ b/src/librustc_incremental/persist/file_format.rs
@@ -21,7 +21,7 @@
 
 use std::io::{self, Read};
 use std::path::Path;
-use std::fs::File;
+use std::fs;
 use std::env;
 
 use rustc::session::config::nightly_options;
@@ -66,11 +66,7 @@ pub fn read_file(report_incremental_info: bool, path: &Path)
         return Ok(None);
     }
 
-    let mut file = File::open(path)?;
-    let file_size = file.metadata()?.len() as usize;
-
-    let mut data = Vec::with_capacity(file_size);
-    file.read_to_end(&mut data)?;
+    let data = fs::read(path)?;
 
     let mut file = io::Cursor::new(data);
 
diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs
index e51587e1cd3..d44d1d6f260 100644
--- a/src/librustc_incremental/persist/save.rs
+++ b/src/librustc_incremental/persist/save.rs
@@ -15,8 +15,8 @@ use rustc::util::common::time;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_serialize::Encodable as RustcEncodable;
 use rustc_serialize::opaque::Encoder;
-use std::io::{self, Cursor, Write};
-use std::fs::{self, File};
+use std::io::{self, Cursor};
+use std::fs;
 use std::path::PathBuf;
 
 use super::data::*;
@@ -125,7 +125,7 @@ fn save_in<F>(sess: &Session, path_buf: PathBuf, encode: F)
 
     // write the data out
     let data = wr.into_inner();
-    match File::create(&path_buf).and_then(|mut file| file.write_all(&data)) {
+    match fs::write(&path_buf, data) {
         Ok(_) => {
             debug!("save: data written to disk successfully");
         }
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 18117533c18..33075e40432 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -15,6 +15,7 @@
 
 #![feature(box_patterns)]
 #![feature(conservative_impl_trait)]
+#![feature(fs_read_write)]
 #![feature(i128_type)]
 #![feature(libc)]
 #![feature(proc_macro_internals)]
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index 90c469eea84..e0fb924f1aa 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -237,7 +237,7 @@ use rustc_back::target::Target;
 
 use std::cmp;
 use std::fmt;
-use std::fs::{self, File};
+use std::fs;
 use std::io::{self, Read};
 use std::path::{Path, PathBuf};
 use std::time::Instant;
@@ -870,10 +870,7 @@ fn get_metadata_section_imp(target: &Target,
             }
         }
         CrateFlavor::Rmeta => {
-            let mut file = File::open(filename).map_err(|_|
-                format!("could not open file: '{}'", filename.display()))?;
-            let mut buf = vec![];
-            file.read_to_end(&mut buf).map_err(|_|
+            let buf = fs::read(filename).map_err(|_|
                 format!("failed to read rmeta metadata: '{}'", filename.display()))?;
             OwningRef::new(buf).map_owner_box().erase_owner()
         }
diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs
index b79e044b24f..fb3cb1518cb 100644
--- a/src/librustc_mir/dataflow/graphviz.rs
+++ b/src/librustc_mir/dataflow/graphviz.rs
@@ -18,7 +18,7 @@ use rustc_data_structures::indexed_vec::Idx;
 use dot;
 use dot::IntoCow;
 
-use std::fs::File;
+use std::fs;
 use std::io;
 use std::io::prelude::*;
 use std::marker::PhantomData;
@@ -67,7 +67,7 @@ pub(crate) fn print_borrowck_graph_to<'a, 'tcx, BD, P>(
     dot::render(&g, &mut v)?;
     debug!("print_borrowck_graph_to path: {} node_id: {}",
            path.display(), mbcx.node_id);
-    File::create(path).and_then(|mut f| f.write_all(&v))
+    fs::write(path, v)
 }
 
 pub type Node = BasicBlock;
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index e9e7e688f1f..5379bf3f5a7 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -24,6 +24,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 #![feature(core_intrinsics)]
 #![feature(decl_macro)]
 #![feature(dyn_trait)]
+#![feature(fs_read_write)]
 #![feature(i128_type)]
 #![feature(inclusive_range_syntax)]
 #![feature(inclusive_range)]
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index f0871bb188d..b896e6ca853 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -122,7 +122,6 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     return_qualif: Option<Qualif>,
     qualif: Qualif,
     const_fn_arg_vars: BitVector,
-    local_needs_drop: IndexVec<Local, Option<Span>>,
     temp_promotion_state: IndexVec<Local, TempState>,
     promotion_candidates: Vec<Candidate>
 }
@@ -136,6 +135,16 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
         let mut rpo = traversal::reverse_postorder(mir);
         let temps = promote_consts::collect_temps(mir, &mut rpo);
         rpo.reset();
+
+        let param_env = tcx.param_env(def_id);
+
+        let mut temp_qualif = IndexVec::from_elem(None, &mir.local_decls);
+        for arg in mir.args_iter() {
+            let mut qualif = Qualif::NEEDS_DROP;
+            qualif.restrict(mir.local_decls[arg].ty, tcx, param_env);
+            temp_qualif[arg] = Some(qualif);
+        }
+
         Qualifier {
             mode,
             span: mir.span,
@@ -143,12 +152,11 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
             mir,
             rpo,
             tcx,
-            param_env: tcx.param_env(def_id),
-            temp_qualif: IndexVec::from_elem(None, &mir.local_decls),
+            param_env,
+            temp_qualif,
             return_qualif: None,
             qualif: Qualif::empty(),
             const_fn_arg_vars: BitVector::new(mir.local_decls.len()),
-            local_needs_drop: IndexVec::from_elem(None, &mir.local_decls),
             temp_promotion_state: temps,
             promotion_candidates: vec![]
         }
@@ -255,15 +263,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
             return;
         }
 
-        // When initializing a local, record whether the *value* being
-        // stored in it needs dropping, which it may not, even if its
-        // type does, e.g. `None::<String>`.
-        if let Place::Local(local) = *dest {
-            if qualif.intersects(Qualif::NEEDS_DROP) {
-                self.local_needs_drop[local] = Some(self.span);
-            }
-        }
-
         match *dest {
             Place::Local(index) if self.mir.local_kind(index) == LocalKind::Temp => {
                 debug!("store to temp {:?}", index);
@@ -424,17 +423,20 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                    &local: &Local,
                    _: PlaceContext<'tcx>,
                    _: Location) {
-        match self.mir.local_kind(local) {
+        let kind = self.mir.local_kind(local);
+        match kind {
             LocalKind::ReturnPointer => {
                 self.not_const();
             }
-            LocalKind::Arg => {
-                self.add(Qualif::FN_ARGUMENT);
-            }
             LocalKind::Var => {
                 self.add(Qualif::NOT_CONST);
             }
+            LocalKind::Arg |
             LocalKind::Temp => {
+                if let LocalKind::Arg = kind {
+                    self.add(Qualif::FN_ARGUMENT);
+                }
+
                 if !self.temp_promotion_state[local].is_promotable() {
                     self.add(Qualif::NOT_PROMOTABLE);
                 }
@@ -529,16 +531,18 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
 
     fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
         match *operand {
-            Operand::Copy(ref place) |
-            Operand::Move(ref place) => {
+            Operand::Copy(_) |
+            Operand::Move(_) => {
                 self.nest(|this| {
                     this.super_operand(operand, location);
                     this.try_consume();
                 });
 
                 // Mark the consumed locals to indicate later drops are noops.
-                if let Place::Local(local) = *place {
-                    self.local_needs_drop[local] = None;
+                if let Operand::Move(Place::Local(local)) = *operand {
+                    self.temp_qualif[local] = self.temp_qualif[local].map(|q|
+                        q - Qualif::NEEDS_DROP
+                    );
                 }
             }
             Operand::Constant(ref constant) => {
@@ -847,9 +851,13 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                 // HACK(eddyb) Emulate a bit of dataflow analysis,
                 // conservatively, that drop elaboration will do.
                 let needs_drop = if let Place::Local(local) = *place {
-                    self.local_needs_drop[local]
+                    if self.temp_qualif[local].map_or(true, |q| q.intersects(Qualif::NEEDS_DROP)) {
+                        Some(self.mir.local_decls[local].source_info.span)
+                    } else {
+                        None
+                    }
                 } else {
-                    None
+                    Some(self.span)
                 };
 
                 if let Some(span) = needs_drop {
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index c39faf021df..30e3c9c4ca8 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -1252,7 +1252,13 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
                          root_item: &'l ast::Item,
                          prefix: &ast::Path) {
         let path = &use_tree.prefix;
-        let access = access_from!(self.save_ctxt, root_item);
+
+        // The access is calculated using the current tree ID, but with the root tree's visibility
+        // (since nested trees don't have their own visibility).
+        let access = Access {
+            public: root_item.vis == ast::Visibility::Public,
+            reachable: self.save_ctxt.analysis.access_levels.is_reachable(id),
+        };
 
         // The parent def id of a given use tree is always the enclosing item.
         let parent = self.save_ctxt.tcx.hir.opt_local_def_id(id)
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index 42538c5a3ad..13a319d31bf 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -342,9 +342,7 @@ fn archive_config<'a>(sess: &'a Session,
 fn emit_metadata<'a>(sess: &'a Session, trans: &CrateTranslation, tmpdir: &TempDir)
                      -> PathBuf {
     let out_filename = tmpdir.path().join(METADATA_FILENAME);
-    let result = fs::File::create(&out_filename).and_then(|mut f| {
-        f.write_all(&trans.metadata.raw_data)
-    });
+    let result = fs::write(&out_filename, &trans.metadata.raw_data);
 
     if let Err(e) = result {
         sess.fatal(&format!("failed to write {}: {}", out_filename.display(), e));
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 4d1bcd9bf46..1ee04a46243 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -46,9 +46,8 @@ use rustc_demangle;
 
 use std::any::Any;
 use std::ffi::{CString, CStr};
-use std::fs::{self, File};
-use std::io;
-use std::io::{Read, Write};
+use std::fs;
+use std::io::{self, Write};
 use std::mem;
 use std::path::{Path, PathBuf};
 use std::str;
@@ -666,7 +665,7 @@ unsafe fn codegen(cgcx: &CodegenContext,
         timeline.record("make-bc");
 
         if write_bc {
-            if let Err(e) = File::create(&bc_out).and_then(|mut f| f.write_all(data)) {
+            if let Err(e) = fs::write(&bc_out, data) {
                 diag_handler.err(&format!("failed to write bytecode: {}", e));
             }
             timeline.record("write-bc");
@@ -675,7 +674,7 @@ unsafe fn codegen(cgcx: &CodegenContext,
         if config.emit_bc_compressed {
             let dst = bc_out.with_extension(RLIB_BYTECODE_EXTENSION);
             let data = bytecode::encode(&mtrans.llmod_id, data);
-            if let Err(e) = File::create(&dst).and_then(|mut f| f.write_all(&data)) {
+            if let Err(e) = fs::write(&dst, data) {
                 diag_handler.err(&format!("failed to write bytecode: {}", e));
             }
             timeline.record("compress-bc");
@@ -799,9 +798,7 @@ fn binaryen_assemble(cgcx: &CodegenContext,
                      object: &Path) {
     use rustc_binaryen::{Module, ModuleOptions};
 
-    let input = File::open(&assembly).and_then(|mut f| {
-        let mut contents = Vec::new();
-        f.read_to_end(&mut contents)?;
+    let input = fs::read(&assembly).and_then(|contents| {
         Ok(CString::new(contents)?)
     });
     let mut options = ModuleOptions::new();
@@ -818,7 +815,7 @@ fn binaryen_assemble(cgcx: &CodegenContext,
             .map_err(|e| io::Error::new(io::ErrorKind::Other, e))
     });
     let err = assembled.and_then(|binary| {
-        File::create(&object).and_then(|mut f| f.write_all(binary.data()))
+        fs::write(&object, binary.data())
     });
     if let Err(e) = err {
         handler.err(&format!("failed to run binaryen assembler: {}", e));
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index fd6cd5c371d..ee08a7f1ec4 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -22,6 +22,7 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(custom_attribute)]
+#![feature(fs_read_write)]
 #![allow(unused_attributes)]
 #![feature(i128_type)]
 #![feature(i128)]
diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs
index 2f7bd5e39a1..f8320330ad2 100644
--- a/src/librustdoc/externalfiles.rs
+++ b/src/librustdoc/externalfiles.rs
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::fs::File;
-use std::io::prelude::*;
+use std::fs;
 use std::path::Path;
 use std::str;
 use html::markdown::{Markdown, RenderType};
@@ -65,13 +64,13 @@ pub enum LoadStringError {
 
 pub fn load_string<P: AsRef<Path>>(file_path: P) -> Result<String, LoadStringError> {
     let file_path = file_path.as_ref();
-    let mut contents = vec![];
-    let result = File::open(file_path)
-                      .and_then(|mut f| f.read_to_end(&mut contents));
-    if let Err(e) = result {
-        eprintln!("error reading `{}`: {}", file_path.display(), e);
-        return Err(LoadStringError::ReadFail);
-    }
+    let contents = match fs::read(file_path) {
+        Ok(bytes) => bytes,
+        Err(e) => {
+            eprintln!("error reading `{}`: {}", file_path.display(), e);
+            return Err(LoadStringError::ReadFail);
+        }
+    };
     match str::from_utf8(&contents) {
         Ok(s) => Ok(s.to_string()),
         Err(_) => {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 7449c08fcd2..93a3035e06a 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -866,15 +866,8 @@ fn write_shared(cx: &Context,
     write(cx.dst.join("main.css"),
           include_bytes!("static/styles/main.css"))?;
     if let Some(ref css) = cx.shared.css_file_extension {
-        let mut content = String::new();
-        let css = css.as_path();
-        let mut f = try_err!(File::open(css), css);
-
-        try_err!(f.read_to_string(&mut content), css);
-        let css = cx.dst.join("theme.css");
-        let css = css.as_path();
-        let mut f = try_err!(File::create(css), css);
-        try_err!(write!(f, "{}", &content), css);
+        let out = cx.dst.join("theme.css");
+        try_err!(fs::copy(css, out), css);
     }
     write(cx.dst.join("normalize.css"),
           include_bytes!("static/normalize.css"))?;
@@ -1027,7 +1020,7 @@ fn render_sources(dst: &Path, scx: &mut SharedContext,
 /// Writes the entire contents of a string to a destination, not attempting to
 /// catch any errors.
 fn write(dst: PathBuf, contents: &[u8]) -> Result<(), Error> {
-    Ok(try_err!(try_err!(File::create(&dst), &dst).write_all(contents), &dst))
+    Ok(try_err!(fs::write(&dst, contents), &dst))
 }
 
 /// Takes a path to a source file and cleans the path to it. This canonicalizes
@@ -1124,16 +1117,13 @@ impl<'a> SourceCollector<'a> {
             return Ok(());
         }
 
-        let mut contents = Vec::new();
-        File::open(&p).and_then(|mut f| f.read_to_end(&mut contents))?;
-
-        let contents = str::from_utf8(&contents).unwrap();
+        let contents = fs::read_string(&p)?;
 
         // Remove the utf-8 BOM if any
         let contents = if contents.starts_with("\u{feff}") {
             &contents[3..]
         } else {
-            contents
+            &contents[..]
         };
 
         // Create the intermediate directories
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 1740816ef6b..3b43eafb849 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -18,6 +18,7 @@
 #![feature(rustc_private)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
+#![feature(fs_read_write)]
 #![feature(libc)]
 #![feature(set_stdio)]
 #![feature(slice_patterns)]
diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs
index a75596351e4..a37a5e8ae82 100644
--- a/src/libstd/ffi/mod.rs
+++ b/src/libstd/ffi/mod.rs
@@ -53,7 +53,7 @@
 //! terminator, so the buffer length is really `len+1` characters.
 //! Rust strings don't have a nul terminator; their length is always
 //! stored and does not need to be calculated. While in Rust
-//! accessing a string's length is a O(1) operation (becasue the
+//! accessing a string's length is a O(1) operation (because the
 //! length is stored); in C it is an O(length) operation because the
 //! length needs to be computed by scanning the string for the nul
 //! terminator.
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 109173d31c5..3959e8533be 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -36,7 +36,7 @@ use sys_common::{AsInner, IntoInner, FromInner};
 /// and platform-native string values, and in particular allowing a Rust string
 /// to be converted into an "OS" string with no cost if possible.
 ///
-/// `OsString` is to [`OsStr`] as [`String`] is to [`&str`]: the former
+/// `OsString` is to [`&OsStr`] as [`String`] is to [`&str`]: the former
 /// in each pair are owned strings; the latter are borrowed
 /// references.
 ///
@@ -64,6 +64,7 @@ use sys_common::{AsInner, IntoInner, FromInner};
 /// the traits which `OsString` implements for conversions from/to native representations.
 ///
 /// [`OsStr`]: struct.OsStr.html
+/// [`&OsStr`]: struct.OsStr.html
 /// [`From`]: ../convert/trait.From.html
 /// [`String`]: ../string/struct.String.html
 /// [`&str`]: ../primitive.str.html
@@ -84,13 +85,15 @@ pub struct OsString {
 /// This type represents a borrowed reference to a string in the operating system's preferred
 /// representation.
 ///
-/// `OsStr` is to [`OsString`] as [`String`] is to [`&str`]: the former in each pair are borrowed
+/// `&OsStr` is to [`OsString`] as [`&str`] is to [`String`]: the former in each pair are borrowed
 /// references; the latter are owned strings.
 ///
 /// See the [module's toplevel documentation about conversions][conversions] for a discussion on
 /// the traits which `OsStr` implements for conversions from/to native representations.
 ///
 /// [`OsString`]: struct.OsString.html
+/// [`&str`]: ../primitive.str.html
+/// [`String`]: ../string/struct.String.html
 /// [conversions]: index.html#conversions
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct OsStr {
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index f40aed2478a..51cb9609120 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -211,6 +211,14 @@ pub struct DirBuilder {
     recursive: bool,
 }
 
+/// How large a buffer to pre-allocate before reading the entire file at `path`.
+fn initial_buffer_size<P: AsRef<Path>>(path: P) -> usize {
+    // Allocate one extra byte so the buffer doesn't need to grow before the
+    // final `read` call at the end of the file.  Don't worry about `usize`
+    // overflow because reading will fail regardless in that case.
+    metadata(path).map(|m| m.len() as usize + 1).unwrap_or(0)
+}
+
 /// Read the entire contents of a file into a bytes vector.
 ///
 /// This is a convenience function for using [`File::open`] and [`read_to_end`]
@@ -246,7 +254,7 @@ pub struct DirBuilder {
 /// ```
 #[unstable(feature = "fs_read_write", issue = "46588")]
 pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
-    let mut bytes = Vec::new();
+    let mut bytes = Vec::with_capacity(initial_buffer_size(&path));
     File::open(path)?.read_to_end(&mut bytes)?;
     Ok(bytes)
 }
@@ -287,7 +295,7 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
 /// ```
 #[unstable(feature = "fs_read_write", issue = "46588")]
 pub fn read_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
-    let mut string = String::new();
+    let mut string = String::with_capacity(initial_buffer_size(&path));
     File::open(path)?.read_to_string(&mut string)?;
     Ok(string)
 }
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index bed9efcb846..e8297c20af3 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -576,6 +576,13 @@ impl<'a> AsRef<OsStr> for Component<'a> {
     }
 }
 
+#[stable(feature = "path_component_asref", since = "1.24.0")]
+impl<'a> AsRef<Path> for Component<'a> {
+    fn as_ref(&self) -> &Path {
+        self.as_os_str().as_ref()
+    }
+}
+
 /// An iterator over the [`Component`]s of a [`Path`].
 ///
 /// This `struct` is created by the [`components`] method on [`Path`].
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index 0f3f4e50f7e..2edf02efc47 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -36,7 +36,7 @@ use sys_common::rwlock as sys;
 /// required that `T` satisfies [`Send`] to be shared across threads and
 /// [`Sync`] to allow concurrent access through readers. The RAII guards
 /// returned from the locking methods implement [`Deref`][] (and [`DerefMut`]
-/// for the `write` methods) to allow access to the contained of the lock.
+/// for the `write` methods) to allow access to the content of the lock.
 ///
 /// # Poisoning
 ///
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index 15ddb62bab5..cb5bfb9176e 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -206,7 +206,7 @@ impl Duration {
     ///
     /// let duration = Duration::from_millis(5432);
     /// assert_eq!(duration.as_secs(), 5);
-    /// assert_eq!(duration.subsec_nanos(), 432_000_000);
+    /// assert_eq!(duration.subsec_millis(), 432);
     /// ```
     #[unstable(feature = "duration_extras", issue = "46507")]
     #[inline]
@@ -226,7 +226,7 @@ impl Duration {
     ///
     /// let duration = Duration::from_micros(1_234_567);
     /// assert_eq!(duration.as_secs(), 1);
-    /// assert_eq!(duration.subsec_nanos(), 234_567_000);
+    /// assert_eq!(duration.subsec_micros(), 234_567);
     /// ```
     #[unstable(feature = "duration_extras", issue = "46507")]
     #[inline]
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index b61c39d589b..49035203150 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -5894,10 +5894,14 @@ impl<'a> Parser<'a> {
         if let Some(path) = Parser::submod_path_from_attr(outer_attrs, &self.directory.path) {
             return Ok(ModulePathSuccess {
                 directory_ownership: match path.file_name().and_then(|s| s.to_str()) {
-                    Some("mod.rs") => DirectoryOwnership::Owned { relative: None },
-                    Some(_) => {
-                        DirectoryOwnership::Owned { relative: Some(id) }
-                    }
+                    // All `#[path]` files are treated as though they are a `mod.rs` file.
+                    // This means that `mod foo;` declarations inside `#[path]`-included
+                    // files are siblings,
+                    //
+                    // Note that this will produce weirdness when a file named `foo.rs` is
+                    // `#[path]` included and contains a `mod foo;` declaration.
+                    // If you encounter this, it's your own darn fault :P
+                    Some(_) => DirectoryOwnership::Owned { relative: None },
                     _ => DirectoryOwnership::UnownedViaMod(true),
                 },
                 path,
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index 870f54e4396..ad04b6ab2b5 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -286,12 +286,12 @@ impl TokenStream {
         TokenStream::concat(result)
     }
 
-    fn first_tree(&self) -> Option<TokenTree> {
+    fn first_tree_and_joint(&self) -> Option<(TokenTree, bool)> {
         match self.kind {
             TokenStreamKind::Empty => None,
-            TokenStreamKind::Tree(ref tree) |
-            TokenStreamKind::JointTree(ref tree) => Some(tree.clone()),
-            TokenStreamKind::Stream(ref stream) => stream.first().unwrap().first_tree(),
+            TokenStreamKind::Tree(ref tree) => Some((tree.clone(), false)),
+            TokenStreamKind::JointTree(ref tree) => Some((tree.clone(), true)),
+            TokenStreamKind::Stream(ref stream) => stream.first().unwrap().first_tree_and_joint(),
         }
     }
 
@@ -315,12 +315,18 @@ impl TokenStreamBuilder {
         let stream = stream.into();
         let last_tree_if_joint = self.0.last().and_then(TokenStream::last_tree_if_joint);
         if let Some(TokenTree::Token(last_span, last_tok)) = last_tree_if_joint {
-            if let Some(TokenTree::Token(span, tok)) = stream.first_tree() {
+            if let Some((TokenTree::Token(span, tok), is_joint)) = stream.first_tree_and_joint() {
                 if let Some(glued_tok) = last_tok.glue(tok) {
                     let last_stream = self.0.pop().unwrap();
                     self.push_all_but_last_tree(&last_stream);
                     let glued_span = last_span.to(span);
-                    self.0.push(TokenTree::Token(glued_span, glued_tok).into());
+                    let glued_tt = TokenTree::Token(glued_span, glued_tok);
+                    let glued_tokenstream = if is_joint {
+                        glued_tt.joint()
+                    } else {
+                        glued_tt.into()
+                    };
+                    self.0.push(glued_tokenstream);
                     self.push_all_but_first_tree(&stream);
                     return
                 }
@@ -669,4 +675,16 @@ mod tests {
         assert_eq!(test1.is_empty(), false);
         assert_eq!(test2.is_empty(), false);
     }
+
+    #[test]
+    fn test_dotdotdot() {
+        let mut builder = TokenStreamBuilder::new();
+        builder.push(TokenTree::Token(sp(0, 1), Token::Dot).joint());
+        builder.push(TokenTree::Token(sp(1, 2), Token::Dot).joint());
+        builder.push(TokenTree::Token(sp(2, 3), Token::Dot));
+        let stream = builder.build();
+        assert!(stream.eq_unspanned(&string_to_ts("...")));
+        assert_eq!(stream.trees().count(), 1);
+    }
+
 }
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 76557982a02..f7880d3c4d8 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -36,14 +36,14 @@
 
 #![feature(asm)]
 #![feature(fnbox)]
-#![cfg_attr(unix, feature(libc))]
+#![cfg_attr(any(unix, target_os = "cloudabi"), feature(libc))]
 #![feature(set_stdio)]
 #![feature(panic_unwind)]
 #![feature(staged_api)]
 
 extern crate getopts;
 extern crate term;
-#[cfg(unix)]
+#[cfg(any(unix, target_os = "cloudabi"))]
 extern crate libc;
 extern crate panic_unwind;
 
@@ -1191,13 +1191,14 @@ fn get_concurrency() -> usize {
         1
     }
 
-    #[cfg(any(target_os = "linux",
-              target_os = "macos",
-              target_os = "ios",
-              target_os = "android",
-              target_os = "solaris",
+    #[cfg(any(target_os = "android",
+              target_os = "cloudabi",
               target_os = "emscripten",
-              target_os = "fuchsia"))]
+              target_os = "fuchsia",
+              target_os = "ios",
+              target_os = "linux",
+              target_os = "macos",
+              target_os = "solaris"))]
     fn num_cpus() -> usize {
         unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize }
     }
diff --git a/src/test/compile-fail/issue-39687.rs b/src/test/compile-fail/issue-39687.rs
new file mode 100644
index 00000000000..404465e6a0f
--- /dev/null
+++ b/src/test/compile-fail/issue-39687.rs
@@ -0,0 +1,16 @@
+// Copyright 2018 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(fn_traits)]
+
+fn main() {
+    <fn() as Fn()>::call;
+    //~^ ERROR associated type bindings are not allowed here [E0229]
+}
diff --git a/src/test/compile-fail/issue-43105.rs b/src/test/compile-fail/issue-43105.rs
new file mode 100644
index 00000000000..fb419d751b4
--- /dev/null
+++ b/src/test/compile-fail/issue-43105.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 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 xyz() -> u8 { 42 }
+
+const NUM: u8 = xyz();
+//~^ ERROR calls in constants are limited to constant functions, struct and enum constructors
+
+fn main() {
+    match 1 {
+        NUM => unimplemented!(),
+        _ => unimplemented!(),
+    }
+}
diff --git a/src/test/compile-fail/static-drop-scope.rs b/src/test/compile-fail/static-drop-scope.rs
index c96cadece97..e22eb7e4484 100644
--- a/src/test/compile-fail/static-drop-scope.rs
+++ b/src/test/compile-fail/static-drop-scope.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(const_fn)]
+
 struct WithDtor;
 
 impl Drop for WithDtor {
@@ -28,4 +30,12 @@ static EARLY_DROP_S: i32 = (WithDtor, 0).1;
 const EARLY_DROP_C: i32 = (WithDtor, 0).1;
 //~^ ERROR destructors cannot be evaluated at compile-time
 
+const fn const_drop<T>(_: T) {}
+//~^ ERROR destructors cannot be evaluated at compile-time
+
+const fn const_drop2<T>(x: T) {
+    (x, ()).1
+    //~^ ERROR destructors cannot be evaluated at compile-time
+}
+
 fn main () {}
diff --git a/src/test/run-make/linker-output-non-utf8/Makefile b/src/test/run-make/linker-output-non-utf8/Makefile
index 76d4b133def..5f1577ab44d 100644
--- a/src/test/run-make/linker-output-non-utf8/Makefile
+++ b/src/test/run-make/linker-output-non-utf8/Makefile
@@ -2,15 +2,16 @@
 
 # Make sure we don't ICE if the linker prints a non-UTF-8 error message.
 
-ifdef IS_WINDOWS
-# ignore windows
+# Ignore Windows and Apple
 
 # This does not work in its current form on windows, possibly due to
 # gcc bugs or something about valid Windows paths.  See issue #29151
 # for more information.
-all:
+ifndef IS_WINDOWS
 
-else
+# This also does not work on Apple APFS due to the filesystem requiring
+# valid UTF-8 paths.
+ifneq ($(shell uname),Darwin)
 
 # The zzz it to allow humans to tab complete or glob this thing.
 bad_dir := $(TMPDIR)/zzz$$'\xff'
@@ -20,5 +21,12 @@ all:
 	mkdir $(bad_dir)
 	mv $(TMPDIR)/liblibrary.a $(bad_dir)
 	LIBRARY_PATH=$(bad_dir) $(RUSTC) exec.rs 2>&1 | $(CGREP) this_symbol_not_defined
+else
+all:
+
+endif
+
+else
+all:
 
 endif
diff --git a/src/test/run-pass/impl-trait/example-calendar.rs b/src/test/run-pass/impl-trait/example-calendar.rs
index 8d035bafab7..aca100591dd 100644
--- a/src/test/run-pass/impl-trait/example-calendar.rs
+++ b/src/test/run-pass/impl-trait/example-calendar.rs
@@ -15,7 +15,9 @@
            universal_impl_trait,
            fn_traits,
            step_trait,
-           unboxed_closures
+           unboxed_closures,
+           copy_closures,
+           clone_closures
 )]
 
 //! Derived from: <https://raw.githubusercontent.com/quickfur/dcal/master/dcal.d>.
@@ -234,42 +236,6 @@ impl Weekday {
     }
 }
 
-/// Wrapper for zero-sized closures.
-// HACK(eddyb) Only needed because closures can't implement Copy.
-struct Fn0<F>(std::marker::PhantomData<F>);
-
-impl<F> Copy for Fn0<F> {}
-impl<F> Clone for Fn0<F> {
-    fn clone(&self) -> Self { *self }
-}
-
-impl<F: FnOnce<A>, A> FnOnce<A> for Fn0<F> {
-    type Output = F::Output;
-
-    extern "rust-call" fn call_once(self, args: A) -> Self::Output {
-        let f = unsafe { std::mem::uninitialized::<F>() };
-        f.call_once(args)
-    }
-}
-
-impl<F: FnMut<A>, A> FnMut<A> for Fn0<F> {
-    extern "rust-call" fn call_mut(&mut self, args: A) -> Self::Output {
-        let mut f = unsafe { std::mem::uninitialized::<F>() };
-        f.call_mut(args)
-    }
-}
-
-trait AsFn0<A>: Sized {
-    fn copyable(self) -> Fn0<Self>;
-}
-
-impl<F: FnMut<A>, A> AsFn0<A> for F {
-    fn copyable(self) -> Fn0<Self> {
-        assert_eq!(std::mem::size_of::<F>(), 0);
-        Fn0(std::marker::PhantomData)
-    }
-}
-
 /// GroupBy implementation.
 struct GroupBy<It: Iterator, F> {
     it: std::iter::Peekable<It>,
@@ -277,11 +243,15 @@ struct GroupBy<It: Iterator, F> {
 }
 
 impl<It, F> Clone for GroupBy<It, F>
-where It: Iterator + Clone, It::Item: Clone, F: Clone {
-    fn clone(&self) -> GroupBy<It, F> {
+where
+    It: Iterator + Clone,
+    It::Item: Clone,
+    F: Clone,
+{
+    fn clone(&self) -> Self {
         GroupBy {
             it: self.it.clone(),
-            f: self.f.clone()
+            f: self.f.clone(),
         }
     }
 }
@@ -331,14 +301,11 @@ impl<It: Iterator, F: FnMut(&It::Item) -> G, G: Eq> Iterator for InGroup<It, F,
 }
 
 trait IteratorExt: Iterator + Sized {
-    fn group_by<G, F>(self, f: F) -> GroupBy<Self, Fn0<F>>
-    where F: FnMut(&Self::Item) -> G,
+    fn group_by<G, F>(self, f: F) -> GroupBy<Self, F>
+    where F: Clone + FnMut(&Self::Item) -> G,
           G: Eq
     {
-        GroupBy {
-            it: self.peekable(),
-            f: f.copyable(),
-        }
+        GroupBy { it: self.peekable(), f }
     }
 
     fn join(mut self, sep: &str) -> String
@@ -382,7 +349,7 @@ fn test_spaces() {
 fn dates_in_year(year: i32) -> impl Iterator<Item=NaiveDate>+Clone {
     InGroup {
         it: NaiveDate::from_ymd(year, 1, 1)..,
-        f: (|d: &NaiveDate| d.year()).copyable(),
+        f: |d: &NaiveDate| d.year(),
         g: year
     }
 }
diff --git a/src/test/run-pass/issue-36792.rs b/src/test/run-pass/issue-36792.rs
new file mode 100644
index 00000000000..faf983f6ecb
--- /dev/null
+++ b/src/test/run-pass/issue-36792.rs
@@ -0,0 +1,17 @@
+// Copyright 2018 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(conservative_impl_trait)]
+fn foo() -> impl Copy {
+    foo
+}
+fn main() {
+    foo();
+}
diff --git a/src/test/run-pass/issue-38091.rs b/src/test/run-pass/issue-38091.rs
new file mode 100644
index 00000000000..34050242f84
--- /dev/null
+++ b/src/test/run-pass/issue-38091.rs
@@ -0,0 +1,29 @@
+// Copyright 2018 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(specialization)]
+
+trait Iterate<'a> {
+    type Ty: Valid;
+    fn iterate(self);
+}
+impl<'a, T> Iterate<'a> for T where T: Check {
+    default type Ty = ();
+    default fn iterate(self) {}
+}
+
+trait Check {}
+impl<'a, T> Check for T where <T as Iterate<'a>>::Ty: Valid {}
+
+trait Valid {}
+
+fn main() {
+    Iterate::iterate(0);
+}
diff --git a/src/test/compile-fail/directory_ownership/backcompat-warnings.rs b/src/test/run-pass/issue-42148.rs
index 2da07a2cc72..0196649a3f6 100644
--- a/src/test/compile-fail/directory_ownership/backcompat-warnings.rs
+++ b/src/test/run-pass/issue-42148.rs
@@ -1,4 +1,4 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,9 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: mod statements in non-mod.rs files are unstable
+struct Zst;
 
-#[path="mod_file_not_owning_aux3.rs"]
-mod foo;
-
-fn main() {}
+fn main() {
+    unsafe { ::std::ptr::write_volatile(1 as *mut Zst, Zst) }
+}
diff --git a/src/test/run-pass/issue-42956.rs b/src/test/run-pass/issue-42956.rs
new file mode 100644
index 00000000000..9bda6ee4bcb
--- /dev/null
+++ b/src/test/run-pass/issue-42956.rs
@@ -0,0 +1,33 @@
+// Copyright 2018 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(associated_consts)]
+
+impl A for i32 {
+    type Foo = u32;
+}
+impl B for u32 {
+    const BAR: i32 = 0;
+}
+
+trait A {
+    type Foo: B;
+}
+
+trait B {
+    const BAR: i32;
+}
+
+fn generic<T: A>() {
+    // This panics if the universal function call syntax is used as well
+    println!("{}", T::Foo::BAR);
+}
+
+fn main() {}
diff --git a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs b/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs
index b61667cfd88..b61667cfd88 100644
--- a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs
+++ b/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs
diff --git a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs b/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs
index 77cab972352..77cab972352 100644
--- a/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs
+++ b/src/test/run-pass/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs
diff --git a/src/test/ui/non_modrs_mods/non_modrs_mods.stderr b/src/test/ui/non_modrs_mods/non_modrs_mods.stderr
index b4b524786cd..95a2539ed64 100644
--- a/src/test/ui/non_modrs_mods/non_modrs_mods.stderr
+++ b/src/test/ui/non_modrs_mods/non_modrs_mods.stderr
@@ -34,14 +34,5 @@ error: mod statements in non-mod.rs files are unstable (see issue #44660)
    = help: add #![feature(non_modrs_mods)] to the crate attributes to enable
    = help: on stable builds, rename this file to inner_foors_mod/mod.rs
 
-error: mod statements in non-mod.rs files are unstable (see issue #44660)
-  --> $DIR/some_crazy_attr_mod_dir/arbitrary_name.rs:11:9
-   |
-11 | pub mod inner_modrs_mod;
-   |         ^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(non_modrs_mods)] to the crate attributes to enable
-   = help: on stable builds, rename this file to attr_mod/mod.rs
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs
index b61667cfd88..b61667cfd88 100644
--- a/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/innest.rs
+++ b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/innest.rs
diff --git a/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs
index 77cab972352..77cab972352 100644
--- a/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/attr_mod/inner_modrs_mod/mod.rs
+++ b/src/test/ui/non_modrs_mods/some_crazy_attr_mod_dir/inner_modrs_mod/mod.rs
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index fc2759df447..4113f8fd124 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -67,6 +67,7 @@ static TARGETS: &'static [&'static str] = &[
     "i386-apple-ios",
     "i586-pc-windows-msvc",
     "i586-unknown-linux-gnu",
+    "i586-unknown-linux-musl",
     "i686-apple-darwin",
     "i686-linux-android",
     "i686-pc-windows-gnu",
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index d1643c0aa4b..efbe5e32fcd 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -21,6 +21,7 @@ use header::TestProps;
 use util::logv;
 use regex::Regex;
 
+use std::collections::VecDeque;
 use std::collections::HashMap;
 use std::collections::HashSet;
 use std::env;
@@ -48,6 +49,88 @@ pub fn dylib_env_var() -> &'static str {
     }
 }
 
+#[derive(Debug, PartialEq)]
+pub enum DiffLine {
+    Context(String),
+    Expected(String),
+    Resulting(String),
+}
+
+#[derive(Debug, PartialEq)]
+pub struct Mismatch {
+    pub line_number: u32,
+    pub lines: Vec<DiffLine>,
+}
+
+impl Mismatch {
+    fn new(line_number: u32) -> Mismatch {
+        Mismatch {
+            line_number: line_number,
+            lines: Vec::new(),
+        }
+    }
+}
+
+// Produces a diff between the expected output and actual output.
+pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Mismatch> {
+    let mut line_number = 1;
+    let mut context_queue: VecDeque<&str> = VecDeque::with_capacity(context_size);
+    let mut lines_since_mismatch = context_size + 1;
+    let mut results = Vec::new();
+    let mut mismatch = Mismatch::new(0);
+
+    for result in diff::lines(actual, expected) {
+        match result {
+            diff::Result::Left(str) => {
+                if lines_since_mismatch >= context_size && lines_since_mismatch > 0 {
+                    results.push(mismatch);
+                    mismatch = Mismatch::new(line_number - context_queue.len() as u32);
+                }
+
+                while let Some(line) = context_queue.pop_front() {
+                    mismatch.lines.push(DiffLine::Context(line.to_owned()));
+                }
+
+                mismatch.lines.push(DiffLine::Resulting(str.to_owned()));
+                lines_since_mismatch = 0;
+            }
+            diff::Result::Right(str) => {
+                if lines_since_mismatch >= context_size && lines_since_mismatch > 0 {
+                    results.push(mismatch);
+                    mismatch = Mismatch::new(line_number - context_queue.len() as u32);
+                }
+
+                while let Some(line) = context_queue.pop_front() {
+                    mismatch.lines.push(DiffLine::Context(line.to_owned()));
+                }
+
+                mismatch.lines.push(DiffLine::Expected(str.to_owned()));
+                line_number += 1;
+                lines_since_mismatch = 0;
+            }
+            diff::Result::Both(str, _) => {
+                if context_queue.len() >= context_size {
+                    let _ = context_queue.pop_front();
+                }
+
+                if lines_since_mismatch < context_size {
+                    mismatch.lines.push(DiffLine::Context(str.to_owned()));
+                } else if context_size > 0 {
+                    context_queue.push_back(str);
+                }
+
+                line_number += 1;
+                lines_since_mismatch += 1;
+            }
+        }
+    }
+
+    results.push(mismatch);
+    results.remove(0);
+
+    results
+}
+
 pub fn run(config: Config, testpaths: &TestPaths) {
     match &*config.target {
         "arm-linux-androideabi" | "armv7-linux-androideabi" | "aarch64-linux-android" => {
@@ -2720,15 +2803,29 @@ impl<'test> TestCx<'test> {
             return 0;
         }
 
-        println!("normalized {}:\n{}\n", kind, actual);
-        println!("expected {}:\n{}\n", kind, expected);
-        println!("diff of {}:\n", kind);
-
-        for diff in diff::lines(expected, actual) {
-            match diff {
-                diff::Result::Left(l) => println!("-{}", l),
-                diff::Result::Both(l, _) => println!(" {}", l),
-                diff::Result::Right(r) => println!("+{}", r),
+        if expected.is_empty() {
+            println!("normalized {}:\n{}\n", kind, actual);
+        } else {
+            println!("diff of {}:\n", kind);
+            let diff_results = make_diff(expected, actual, 3);
+            for result in diff_results {
+                let mut line_number = result.line_number;
+                for line in result.lines {
+                    match line {
+                        DiffLine::Expected(e) => {
+                            println!("-\t{}", e);
+                            line_number += 1;
+                        },
+                        DiffLine::Context(c) => {
+                            println!("{}\t{}", line_number, c);
+                            line_number += 1;
+                        },
+                        DiffLine::Resulting(r) => {
+                            println!("+\t{}", r);
+                        },
+                    }
+                }
+                println!("");
             }
         }