about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--config.toml.example3
-rw-r--r--src/bootstrap/bin/rustc.rs9
-rw-r--r--src/bootstrap/bootstrap.py33
-rw-r--r--src/bootstrap/builder.rs31
-rw-r--r--src/bootstrap/check.rs27
-rw-r--r--src/bootstrap/compile.rs32
-rw-r--r--src/bootstrap/config.rs5
-rw-r--r--src/bootstrap/dist.rs15
-rw-r--r--src/bootstrap/doc.rs22
-rw-r--r--src/bootstrap/lib.rs35
-rw-r--r--src/bootstrap/test.rs53
-rw-r--r--src/bootstrap/tool.rs77
-rw-r--r--src/doc/unstable-book/src/language-features/lang-items.md25
-rw-r--r--src/doc/unstable-book/src/language-features/used.md10
-rw-r--r--src/liballoc/btree/map.rs17
-rw-r--r--src/liballoc/lib.rs1
-rw-r--r--src/liballoc/slice.rs2
-rw-r--r--src/liballoc/tests/str.rs1
-rw-r--r--src/libcore/alloc.rs80
-rw-r--r--src/libcore/lib.rs3
-rw-r--r--src/libcore/mem.rs5
-rw-r--r--src/libcore/num/f32.rs6
-rw-r--r--src/libcore/num/f64.rs6
-rw-r--r--src/libcore/num/mod.rs294
-rw-r--r--src/libcore/panic.rs6
-rw-r--r--src/libcore/panicking.rs21
-rw-r--r--src/libcore/ptr.rs5
-rw-r--r--src/libcore/slice/mod.rs70
-rw-r--r--src/libcore/str/mod.rs6
-rw-r--r--src/libcore/time.rs51
-rw-r--r--src/librustc/diagnostics.rs6
-rw-r--r--src/librustc/hir/def.rs3
-rw-r--r--src/librustc/hir/lowering.rs4
-rw-r--r--src/librustc/hir/map/collector.rs2
-rw-r--r--src/librustc/hir/mod.rs6
-rw-r--r--src/librustc/hir/print.rs20
-rw-r--r--src/librustc/ich/impls_hir.rs12
-rw-r--r--src/librustc/middle/dead.rs2
-rw-r--r--src/librustc/middle/lang_items.rs5
-rw-r--r--src/librustc/middle/mem_categorization.rs16
-rw-r--r--src/librustc/middle/weak_lang_items.rs2
-rw-r--r--src/librustc/session/config.rs2
-rw-r--r--src/librustc/traits/project.rs8
-rw-r--r--src/librustc/traits/query/normalize.rs2
-rw-r--r--src/librustc/ty/mod.rs2
-rw-r--r--src/librustc_codegen_llvm/back/link.rs16
-rw-r--r--src/librustc_codegen_llvm/mir/block.rs19
-rw-r--r--src/librustc_lint/builtin.rs66
-rw-r--r--src/librustc_lint/lib.rs3
-rw-r--r--src/librustc_metadata/decoder.rs9
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs4
-rw-r--r--src/librustc_passes/rvalue_promotion.rs39
-rw-r--r--src/librustc_resolve/macros.rs1
-rw-r--r--src/librustc_resolve/resolve_imports.rs1
-rw-r--r--src/librustc_target/spec/linux_musl_base.rs9
-rw-r--r--src/librustc_target/spec/mod.rs21
-rw-r--r--src/librustc_typeck/check/method/suggest.rs12
-rw-r--r--src/librustc_typeck/check/mod.rs58
-rw-r--r--src/librustc_typeck/check_unused.rs215
-rw-r--r--src/librustdoc/clean/mod.rs60
-rw-r--r--src/librustdoc/html/markdown.rs25
-rw-r--r--src/librustdoc/html/render.rs1
-rw-r--r--src/librustdoc/html/static/main.js18
-rw-r--r--src/librustdoc/html/static/rustdoc.css18
-rw-r--r--src/librustdoc/html/static/themes/dark.css3
-rw-r--r--src/librustdoc/html/static/themes/light.css3
-rw-r--r--src/librustdoc/lib.rs1
-rw-r--r--src/librustdoc/visit_lib.rs3
-rw-r--r--src/libstd/collections/hash/map.rs17
-rw-r--r--src/libstd/lib.rs2
-rw-r--r--src/libstd/panicking.rs102
-rw-r--r--src/libsyntax/feature_gate.rs8
-rw-r--r--src/test/compile-fail/auxiliary/some-panic-impl.rs22
-rw-r--r--src/test/compile-fail/duplicate_entry_error.rs8
-rw-r--r--src/test/compile-fail/edition-extern-crate-allowed.rs3
-rw-r--r--src/test/compile-fail/feature-gate-panic-implementation.rs21
-rw-r--r--src/test/compile-fail/no_owned_box_lang_item.rs2
-rw-r--r--src/test/compile-fail/panic-implementation-bad-signature-1.rs24
-rw-r--r--src/test/compile-fail/panic-implementation-bad-signature-2.rs25
-rw-r--r--src/test/compile-fail/panic-implementation-bad-signature-3.rs22
-rw-r--r--src/test/compile-fail/panic-implementation-bad-signature-4.rs23
-rw-r--r--src/test/compile-fail/panic-implementation-duplicate.rs28
-rw-r--r--src/test/compile-fail/panic-implementation-requires-panic-info.rs26
-rw-r--r--src/test/compile-fail/panic-implementation-std.rs22
-rw-r--r--src/test/compile-fail/panic-implementation-twice.rs29
-rw-r--r--src/test/compile-fail/panic-runtime/auxiliary/panic-runtime-lang-items.rs6
-rw-r--r--src/test/compile-fail/weak-lang-item.rs2
-rw-r--r--src/test/run-make-fulldeps/issue-36710/Makefile21
-rw-r--r--src/test/run-make-fulldeps/issue-36710/foo.cpp25
-rw-r--r--src/test/run-make-fulldeps/issue-36710/foo.rs18
-rw-r--r--src/test/run-make-fulldeps/panic-impl-transitive/Makefile7
-rw-r--r--src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-consumer.rs15
-rw-r--r--src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-provider.rs20
-rw-r--r--src/test/run-make-fulldeps/tools.mk2
-rw-r--r--src/test/run-pass/const-endianess.rs32
-rw-r--r--src/test/rustdoc-ui/intra-links-warning.rs4
-rw-r--r--src/test/rustdoc-ui/intra-links-warning.stderr33
-rw-r--r--src/test/rustdoc/rustc-macro-crate.rs1
-rw-r--r--src/test/rustdoc/trait-attributes.rs32
-rw-r--r--src/test/ui-fulldeps/unnecessary-extern-crate.rs84
-rw-r--r--src/test/ui-fulldeps/unnecessary-extern-crate.stderr90
-rw-r--r--src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.nll.stderr63
-rw-r--r--src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.rs41
-rw-r--r--src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.stderr57
-rw-r--r--src/test/ui/deriving-with-repr-packed.rs2
-rw-r--r--src/test/ui/deriving-with-repr-packed.stderr4
-rw-r--r--src/test/ui/error-codes/E0152.rs2
-rw-r--r--src/test/ui/error-codes/E0152.stderr2
-rw-r--r--src/test/ui/issue-23217.stderr2
-rw-r--r--src/test/ui/issue-28971.stderr2
-rw-r--r--src/test/ui/rfc-2166-underscore-imports/basic.stderr2
-rw-r--r--src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed36
-rw-r--r--src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs36
-rw-r--r--src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr21
-rw-r--r--src/test/ui/suggestions/removing-extern-crate.fixed6
-rw-r--r--src/test/ui/suggestions/removing-extern-crate.stderr16
-rw-r--r--src/tools/compiletest/src/runtest.rs2
m---------src/tools/miri10
118 files changed, 2168 insertions, 560 deletions
diff --git a/config.toml.example b/config.toml.example
index 33ad9147ce0..5054a8f44b9 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -279,6 +279,9 @@
 # Whether or not `panic!`s generate backtraces (RUST_BACKTRACE)
 #backtrace = true
 
+# Whether to always use incremental compilation when building rustc
+#incremental = false
+
 # Build rustc with experimental parallelization
 #experimental-parallel-queries = false
 
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index 6f27402233f..4607ca5cf9f 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -268,6 +268,15 @@ fn main() {
         if let Ok(host_linker) = env::var("RUSTC_HOST_LINKER") {
             cmd.arg(format!("-Clinker={}", host_linker));
         }
+
+        if let Ok(s) = env::var("RUSTC_HOST_CRT_STATIC") {
+            if s == "true" {
+                cmd.arg("-C").arg("target-feature=+crt-static");
+            }
+            if s == "false" {
+                cmd.arg("-C").arg("target-feature=-crt-static");
+            }
+        }
     }
 
     if env::var_os("RUSTC_PARALLEL_QUERIES").is_some() {
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 487440becf6..28f5192f2cd 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -489,7 +489,7 @@ class RustBuild(object):
         """
         return os.path.join(self.build_dir, self.build, "stage0")
 
-    def get_toml(self, key):
+    def get_toml(self, key, section=None):
         """Returns the value of the given key in config.toml, otherwise returns None
 
         >>> rb = RustBuild()
@@ -501,12 +501,29 @@ class RustBuild(object):
 
         >>> rb.get_toml("key3") is None
         True
+
+        Optionally also matches the section the key appears in
+
+        >>> rb.config_toml = '[a]\\nkey = "value1"\\n[b]\\nkey = "value2"'
+        >>> rb.get_toml('key', 'a')
+        'value1'
+        >>> rb.get_toml('key', 'b')
+        'value2'
+        >>> rb.get_toml('key', 'c') is None
+        True
         """
+
+        cur_section = None
         for line in self.config_toml.splitlines():
+            section_match = re.match(r'^\s*\[(.*)\]\s*$', line)
+            if section_match is not None:
+                cur_section = section_match.group(1)
+
             match = re.match(r'^{}\s*=(.*)$'.format(key), line)
             if match is not None:
                 value = match.group(1)
-                return self.get_string(value) or value.strip()
+                if section is None or section == cur_section:
+                    return self.get_string(value) or value.strip()
         return None
 
     def cargo(self):
@@ -589,7 +606,17 @@ class RustBuild(object):
         env["LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \
             (os.pathsep + env["LIBRARY_PATH"]) \
             if "LIBRARY_PATH" in env else ""
-        env["RUSTFLAGS"] = "-Cdebuginfo=2"
+        env["RUSTFLAGS"] = "-Cdebuginfo=2 "
+
+        build_section = "target.{}".format(self.build_triple())
+        target_features = []
+        if self.get_toml("crt-static", build_section) == "true":
+            target_features += ["+crt-static"]
+        elif self.get_toml("crt-static", build_section) == "false":
+            target_features += ["-crt-static"]
+        if target_features:
+            env["RUSTFLAGS"] += "-C target-feature=" + (",".join(target_features)) + " "
+
         env["PATH"] = os.path.join(self.bin_root(), "bin") + \
             os.pathsep + env["PATH"]
         if not os.path.isfile(self.cargo()):
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 4fdb36b3f6e..9300b94156a 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -698,9 +698,14 @@ impl<'a> Builder<'a> {
         let out_dir = self.stage_out(compiler, mode);
         cargo
             .env("CARGO_TARGET_DIR", out_dir)
-            .arg(cmd)
-            .arg("--target")
-            .arg(target);
+            .arg(cmd);
+
+        if cmd != "install" {
+            cargo.arg("--target")
+                 .arg(target);
+        } else {
+            assert_eq!(target, compiler.host);
+        }
 
         // Set a flag for `check` so that certain build scripts can do less work
         // (e.g. not building/requiring LLVM).
@@ -801,7 +806,7 @@ impl<'a> Builder<'a> {
             );
         }
 
-        if mode == Mode::Tool {
+        if mode.is_tool() {
             // Tools like cargo and rls don't get debuginfo by default right now, but this can be
             // enabled in the config.  Adding debuginfo makes them several times larger.
             if self.config.rust_debuginfo_tools {
@@ -842,6 +847,10 @@ impl<'a> Builder<'a> {
             cargo.env("RUSTC_CRT_STATIC", x.to_string());
         }
 
+        if let Some(x) = self.crt_static(compiler.host) {
+            cargo.env("RUSTC_HOST_CRT_STATIC", x.to_string());
+        }
+
         // Enable usage of unstable features
         cargo.env("RUSTC_BOOTSTRAP", "1");
         self.add_rust_test_threads(&mut cargo);
@@ -862,7 +871,7 @@ impl<'a> Builder<'a> {
         //
         // If LLVM support is disabled we need to use the snapshot compiler to compile
         // build scripts, as the new compiler doesn't support executables.
-        if mode == Mode::Libstd || !self.config.llvm_enabled {
+        if mode == Mode::Std || !self.config.llvm_enabled {
             cargo
                 .env("RUSTC_SNAPSHOT", &self.initial_rustc)
                 .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir());
@@ -894,7 +903,7 @@ impl<'a> Builder<'a> {
         cargo.env("RUSTC_VERBOSE", format!("{}", self.verbosity));
 
         // in std, we want to avoid denying warnings for stage 0 as that makes cfg's painful.
-        if self.config.deny_warnings && !(mode == Mode::Libstd && stage == 0) {
+        if self.config.deny_warnings && !(mode == Mode::Std && stage == 0) {
             cargo.env("RUSTC_DENY_WARNINGS", "1");
         }
 
@@ -954,7 +963,7 @@ impl<'a> Builder<'a> {
         }
 
         if cmd == "build"
-            && mode == Mode::Libstd
+            && mode == Mode::Std
             && self.config.extended
             && compiler.is_final_stage(self)
         {
@@ -1003,7 +1012,7 @@ impl<'a> Builder<'a> {
         // be resolved because MinGW has the import library. The downside is we
         // don't get newer functions from Windows, but we don't use any of them
         // anyway.
-        if mode != Mode::Tool {
+        if !mode.is_tool() {
             cargo.env("WINAPI_NO_BUNDLED_LIBRARIES", "1");
         }
 
@@ -1018,8 +1027,8 @@ impl<'a> Builder<'a> {
         }
 
         if self.config.rust_optimize {
-            // FIXME: cargo bench does not accept `--release`
-            if cmd != "bench" {
+            // FIXME: cargo bench/install do not accept `--release`
+            if cmd != "bench" && cmd != "install" {
                 cargo.arg("--release");
             }
         }
@@ -1742,7 +1751,7 @@ mod __test {
             &[test::Crate {
                 compiler: Compiler { host, stage: 0 },
                 target: host,
-                mode: Mode::Libstd,
+                mode: Mode::Std,
                 test_kind: test::TestKind::Test,
                 krate: INTERNER.intern_str("std"),
             },]
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index a516af58b1e..b3ccb3cc3c9 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -40,10 +40,10 @@ impl Step for Std {
         let target = self.target;
         let compiler = builder.compiler(0, builder.config.build);
 
-        let out_dir = builder.stage_out(compiler, Mode::Libstd);
+        let out_dir = builder.stage_out(compiler, Mode::Std);
         builder.clear_if_dirty(&out_dir, &builder.rustc(compiler));
 
-        let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Std, target, "check");
         std_cargo(builder, &compiler, target, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-std", compiler.stage));
@@ -87,11 +87,11 @@ impl Step for Rustc {
         let compiler = builder.compiler(0, builder.config.build);
         let target = self.target;
 
-        let stage_out = builder.stage_out(compiler, Mode::Librustc);
+        let stage_out = builder.stage_out(compiler, Mode::Rustc);
         builder.clear_if_dirty(&stage_out, &libstd_stamp(builder, compiler, target));
         builder.clear_if_dirty(&stage_out, &libtest_stamp(builder, compiler, target));
 
-        let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "check");
         rustc_cargo(builder, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-rustc", compiler.stage));
@@ -137,7 +137,7 @@ impl Step for CodegenBackend {
         let target = self.target;
         let backend = self.backend;
 
-        let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Codegen, target, "check");
         let features = builder.rustc_features().to_string();
         cargo.arg("--manifest-path").arg(builder.src.join("src/librustc_codegen_llvm/Cargo.toml"));
         rustc_cargo_env(builder, &mut cargo);
@@ -175,10 +175,10 @@ impl Step for Test {
         let compiler = builder.compiler(0, builder.config.build);
         let target = self.target;
 
-        let out_dir = builder.stage_out(compiler, Mode::Libtest);
+        let out_dir = builder.stage_out(compiler, Mode::Test);
         builder.clear_if_dirty(&out_dir, &libstd_stamp(builder, compiler, target));
 
-        let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Test, target, "check");
         test_cargo(builder, &compiler, target, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-test", compiler.stage));
@@ -219,6 +219,7 @@ impl Step for Rustdoc {
 
         let mut cargo = prepare_tool_cargo(builder,
                                            compiler,
+                                           Mode::ToolRustc,
                                            target,
                                            "check",
                                            "src/tools/rustdoc");
@@ -236,7 +237,7 @@ impl Step for Rustdoc {
         builder.ensure(tool::CleanTools {
             compiler,
             target,
-            mode: Mode::Tool,
+            cause: Mode::Rustc,
         });
     }
 }
@@ -244,19 +245,19 @@ impl Step for Rustdoc {
 /// Cargo's output path for the standard library in a given stage, compiled
 /// by a particular compiler for the specified target.
 pub fn libstd_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Libstd, target).join(".libstd-check.stamp")
+    builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check.stamp")
 }
 
 /// Cargo's output path for libtest in a given stage, compiled by a particular
 /// compiler for the specified target.
 pub fn libtest_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Libtest, target).join(".libtest-check.stamp")
+    builder.cargo_out(compiler, Mode::Test, target).join(".libtest-check.stamp")
 }
 
 /// Cargo's output path for librustc in a given stage, compiled by a particular
 /// compiler for the specified target.
 pub fn librustc_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Librustc, target).join(".librustc-check.stamp")
+    builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc-check.stamp")
 }
 
 /// Cargo's output path for librustc_codegen_llvm in a given stage, compiled by a particular
@@ -265,12 +266,12 @@ fn codegen_backend_stamp(builder: &Builder,
                          compiler: Compiler,
                          target: Interned<String>,
                          backend: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Librustc, target)
+    builder.cargo_out(compiler, Mode::Codegen, target)
          .join(format!(".librustc_codegen_llvm-{}-check.stamp", backend))
 }
 
 /// Cargo's output path for rustdoc in a given stage, compiled by a particular
 /// compiler for the specified target.
 pub fn rustdoc_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Tool, target).join(".rustdoc-check.stamp")
+    builder.cargo_out(compiler, Mode::ToolRustc, target).join(".rustdoc-check.stamp")
 }
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 231ed9d40d2..11d9154ba69 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -98,9 +98,9 @@ impl Step for Std {
             copy_musl_third_party_objects(builder, target, &libdir);
         }
 
-        let out_dir = builder.cargo_out(compiler, Mode::Libstd, target);
+        let out_dir = builder.cargo_out(compiler, Mode::Std, target);
         builder.clear_if_dirty(&out_dir, &builder.rustc(compiler));
-        let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "build");
+        let mut cargo = builder.cargo(compiler, Mode::Std, target, "build");
         std_cargo(builder, &compiler, target, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-std", compiler.stage));
@@ -240,7 +240,7 @@ impl Step for StdLink {
         builder.ensure(tool::CleanTools {
             compiler: target_compiler,
             target,
-            mode: Mode::Libstd,
+            cause: Mode::Std,
         });
     }
 }
@@ -368,9 +368,9 @@ impl Step for Test {
             return;
         }
 
-        let out_dir = builder.cargo_out(compiler, Mode::Libtest, target);
+        let out_dir = builder.cargo_out(compiler, Mode::Test, target);
         builder.clear_if_dirty(&out_dir, &libstd_stamp(builder, compiler, target));
-        let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "build");
+        let mut cargo = builder.cargo(compiler, Mode::Test, target, "build");
         test_cargo(builder, &compiler, target, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-test", compiler.stage));
@@ -431,7 +431,7 @@ impl Step for TestLink {
         builder.ensure(tool::CleanTools {
             compiler: target_compiler,
             target,
-            mode: Mode::Libtest,
+            cause: Mode::Test,
         });
     }
 }
@@ -489,11 +489,11 @@ impl Step for Rustc {
             compiler: builder.compiler(self.compiler.stage, builder.config.build),
             target: builder.config.build,
         });
-        let cargo_out = builder.cargo_out(compiler, Mode::Librustc, target);
+        let cargo_out = builder.cargo_out(compiler, Mode::Rustc, target);
         builder.clear_if_dirty(&cargo_out, &libstd_stamp(builder, compiler, target));
         builder.clear_if_dirty(&cargo_out, &libtest_stamp(builder, compiler, target));
 
-        let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build");
+        let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "build");
         rustc_cargo(builder, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-rustc", compiler.stage));
@@ -585,7 +585,7 @@ impl Step for RustcLink {
         builder.ensure(tool::CleanTools {
             compiler: target_compiler,
             target,
-            mode: Mode::Librustc,
+            cause: Mode::Rustc,
         });
     }
 }
@@ -634,7 +634,7 @@ impl Step for CodegenBackend {
             return;
         }
 
-        let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "build");
+        let mut cargo = builder.cargo(compiler, Mode::Codegen, target, "build");
         let mut features = builder.rustc_features().to_string();
         cargo.arg("--manifest-path")
             .arg(builder.src.join("src/librustc_codegen_llvm/Cargo.toml"));
@@ -642,7 +642,7 @@ impl Step for CodegenBackend {
 
         features += &build_codegen_backend(&builder, &mut cargo, &compiler, target, backend);
 
-        let tmp_stamp = builder.cargo_out(compiler, Mode::Librustc, target)
+        let tmp_stamp = builder.cargo_out(compiler, Mode::Codegen, target)
             .join(".tmp.stamp");
 
         let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage));
@@ -793,19 +793,19 @@ fn copy_lld_to_sysroot(builder: &Builder,
 /// Cargo's output path for the standard library in a given stage, compiled
 /// by a particular compiler for the specified target.
 pub fn libstd_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Libstd, target).join(".libstd.stamp")
+    builder.cargo_out(compiler, Mode::Std, target).join(".libstd.stamp")
 }
 
 /// Cargo's output path for libtest in a given stage, compiled by a particular
 /// compiler for the specified target.
 pub fn libtest_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Libtest, target).join(".libtest.stamp")
+    builder.cargo_out(compiler, Mode::Test, target).join(".libtest.stamp")
 }
 
 /// Cargo's output path for librustc in a given stage, compiled by a particular
 /// compiler for the specified target.
 pub fn librustc_stamp(builder: &Builder, compiler: Compiler, target: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Librustc, target).join(".librustc.stamp")
+    builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc.stamp")
 }
 
 /// Cargo's output path for librustc_codegen_llvm in a given stage, compiled by a particular
@@ -814,7 +814,7 @@ fn codegen_backend_stamp(builder: &Builder,
                          compiler: Compiler,
                          target: Interned<String>,
                          backend: Interned<String>) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Librustc, target)
+    builder.cargo_out(compiler, Mode::Codegen, target)
         .join(format!(".librustc_codegen_llvm-{}.stamp", backend))
 }
 
@@ -971,7 +971,7 @@ impl Step for Assemble {
         }
 
         // Link the compiler binary itself into place
-        let out_dir = builder.cargo_out(build_compiler, Mode::Librustc, host);
+        let out_dir = builder.cargo_out(build_compiler, Mode::Rustc, host);
         let rustc = out_dir.join(exe("rustc_binary", &*host));
         let bindir = sysroot.join("bin");
         t!(fs::create_dir_all(&bindir));
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 9840682d137..47feb8a8ab6 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -303,6 +303,7 @@ struct Rust {
     dist_src: Option<bool>,
     quiet_tests: Option<bool>,
     test_miri: Option<bool>,
+    incremental: Option<bool>,
     save_toolstates: Option<String>,
     codegen_backends: Option<Vec<String>>,
     codegen_backends_dir: Option<String>,
@@ -529,6 +530,10 @@ impl Config {
             set(&mut config.rust_dist_src, rust.dist_src);
             set(&mut config.quiet_tests, rust.quiet_tests);
             set(&mut config.test_miri, rust.test_miri);
+            // in the case "false" is set explicitly, do not overwrite the command line args
+            if let Some(true) = rust.incremental {
+                config.incremental = true;
+            }
             set(&mut config.wasm_syscall, rust.wasm_syscall);
             set(&mut config.lld_enabled, rust.lld);
             config.rustc_parallel_queries = rust.experimental_parallel_queries.unwrap_or(false);
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index e21a59390b7..7341137e20d 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -722,7 +722,7 @@ impl Step for Analysis {
 
         let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
 
-        let src = builder.stage_out(compiler, Mode::Libstd)
+        let src = builder.stage_out(compiler, Mode::Std)
             .join(target).join(builder.cargo_dir()).join("deps");
 
         let image_src = src.join("save-analysis");
@@ -951,13 +951,16 @@ impl Step for PlainSourceTarball {
                 has_cargo_vendor |= line.starts_with("cargo-vendor ");
             }
             if !has_cargo_vendor {
-                let mut cmd = Command::new(&builder.initial_cargo);
-                cmd.arg("install")
-                   .arg("--force")
+                let mut cmd = builder.cargo(
+                    builder.compiler(0, builder.config.build),
+                    Mode::ToolRustc,
+                    builder.config.build,
+                    "install"
+                );
+                cmd.arg("--force")
                    .arg("--debug")
                    .arg("--vers").arg(CARGO_VENDOR_VERSION)
-                   .arg("cargo-vendor")
-                   .env("RUSTC", &builder.initial_rustc);
+                   .arg("cargo-vendor");
                 if let Some(dir) = builder.openssl_install_dir(builder.config.build) {
                     builder.ensure(native::Openssl {
                         target: builder.config.build,
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index cb229938521..19599b33ebe 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -463,7 +463,7 @@ impl Step for Std {
         };
 
         builder.ensure(compile::Std { compiler, target });
-        let out_dir = builder.stage_out(compiler, Mode::Libstd)
+        let out_dir = builder.stage_out(compiler, Mode::Std)
                            .join(target).join("doc");
 
         // Here what we're doing is creating a *symlink* (directory junction on
@@ -483,7 +483,7 @@ impl Step for Std {
         builder.clear_if_dirty(&my_out, &rustdoc);
         t!(symlink_dir_force(&builder.config, &my_out, &out_dir));
 
-        let mut cargo = builder.cargo(compiler, Mode::Libstd, target, "doc");
+        let mut cargo = builder.cargo(compiler, Mode::Std, target, "doc");
         compile::std_cargo(builder, &compiler, target, &mut cargo);
 
         // Keep a whitelist so we do not build internal stdlib crates, these will be
@@ -546,7 +546,7 @@ impl Step for Test {
         builder.ensure(Std { stage, target });
 
         builder.ensure(compile::Test { compiler, target });
-        let out_dir = builder.stage_out(compiler, Mode::Libtest)
+        let out_dir = builder.stage_out(compiler, Mode::Test)
                            .join(target).join("doc");
 
         // See docs in std above for why we symlink
@@ -554,7 +554,7 @@ impl Step for Test {
         builder.clear_if_dirty(&my_out, &rustdoc);
         t!(symlink_dir_force(&builder.config, &my_out, &out_dir));
 
-        let mut cargo = builder.cargo(compiler, Mode::Libtest, target, "doc");
+        let mut cargo = builder.cargo(compiler, Mode::Test, target, "doc");
         compile::test_cargo(builder, &compiler, target, &mut cargo);
 
         cargo.arg("--no-deps").arg("-p").arg("test");
@@ -614,7 +614,7 @@ impl Step for WhitelistedRustc {
         builder.ensure(Std { stage, target });
 
         builder.ensure(compile::Rustc { compiler, target });
-        let out_dir = builder.stage_out(compiler, Mode::Librustc)
+        let out_dir = builder.stage_out(compiler, Mode::Rustc)
                            .join(target).join("doc");
 
         // See docs in std above for why we symlink
@@ -622,7 +622,7 @@ impl Step for WhitelistedRustc {
         builder.clear_if_dirty(&my_out, &rustdoc);
         t!(symlink_dir_force(&builder.config, &my_out, &out_dir));
 
-        let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc");
+        let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "doc");
         compile::rustc_cargo(builder, &mut cargo);
 
         // We don't want to build docs for internal compiler dependencies in this
@@ -698,12 +698,12 @@ impl Step for Rustc {
 
         // We do not symlink to the same shared folder that already contains std library
         // documentation from previous steps as we do not want to include that.
-        let out_dir = builder.stage_out(compiler, Mode::Librustc).join(target).join("doc");
+        let out_dir = builder.stage_out(compiler, Mode::Rustc).join(target).join("doc");
         builder.clear_if_dirty(&out, &rustdoc);
         t!(symlink_dir_force(&builder.config, &out, &out_dir));
 
         // Build cargo command.
-        let mut cargo = builder.cargo(compiler, Mode::Librustc, target, "doc");
+        let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "doc");
         cargo.env("RUSTDOCFLAGS", "--document-private-items");
         compile::rustc_cargo(builder, &mut cargo);
 
@@ -799,13 +799,15 @@ impl Step for Rustdoc {
         builder.ensure(tool::Rustdoc { host: compiler.host });
 
         // Symlink compiler docs to the output directory of rustdoc documentation.
-        let out_dir = builder.stage_out(compiler, Mode::Tool).join(target).join("doc");
+        let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target).join("doc");
         t!(fs::create_dir_all(&out_dir));
         builder.clear_if_dirty(&out, &rustdoc);
         t!(symlink_dir_force(&builder.config, &out, &out_dir));
 
         // Build cargo command.
-        let mut cargo = prepare_tool_cargo(builder, compiler, target, "doc", "src/tools/rustdoc");
+        let mut cargo = prepare_tool_cargo(
+            builder, compiler, Mode::ToolRustc, target, "doc", "src/tools/rustdoc");
+
         cargo.env("RUSTDOCFLAGS", "--document-private-items");
         builder.run(&mut cargo);
     }
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index f64161fb027..d16d7a52065 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -307,16 +307,30 @@ impl Crate {
 #[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
 pub enum Mode {
     /// Build the standard library, placing output in the "stageN-std" directory.
-    Libstd,
+    Std,
 
     /// Build libtest, placing output in the "stageN-test" directory.
-    Libtest,
+    Test,
 
-    /// Build librustc and compiler libraries, placing output in the "stageN-rustc" directory.
-    Librustc,
+    /// Build librustc, and compiler libraries, placing output in the "stageN-rustc" directory.
+    Rustc,
 
-    /// Build some tool, placing output in the "stageN-tools" directory.
-    Tool,
+    /// Build codegen libraries, placing output in the "stageN-codegen" directory
+    Codegen,
+
+    /// Build some tools, placing output in the "stageN-tools" directory.
+    ToolStd,
+    ToolTest,
+    ToolRustc,
+}
+
+impl Mode {
+    pub fn is_tool(&self) -> bool {
+        match self {
+            Mode::ToolStd | Mode::ToolTest | Mode::ToolRustc => true,
+            _ => false
+        }
+    }
 }
 
 impl Build {
@@ -517,10 +531,11 @@ impl Build {
     /// The mode indicates what the root directory is for.
     fn stage_out(&self, compiler: Compiler, mode: Mode) -> PathBuf {
         let suffix = match mode {
-            Mode::Libstd => "-std",
-            Mode::Libtest => "-test",
-            Mode::Tool => "-tools",
-            Mode::Librustc => "-rustc",
+            Mode::Std => "-std",
+            Mode::Test => "-test",
+            Mode::Codegen => "-rustc",
+            Mode::Rustc => "-rustc",
+            Mode::ToolStd | Mode::ToolTest | Mode::ToolRustc => "-tools",
         };
         self.out.join(&*compiler.host)
                 .join(format!("stage{}{}", compiler.stage, suffix))
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 92847786792..a0b6222421d 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -222,7 +222,7 @@ impl Step for Cargo {
             compiler,
             target: self.host,
         });
-        let mut cargo = builder.cargo(compiler, Mode::Tool, self.host, "test");
+        let mut cargo = builder.cargo(compiler, Mode::ToolRustc, self.host, "test");
         cargo
             .arg("--manifest-path")
             .arg(builder.src.join("src/tools/cargo/Cargo.toml"));
@@ -281,7 +281,12 @@ impl Step for Rls {
             return;
         }
 
-        let mut cargo = tool::prepare_tool_cargo(builder, compiler, host, "test", "src/tools/rls");
+        let mut cargo = tool::prepare_tool_cargo(builder,
+                                                 compiler,
+                                                 Mode::ToolRustc,
+                                                 host,
+                                                 "test",
+                                                 "src/tools/rls");
 
         // Don't build tests dynamically, just a pain to work with
         cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
@@ -331,8 +336,12 @@ impl Step for Rustfmt {
             return;
         }
 
-        let mut cargo =
-            tool::prepare_tool_cargo(builder, compiler, host, "test", "src/tools/rustfmt");
+        let mut cargo = tool::prepare_tool_cargo(builder,
+                                                 compiler,
+                                                 Mode::ToolRustc,
+                                                 host,
+                                                 "test",
+                                                 "src/tools/rustfmt");
 
         // Don't build tests dynamically, just a pain to work with
         cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
@@ -383,7 +392,7 @@ impl Step for Miri {
             extra_features: Vec::new(),
         });
         if let Some(miri) = miri {
-            let mut cargo = builder.cargo(compiler, Mode::Tool, host, "test");
+            let mut cargo = builder.cargo(compiler, Mode::ToolRustc, host, "test");
             cargo
                 .arg("--manifest-path")
                 .arg(builder.src.join("src/tools/miri/Cargo.toml"));
@@ -441,7 +450,7 @@ impl Step for Clippy {
             extra_features: Vec::new(),
         });
         if let Some(clippy) = clippy {
-            let mut cargo = builder.cargo(compiler, Mode::Tool, host, "test");
+            let mut cargo = builder.cargo(compiler, Mode::ToolRustc, host, "test");
             cargo
                 .arg("--manifest-path")
                 .arg(builder.src.join("src/tools/clippy/Cargo.toml"));
@@ -453,7 +462,7 @@ impl Step for Clippy {
             cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
             cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
             let host_libs = builder
-                .stage_out(compiler, Mode::Tool)
+                .stage_out(compiler, Mode::ToolRustc)
                 .join(builder.cargo_dir());
             cargo.env("HOST_LIBS", host_libs);
             // clippy tests need to find the driver
@@ -952,8 +961,7 @@ impl Step for Compiletest {
         if suite.ends_with("fulldeps") ||
             // FIXME: Does pretty need librustc compiled? Note that there are
             // fulldeps test suites with mode = pretty as well.
-            mode == "pretty" ||
-            mode == "rustdoc"
+            mode == "pretty"
         {
             builder.ensure(compile::Rustc { compiler, target });
         }
@@ -1435,7 +1443,7 @@ impl Step for CrateLibrustc {
         builder.ensure(Crate {
             compiler: self.compiler,
             target: self.target,
-            mode: Mode::Librustc,
+            mode: Mode::Rustc,
             test_kind: self.test_kind,
             krate: self.krate,
         });
@@ -1486,7 +1494,7 @@ impl Step for CrateNotDefault {
         builder.ensure(Crate {
             compiler: self.compiler,
             target: self.target,
-            mode: Mode::Libstd,
+            mode: Mode::Std,
             test_kind: self.test_kind,
             krate: INTERNER.intern_str(self.krate),
         });
@@ -1539,12 +1547,12 @@ impl Step for Crate {
 
         for krate in builder.in_tree_crates("std") {
             if run.path.ends_with(&krate.local_path(&builder)) {
-                make(Mode::Libstd, krate);
+                make(Mode::Std, krate);
             }
         }
         for krate in builder.in_tree_crates("test") {
             if run.path.ends_with(&krate.local_path(&builder)) {
-                make(Mode::Libtest, krate);
+                make(Mode::Test, krate);
             }
         }
     }
@@ -1579,13 +1587,13 @@ impl Step for Crate {
 
         let mut cargo = builder.cargo(compiler, mode, target, test_kind.subcommand());
         match mode {
-            Mode::Libstd => {
+            Mode::Std => {
                 compile::std_cargo(builder, &compiler, target, &mut cargo);
             }
-            Mode::Libtest => {
+            Mode::Test => {
                 compile::test_cargo(builder, &compiler, target, &mut cargo);
             }
-            Mode::Librustc => {
+            Mode::Rustc => {
                 builder.ensure(compile::Rustc { compiler, target });
                 compile::rustc_cargo(builder, &mut cargo);
             }
@@ -1719,13 +1727,12 @@ impl Step for CrateRustdoc {
         let compiler = builder.compiler(builder.top_stage, self.host);
         let target = compiler.host;
 
-        let mut cargo = tool::prepare_tool_cargo(
-            builder,
-            compiler,
-            target,
-            test_kind.subcommand(),
-            "src/tools/rustdoc",
-        );
+        let mut cargo = tool::prepare_tool_cargo(builder,
+                                                 compiler,
+                                                 Mode::ToolRustc,
+                                                 target,
+                                                 test_kind.subcommand(),
+                                                 "src/tools/rustdoc");
         if test_kind.subcommand() == "test" && !builder.fail_fast {
             cargo.arg("--no-fail-fast");
         }
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 29f37b36e2a..d4a2e96cc0d 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -28,7 +28,7 @@ use toolstate::ToolState;
 pub struct CleanTools {
     pub compiler: Compiler,
     pub target: Interned<String>,
-    pub mode: Mode,
+    pub cause: Mode,
 }
 
 impl Step for CleanTools {
@@ -41,23 +41,23 @@ impl Step for CleanTools {
     fn run(self, builder: &Builder) {
         let compiler = self.compiler;
         let target = self.target;
-        let mode = self.mode;
+        let cause = self.cause;
 
         // This is for the original compiler, but if we're forced to use stage 1, then
         // std/test/rustc stamps won't exist in stage 2, so we need to get those from stage 1, since
         // we copy the libs forward.
-        let tools_dir = builder.stage_out(compiler, Mode::Tool);
+        let tools_dir = builder.stage_out(compiler, Mode::ToolRustc);
         let compiler = if builder.force_use_stage1(compiler, target) {
             builder.compiler(1, compiler.host)
         } else {
             compiler
         };
 
-        for &cur_mode in &[Mode::Libstd, Mode::Libtest, Mode::Librustc] {
+        for &cur_mode in &[Mode::Std, Mode::Test, Mode::Rustc] {
             let stamp = match cur_mode {
-                Mode::Libstd => libstd_stamp(builder, compiler, target),
-                Mode::Libtest => libtest_stamp(builder, compiler, target),
-                Mode::Librustc => librustc_stamp(builder, compiler, target),
+                Mode::Std => libstd_stamp(builder, compiler, target),
+                Mode::Test => libtest_stamp(builder, compiler, target),
+                Mode::Rustc => librustc_stamp(builder, compiler, target),
                 _ => panic!(),
             };
 
@@ -67,7 +67,7 @@ impl Step for CleanTools {
 
             // If we are a rustc tool, and std changed, we also need to clear ourselves out -- our
             // dependencies depend on std. Therefore, we iterate up until our own mode.
-            if mode == cur_mode {
+            if cause == cur_mode {
                 break;
             }
         }
@@ -104,13 +104,13 @@ impl Step for ToolBuild {
         let is_ext_tool = self.is_ext_tool;
 
         match self.mode {
-            Mode::Libstd => builder.ensure(compile::Std { compiler, target }),
-            Mode::Libtest => builder.ensure(compile::Test { compiler, target }),
-            Mode::Librustc => builder.ensure(compile::Rustc { compiler, target }),
-            Mode::Tool => panic!("unexpected Mode::Tool for tool build")
+            Mode::ToolStd => builder.ensure(compile::Std { compiler, target }),
+            Mode::ToolTest => builder.ensure(compile::Test { compiler, target }),
+            Mode::ToolRustc => builder.ensure(compile::Rustc { compiler, target }),
+            _ => panic!("unexpected Mode for tool build")
         }
 
-        let mut cargo = prepare_tool_cargo(builder, compiler, target, "build", path);
+        let mut cargo = prepare_tool_cargo(builder, compiler, self.mode, target, "build", path);
         cargo.arg("--features").arg(self.extra_features.join(" "));
 
         let _folder = builder.fold_output(|| format!("stage{}-{}", compiler.stage, tool));
@@ -202,7 +202,7 @@ impl Step for ToolBuild {
                 return None;
             }
         } else {
-            let cargo_out = builder.cargo_out(compiler, Mode::Tool, target)
+            let cargo_out = builder.cargo_out(compiler, self.mode, target)
                 .join(exe(tool, &compiler.host));
             let bin = builder.tools_dir(compiler).join(exe(tool, &compiler.host));
             builder.copy(&cargo_out, &bin);
@@ -214,11 +214,12 @@ impl Step for ToolBuild {
 pub fn prepare_tool_cargo(
     builder: &Builder,
     compiler: Compiler,
+    mode: Mode,
     target: Interned<String>,
     command: &'static str,
     path: &'static str,
 ) -> Command {
-    let mut cargo = builder.cargo(compiler, Mode::Tool, target, command);
+    let mut cargo = builder.cargo(compiler, mode, target, command);
     let dir = builder.src.join(path);
     cargo.arg("--manifest-path").arg(dir.join("Cargo.toml"));
 
@@ -261,6 +262,15 @@ macro_rules! tool {
             )+
         }
 
+        impl Tool {
+            pub fn get_mode(&self) -> Mode {
+                let mode = match self {
+                    $(Tool::$name => $mode,)+
+                };
+                mode
+            }
+        }
+
         impl<'a> Builder<'a> {
             pub fn tool_exe(&self, tool: Tool) -> PathBuf {
                 let stage = self.tool_default_stage(tool);
@@ -324,17 +334,17 @@ macro_rules! tool {
 }
 
 tool!(
-    Rustbook, "src/tools/rustbook", "rustbook", Mode::Librustc;
-    ErrorIndex, "src/tools/error_index_generator", "error_index_generator", Mode::Librustc;
-    UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen", Mode::Libstd;
-    Tidy, "src/tools/tidy", "tidy", Mode::Libstd;
-    Linkchecker, "src/tools/linkchecker", "linkchecker", Mode::Libstd;
-    CargoTest, "src/tools/cargotest", "cargotest", Mode::Libstd;
-    Compiletest, "src/tools/compiletest", "compiletest", Mode::Libtest;
-    BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::Libstd;
-    RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::Libstd;
-    RustInstaller, "src/tools/rust-installer", "fabricate", Mode::Libstd;
-    RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes", Mode::Libstd;
+    Rustbook, "src/tools/rustbook", "rustbook", Mode::ToolRustc;
+    ErrorIndex, "src/tools/error_index_generator", "error_index_generator", Mode::ToolRustc;
+    UnstableBookGen, "src/tools/unstable-book-gen", "unstable-book-gen", Mode::ToolStd;
+    Tidy, "src/tools/tidy", "tidy", Mode::ToolStd;
+    Linkchecker, "src/tools/linkchecker", "linkchecker", Mode::ToolStd;
+    CargoTest, "src/tools/cargotest", "cargotest", Mode::ToolStd;
+    Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolTest;
+    BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::ToolStd;
+    RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::ToolStd;
+    RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolStd;
+    RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes", Mode::ToolStd;
 );
 
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
@@ -362,7 +372,7 @@ impl Step for RemoteTestServer {
             compiler: self.compiler,
             target: self.target,
             tool: "remote-test-server",
-            mode: Mode::Libstd,
+            mode: Mode::ToolStd,
             path: "src/tools/remote-test-server",
             is_ext_tool: false,
             extra_features: Vec::new(),
@@ -414,6 +424,7 @@ impl Step for Rustdoc {
 
         let mut cargo = prepare_tool_cargo(builder,
                                            build_compiler,
+                                           Mode::ToolRustc,
                                            target,
                                            "build",
                                            "src/tools/rustdoc");
@@ -430,7 +441,7 @@ impl Step for Rustdoc {
         // Cargo adds a number of paths to the dylib search path on windows, which results in
         // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
         // rustdoc a different name.
-        let tool_rustdoc = builder.cargo_out(build_compiler, Mode::Tool, target)
+        let tool_rustdoc = builder.cargo_out(build_compiler, Mode::ToolRustc, target)
             .join(exe("rustdoc_tool_binary", &target_compiler.host));
 
         // don't create a stage0-sysroot/bin directory.
@@ -485,7 +496,7 @@ impl Step for Cargo {
             compiler: self.compiler,
             target: self.target,
             tool: "cargo",
-            mode: Mode::Librustc,
+            mode: Mode::ToolRustc,
             path: "src/tools/cargo",
             is_ext_tool: false,
             extra_features: Vec::new(),
@@ -533,7 +544,7 @@ macro_rules! tool_extended {
                     compiler: $sel.compiler,
                     target: $sel.target,
                     tool: $tool_name,
-                    mode: Mode::Librustc,
+                    mode: Mode::ToolRustc,
                     path: $path,
                     extra_features: $sel.extra_features,
                     is_ext_tool: true,
@@ -575,7 +586,7 @@ impl<'a> Builder<'a> {
     pub fn tool_cmd(&self, tool: Tool) -> Command {
         let mut cmd = Command::new(self.tool_exe(tool));
         let compiler = self.compiler(self.tool_default_stage(tool), self.config.build);
-        self.prepare_tool_cmd(compiler, &mut cmd);
+        self.prepare_tool_cmd(compiler, tool.get_mode(), &mut cmd);
         cmd
     }
 
@@ -583,11 +594,11 @@ impl<'a> Builder<'a> {
     ///
     /// Notably this munges the dynamic library lookup path to point to the
     /// right location to run `compiler`.
-    fn prepare_tool_cmd(&self, compiler: Compiler, cmd: &mut Command) {
+    fn prepare_tool_cmd(&self, compiler: Compiler, mode: Mode, cmd: &mut Command) {
         let host = &compiler.host;
         let mut lib_paths: Vec<PathBuf> = vec![
             PathBuf::from(&self.sysroot_libdir(compiler, compiler.host)),
-            self.cargo_out(compiler, Mode::Tool, *host).join("deps"),
+            self.cargo_out(compiler, mode, *host).join("deps"),
         ];
 
         // On MSVC a tool may invoke a C compiler (e.g. compiletest in run-make
diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md
index 6a7aea7f1c2..bac619fd4a3 100644
--- a/src/doc/unstable-book/src/language-features/lang-items.md
+++ b/src/doc/unstable-book/src/language-features/lang-items.md
@@ -19,6 +19,7 @@ sugar for dynamic allocations via `malloc` and `free`:
 #![feature(lang_items, box_syntax, start, libc, core_intrinsics)]
 #![no_std]
 use core::intrinsics;
+use core::panic::PanicInfo;
 
 extern crate libc;
 
@@ -50,7 +51,7 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
 }
 
 #[lang = "eh_personality"] extern fn rust_eh_personality() {}
-#[lang = "panic_fmt"] extern fn rust_begin_panic() -> ! { unsafe { intrinsics::abort() } }
+#[lang = "panic_impl"] extern fn rust_begin_panic(info: &PanicInfo) -> ! { unsafe { intrinsics::abort() } }
 #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {}
 #[no_mangle] pub extern fn rust_eh_register_frames () {}
 #[no_mangle] pub extern fn rust_eh_unregister_frames () {}
@@ -110,6 +111,7 @@ in the same format as C:
 #![feature(start)]
 #![no_std]
 use core::intrinsics;
+use core::panic::PanicInfo;
 
 // Pull in the system libc library for what crt0.o likely requires.
 extern crate libc;
@@ -134,12 +136,9 @@ pub extern fn rust_eh_personality() {
 pub extern fn rust_eh_unwind_resume() {
 }
 
-#[lang = "panic_fmt"]
+#[lang = "panic_impl"]
 #[no_mangle]
-pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
-                               _file: &'static str,
-                               _line: u32,
-                               _column: u32) -> ! {
+pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
     unsafe { intrinsics::abort() }
 }
 ```
@@ -155,6 +154,7 @@ compiler's name mangling too:
 #![no_std]
 #![no_main]
 use core::intrinsics;
+use core::panic::PanicInfo;
 
 // Pull in the system libc library for what crt0.o likely requires.
 extern crate libc;
@@ -179,12 +179,9 @@ pub extern fn rust_eh_personality() {
 pub extern fn rust_eh_unwind_resume() {
 }
 
-#[lang = "panic_fmt"]
+#[lang = "panic_impl"]
 #[no_mangle]
-pub extern fn rust_begin_panic(_msg: core::fmt::Arguments,
-                               _file: &'static str,
-                               _line: u32,
-                               _column: u32) -> ! {
+pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
     unsafe { intrinsics::abort() }
 }
 ```
@@ -215,7 +212,7 @@ called. The language item's name is `eh_personality`.
 
 The second function, `rust_begin_panic`, is also used by the failure mechanisms of the
 compiler. When a panic happens, this controls the message that's displayed on
-the screen. While the language item's name is `panic_fmt`, the symbol name is
+the screen. While the language item's name is `panic_impl`, the symbol name is
 `rust_begin_panic`.
 
 A third function, `rust_eh_unwind_resume`, is also needed if the `custom_unwind_resume`
@@ -259,8 +256,8 @@ the source code.
   - `msvc_try_filter`: `libpanic_unwind/seh.rs` (SEH)
   - `panic`: `libcore/panicking.rs`
   - `panic_bounds_check`: `libcore/panicking.rs`
-  - `panic_fmt`: `libcore/panicking.rs`
-  - `panic_fmt`: `libstd/panicking.rs`
+  - `panic_impl`: `libcore/panicking.rs`
+  - `panic_impl`: `libstd/panicking.rs`
 - Allocations
   - `owned_box`: `liballoc/boxed.rs`
   - `exchange_malloc`: `liballoc/heap.rs`
diff --git a/src/doc/unstable-book/src/language-features/used.md b/src/doc/unstable-book/src/language-features/used.md
index 75a8b2774f4..c3b7f2e41e1 100644
--- a/src/doc/unstable-book/src/language-features/used.md
+++ b/src/doc/unstable-book/src/language-features/used.md
@@ -87,11 +87,13 @@ This condition can be met using `#[used]` and `#[link_section]` plus a linker
 script.
 
 ``` rust,ignore
-#![feature(lang_items)]
+#![feature(panic_implementation)]
 #![feature(used)]
 #![no_main]
 #![no_std]
 
+use core::panic::PanicInfo;
+
 extern "C" fn reset_handler() -> ! {
     loop {}
 }
@@ -100,8 +102,10 @@ extern "C" fn reset_handler() -> ! {
 #[used]
 static RESET_HANDLER: extern "C" fn() -> ! = reset_handler;
 
-#[lang = "panic_fmt"]
-fn panic_fmt() {}
+#[panic_implementation]
+fn panic_impl(info: &PanicInfo) -> ! {
+    loop {}
+}
 ```
 
 ``` text
diff --git a/src/liballoc/btree/map.rs b/src/liballoc/btree/map.rs
index 28c42144b2a..9b6f91c039f 100644
--- a/src/liballoc/btree/map.rs
+++ b/src/liballoc/btree/map.rs
@@ -2369,6 +2369,11 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
 
     /// Gets a mutable reference to the value in the entry.
     ///
+    /// If you need a reference to the `OccupiedEntry` which may outlive the
+    /// destruction of the `Entry` value, see [`into_mut`].
+    ///
+    /// [`into_mut`]: #method.into_mut
+    ///
     /// # Examples
     ///
     /// ```
@@ -2380,9 +2385,13 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
     ///
     /// assert_eq!(map["poneyland"], 12);
     /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
-    ///      *o.get_mut() += 10;
+    ///     *o.get_mut() += 10;
+    ///     assert_eq!(*o.get(), 22);
+    ///
+    ///     // We can use the same Entry multiple times.
+    ///     *o.get_mut() += 2;
     /// }
-    /// assert_eq!(map["poneyland"], 22);
+    /// assert_eq!(map["poneyland"], 24);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut V {
@@ -2391,6 +2400,10 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
 
     /// Converts the entry into a mutable reference to its value.
     ///
+    /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
+    ///
+    /// [`get_mut`]: #method.get_mut
+    ///
     /// # Examples
     ///
     /// ```
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 91de3ad0c39..a56420d52d0 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -104,7 +104,6 @@
 #![feature(ptr_internals)]
 #![feature(ptr_offset_from)]
 #![feature(rustc_attrs)]
-#![feature(slice_get_slice)]
 #![feature(specialization)]
 #![feature(staged_api)]
 #![feature(str_internals)]
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index 90bc2f9769c..c27c596e797 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -121,7 +121,7 @@ pub use core::slice::{RSplit, RSplitMut};
 pub use core::slice::{from_raw_parts, from_raw_parts_mut};
 #[stable(feature = "from_ref", since = "1.28.0")]
 pub use core::slice::{from_ref, from_mut};
-#[unstable(feature = "slice_get_slice", issue = "35729")]
+#[stable(feature = "slice_get_slice", since = "1.28.0")]
 pub use core::slice::SliceIndex;
 #[unstable(feature = "exact_chunks", issue = "47115")]
 pub use core::slice::{ExactChunks, ExactChunksMut};
diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs
index 03d295d16e6..75306ac82df 100644
--- a/src/liballoc/tests/str.rs
+++ b/src/liballoc/tests/str.rs
@@ -1326,6 +1326,7 @@ fn test_str_default() {
 
     t::<&str>();
     t::<String>();
+    t::<&mut str>();
 }
 
 #[test]
diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs
index 6172a98bca6..229758803c8 100644
--- a/src/libcore/alloc.rs
+++ b/src/libcore/alloc.rs
@@ -20,6 +20,7 @@ use fmt;
 use mem;
 use usize;
 use ptr::{self, NonNull};
+use num::NonZeroUsize;
 
 extern {
     /// An opaque, unsized type. Used for pointers to allocated memory.
@@ -66,7 +67,7 @@ fn size_align<T>() -> (usize, usize) {
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct Layout {
     // size of the requested block of memory, measured in bytes.
-    size: usize,
+    size_: usize,
 
     // alignment of the requested block of memory, measured in bytes.
     // we ensure that this is always a power-of-two, because API's
@@ -75,17 +76,12 @@ pub struct Layout {
     //
     // (However, we do not analogously require `align >= sizeof(void*)`,
     //  even though that is *also* a requirement of `posix_memalign`.)
-    align: usize,
+    align_: NonZeroUsize,
 }
 
-
-// FIXME: audit default implementations for overflow errors,
-// (potentially switching to overflowing_add and
-//  overflowing_mul as necessary).
-
 impl Layout {
     /// Constructs a `Layout` from a given `size` and `align`,
-    /// or returns `None` if either of the following conditions
+    /// or returns `LayoutErr` if either of the following conditions
     /// are not met:
     ///
     /// * `align` must be a power of two,
@@ -126,23 +122,23 @@ impl Layout {
     ///
     /// # Safety
     ///
-    /// This function is unsafe as it does not verify that `align` is
-    /// a power-of-two nor `size` aligned to `align` fits within the
-    /// address space (i.e. the `Layout::from_size_align` preconditions).
+    /// This function is unsafe as it does not verify the preconditions from
+    /// [`Layout::from_size_align`](#method.from_size_align).
     #[inline]
     pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
-        Layout { size: size, align: align }
+        Layout { size_: size, align_: NonZeroUsize::new_unchecked(align) }
     }
 
     /// The minimum size in bytes for a memory block of this layout.
     #[inline]
-    pub fn size(&self) -> usize { self.size }
+    pub fn size(&self) -> usize { self.size_ }
 
     /// The minimum byte alignment for a memory block of this layout.
     #[inline]
-    pub fn align(&self) -> usize { self.align }
+    pub fn align(&self) -> usize { self.align_.get() }
 
     /// Constructs a `Layout` suitable for holding a value of type `T`.
+    #[inline]
     pub fn new<T>() -> Self {
         let (size, align) = size_align::<T>();
         // Note that the align is guaranteed by rustc to be a power of two and
@@ -158,6 +154,7 @@ impl Layout {
     /// Produces layout describing a record that could be used to
     /// allocate backing structure for `T` (which could be a trait
     /// or other unsized type like a slice).
+    #[inline]
     pub fn for_value<T: ?Sized>(t: &T) -> Self {
         let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
         // See rationale in `new` for why this us using an unsafe variant below
@@ -181,18 +178,19 @@ impl Layout {
     ///
     /// # Panics
     ///
-    /// Panics if the combination of `self.size` and the given `align`
-    /// violates the conditions listed in `from_size_align`.
+    /// Panics if the combination of `self.size()` and the given `align`
+    /// violates the conditions listed in
+    /// [`Layout::from_size_align`](#method.from_size_align).
     #[inline]
     pub fn align_to(&self, align: usize) -> Self {
-        Layout::from_size_align(self.size, cmp::max(self.align, align)).unwrap()
+        Layout::from_size_align(self.size(), cmp::max(self.align(), align)).unwrap()
     }
 
     /// Returns the amount of padding we must insert after `self`
     /// to ensure that the following address will satisfy `align`
     /// (measured in bytes).
     ///
-    /// E.g. if `self.size` is 9, then `self.padding_needed_for(4)`
+    /// E.g. if `self.size()` is 9, then `self.padding_needed_for(4)`
     /// returns 3, because that is the minimum number of bytes of
     /// padding required to get a 4-aligned address (assuming that the
     /// corresponding memory block starts at a 4-aligned address).
@@ -203,7 +201,7 @@ impl Layout {
     /// Note that the utility of the returned value requires `align`
     /// to be less than or equal to the alignment of the starting
     /// address for the whole allocated block of memory. One way to
-    /// satisfy this constraint is to ensure `align <= self.align`.
+    /// satisfy this constraint is to ensure `align <= self.align()`.
     #[inline]
     pub fn padding_needed_for(&self, align: usize) -> usize {
         let len = self.size();
@@ -227,7 +225,8 @@ impl Layout {
         // size and padding overflow in the above manner should cause
         // the allocator to yield an error anyway.)
 
-        let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1);
+        let len_rounded_up = len.wrapping_add(align).wrapping_sub(1)
+            & !align.wrapping_sub(1);
         return len_rounded_up.wrapping_sub(len);
     }
 
@@ -238,14 +237,19 @@ impl Layout {
     /// layout of the array and `offs` is the distance between the start
     /// of each element in the array.
     ///
-    /// On arithmetic overflow, returns `None`.
+    /// On arithmetic overflow, returns `LayoutErr`.
     #[inline]
     pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutErr> {
-        let padded_size = self.size.checked_add(self.padding_needed_for(self.align))
+        let padded_size = self.size().checked_add(self.padding_needed_for(self.align()))
             .ok_or(LayoutErr { private: () })?;
         let alloc_size = padded_size.checked_mul(n)
             .ok_or(LayoutErr { private: () })?;
-        Ok((Layout::from_size_align(alloc_size, self.align)?, padded_size))
+
+        unsafe {
+            // self.align is already known to be valid and alloc_size has been
+            // padded already.
+            Ok((Layout::from_size_align_unchecked(alloc_size, self.align()), padded_size))
+        }
     }
 
     /// Creates a layout describing the record for `self` followed by
@@ -258,16 +262,15 @@ impl Layout {
     /// start of the `next` embedded within the concatenated record
     /// (assuming that the record itself starts at offset 0).
     ///
-    /// On arithmetic overflow, returns `None`.
+    /// On arithmetic overflow, returns `LayoutErr`.
+    #[inline]
     pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
-        let new_align = cmp::max(self.align, next.align);
-        let realigned = Layout::from_size_align(self.size, new_align)?;
-
-        let pad = realigned.padding_needed_for(next.align);
+        let new_align = cmp::max(self.align(), next.align());
+        let pad = self.padding_needed_for(next.align());
 
-        let offset = self.size.checked_add(pad)
+        let offset = self.size().checked_add(pad)
             .ok_or(LayoutErr { private: () })?;
-        let new_size = offset.checked_add(next.size)
+        let new_size = offset.checked_add(next.size())
             .ok_or(LayoutErr { private: () })?;
 
         let layout = Layout::from_size_align(new_size, new_align)?;
@@ -285,10 +288,11 @@ impl Layout {
     /// guaranteed that all elements in the array will be properly
     /// aligned.
     ///
-    /// On arithmetic overflow, returns `None`.
+    /// On arithmetic overflow, returns `LayoutErr`.
+    #[inline]
     pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutErr> {
         let size = self.size().checked_mul(n).ok_or(LayoutErr { private: () })?;
-        Layout::from_size_align(size, self.align)
+        Layout::from_size_align(size, self.align())
     }
 
     /// Creates a layout describing the record for `self` followed by
@@ -305,17 +309,19 @@ impl Layout {
     ///  signature out of convenience in matching the signature of
     ///  `extend`.)
     ///
-    /// On arithmetic overflow, returns `None`.
+    /// On arithmetic overflow, returns `LayoutErr`.
+    #[inline]
     pub fn extend_packed(&self, next: Self) -> Result<(Self, usize), LayoutErr> {
         let new_size = self.size().checked_add(next.size())
             .ok_or(LayoutErr { private: () })?;
-        let layout = Layout::from_size_align(new_size, self.align)?;
+        let layout = Layout::from_size_align(new_size, self.align())?;
         Ok((layout, self.size()))
     }
 
     /// Creates a layout describing the record for a `[T; n]`.
     ///
-    /// On arithmetic overflow, returns `None`.
+    /// On arithmetic overflow, returns `LayoutErr`.
+    #[inline]
     pub fn array<T>(n: usize) -> Result<Self, LayoutErr> {
         Layout::new::<T>()
             .repeat(n)
@@ -842,7 +848,7 @@ pub unsafe trait Alloc {
                             layout: Layout,
                             new_size: usize) -> Result<(), CannotReallocInPlace> {
         let _ = ptr; // this default implementation doesn't care about the actual address.
-        debug_assert!(new_size >= layout.size);
+        debug_assert!(new_size >= layout.size());
         let (_l, u) = self.usable_size(&layout);
         // _l <= layout.size()                       [guaranteed by usable_size()]
         //       layout.size() <= new_layout.size()  [required by this method]
@@ -897,7 +903,7 @@ pub unsafe trait Alloc {
                               layout: Layout,
                               new_size: usize) -> Result<(), CannotReallocInPlace> {
         let _ = ptr; // this default implementation doesn't care about the actual address.
-        debug_assert!(new_size <= layout.size);
+        debug_assert!(new_size <= layout.size());
         let (l, _u) = self.usable_size(&layout);
         //                      layout.size() <= _u  [guaranteed by usable_size()]
         // new_layout.size() <= layout.size()        [required by this method]
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 32cf31231c3..b27552651a0 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -41,7 +41,7 @@
 //!   dictate the panic message, the file at which panic was invoked, and the
 //!   line and column inside the file. It is up to consumers of this core
 //!   library to define this panic function; it is only required to never
-//!   return. This requires a `lang` attribute named `panic_fmt`.
+//!   return. This requires a `lang` attribute named `panic_impl`.
 //!
 //! * `rust_eh_personality` - is used by the failure mechanisms of the
 //!    compiler. This is often mapped to GCC's personality function, but crates
@@ -81,6 +81,7 @@
 #![feature(cfg_target_has_atomic)]
 #![feature(concat_idents)]
 #![feature(const_fn)]
+#![feature(const_int_ops)]
 #![feature(core_float)]
 #![feature(custom_attribute)]
 #![feature(doc_cfg)]
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index c033b670798..9fed4990345 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -635,8 +635,9 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
     }
 }
 
-/// Replaces the value at a mutable location with a new one, returning the old value, without
-/// deinitializing either one.
+/// Moves `src` into the referenced `dest`, returning the previous `dest` value.
+///
+/// Neither value is dropped.
 ///
 /// # Examples
 ///
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index e5dbc65cd99..577c823f9a0 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -31,7 +31,11 @@ pub const MANTISSA_DIGITS: u32 = 24;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const DIGITS: u32 = 6;
 
-/// Difference between `1.0` and the next largest representable number.
+/// [Machine epsilon] value for `f32`.
+///
+/// This is the difference between `1.0` and the next largest representable number.
+///
+/// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const EPSILON: f32 = 1.19209290e-07_f32;
 
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index eb769c4ad5a..b8e3dd6ed64 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -31,7 +31,11 @@ pub const MANTISSA_DIGITS: u32 = 53;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const DIGITS: u32 = 15;
 
-/// Difference between `1.0` and the next largest representable number.
+/// [Machine epsilon] value for `f64`.
+///
+/// This is the difference between `1.0` and the next largest representable number.
+///
+/// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const EPSILON: f64 = 2.2204460492503131e-16_f64;
 
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index ea652ad811e..26dd08b10b9 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -267,6 +267,16 @@ $EndFeature, "
 ```
 "),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
         }
@@ -282,6 +292,18 @@ Basic usage:
 ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 1);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn count_zeros(self) -> u32 {
+                (!self).count_ones()
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentatio"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn count_zeros(self) -> u32 {
                 (!self).count_ones()
@@ -302,6 +324,18 @@ assert_eq!(n.leading_zeros(), 0);",
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn leading_zeros(self) -> u32 {
+                (self as $UnsignedT).leading_zeros()
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn leading_zeros(self) -> u32 {
                 (self as $UnsignedT).leading_zeros()
@@ -322,6 +356,18 @@ assert_eq!(n.trailing_zeros(), 2);",
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn trailing_zeros(self) -> u32 {
+                (self as $UnsignedT).trailing_zeros()
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn trailing_zeros(self) -> u32 {
                 (self as $UnsignedT).trailing_zeros()
@@ -396,6 +442,16 @@ $EndFeature, "
         /// assert_eq!(m, 21760);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[cfg(not(stage0))]
+        #[rustc_const_unstable(feature = "const_int_ops")]
+        #[inline]
+        pub const fn swap_bytes(self) -> Self {
+            (self as $UnsignedT).swap_bytes() as Self
+        }
+
+        /// Dummy docs. See !stage0 documentation.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[cfg(stage0)]
         #[inline]
         pub fn swap_bytes(self) -> Self {
             (self as $UnsignedT).swap_bytes() as Self
@@ -447,6 +503,25 @@ if cfg!(target_endian = \"big\") {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn from_be(x: Self) -> Self {
+                #[cfg(target_endian = "big")]
+                {
+                    x
+                }
+                #[cfg(not(target_endian = "big"))]
+                {
+                    x.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn from_be(x: Self) -> Self {
                 if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
@@ -473,6 +548,25 @@ if cfg!(target_endian = \"little\") {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn from_le(x: Self) -> Self {
+                #[cfg(target_endian = "little")]
+                {
+                    x
+                }
+                #[cfg(not(target_endian = "little"))]
+                {
+                    x.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn from_le(x: Self) -> Self {
                 if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
@@ -499,6 +593,25 @@ if cfg!(target_endian = \"big\") {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn to_be(self) -> Self { // or not to be?
+                #[cfg(target_endian = "big")]
+                {
+                    self
+                }
+                #[cfg(not(target_endian = "big"))]
+                {
+                    self.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn to_be(self) -> Self { // or not to be?
                 if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
@@ -525,6 +638,25 @@ if cfg!(target_endian = \"little\") {
 $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn to_le(self) -> Self {
+                #[cfg(target_endian = "little")]
+                {
+                    self
+                }
+                #[cfg(not(target_endian = "little"))]
+                {
+                    self.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn to_le(self) -> Self {
                 if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
@@ -1943,6 +2075,19 @@ impl isize {
     int_impl! { isize, i64, u64, 64, -9223372036854775808, 9223372036854775807, "", "" }
 }
 
+// Emits the correct `cttz` call, depending on the size of the type.
+macro_rules! uint_cttz_call {
+    // As of LLVM 3.6 the codegen for the zero-safe cttz8 intrinsic
+    // emits two conditional moves on x86_64. By promoting the value to
+    // u16 and setting bit 8, we get better code without any conditional
+    // operations.
+    // FIXME: There's a LLVM patch (http://reviews.llvm.org/D9284)
+    // pending, remove this workaround once LLVM generates better code
+    // for cttz8.
+    ($value:expr, 8) => { intrinsics::cttz($value as u16 | 0x100) };
+    ($value:expr, $_BITS:expr) => { intrinsics::cttz($value) }
+}
+
 // `Int` + `UnsignedInt` implemented for unsigned integers
 macro_rules! uint_impl {
     ($SelfT:ty, $ActualT:ty, $BITS:expr, $MaxV:expr, $Feature:expr, $EndFeature:expr) => {
@@ -2020,6 +2165,18 @@ Basic usage:
 assert_eq!(n.count_ones(), 3);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn count_ones(self) -> u32 {
+                unsafe { intrinsics::ctpop(self as $ActualT) as u32 }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn count_ones(self) -> u32 {
                 unsafe { intrinsics::ctpop(self as $ActualT) as u32 }
@@ -2037,6 +2194,18 @@ Basic usage:
 ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 0);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn count_zeros(self) -> u32 {
+                (!self).count_ones()
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn count_zeros(self) -> u32 {
                 (!self).count_ones()
@@ -2056,6 +2225,18 @@ Basic usage:
 assert_eq!(n.leading_zeros(), 2);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn leading_zeros(self) -> u32 {
+                unsafe { intrinsics::ctlz(self as $ActualT) as u32 }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn leading_zeros(self) -> u32 {
                 unsafe { intrinsics::ctlz(self as $ActualT) as u32 }
@@ -2076,22 +2257,21 @@ Basic usage:
 assert_eq!(n.trailing_zeros(), 3);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn trailing_zeros(self) -> u32 {
+                unsafe { uint_cttz_call!(self, $BITS) as u32 }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn trailing_zeros(self) -> u32 {
-                // As of LLVM 3.6 the codegen for the zero-safe cttz8 intrinsic
-                // emits two conditional moves on x86_64. By promoting the value to
-                // u16 and setting bit 8, we get better code without any conditional
-                // operations.
-                // FIXME: There's a LLVM patch (http://reviews.llvm.org/D9284)
-                // pending, remove this workaround once LLVM generates better code
-                // for cttz8.
-                unsafe {
-                    if $BITS == 8 {
-                        intrinsics::cttz(self as u16 | 0x100) as u32
-                    } else {
-                        intrinsics::cttz(self) as u32
-                    }
-                }
+                unsafe { uint_cttz_call!(self, $BITS) as u32 }
             }
         }
 
@@ -2167,6 +2347,16 @@ assert_eq!(n.trailing_zeros(), 3);", $EndFeature, "
         /// assert_eq!(m, 21760);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[cfg(not(stage0))]
+        #[rustc_const_unstable(feature = "const_int_ops")]
+        #[inline]
+        pub const fn swap_bytes(self) -> Self {
+            unsafe { intrinsics::bswap(self as $ActualT) as Self }
+        }
+
+        /// Dummy docs. See !stage0 documentation.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[cfg(stage0)]
         #[inline]
         pub fn swap_bytes(self) -> Self {
             unsafe { intrinsics::bswap(self as $ActualT) as Self }
@@ -2218,6 +2408,25 @@ if cfg!(target_endian = \"big\") {
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn from_be(x: Self) -> Self {
+                #[cfg(target_endian = "big")]
+                {
+                    x
+                }
+                #[cfg(not(target_endian = "big"))]
+                {
+                    x.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn from_be(x: Self) -> Self {
                 if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
@@ -2244,6 +2453,25 @@ if cfg!(target_endian = \"little\") {
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn from_le(x: Self) -> Self {
+                #[cfg(target_endian = "little")]
+                {
+                    x
+                }
+                #[cfg(not(target_endian = "little"))]
+                {
+                    x.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn from_le(x: Self) -> Self {
                 if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
@@ -2270,6 +2498,25 @@ if cfg!(target_endian = \"big\") {
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn to_be(self) -> Self { // or not to be?
+                #[cfg(target_endian = "big")]
+                {
+                    self
+                }
+                #[cfg(not(target_endian = "big"))]
+                {
+                    self.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn to_be(self) -> Self { // or not to be?
                 if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
@@ -2296,6 +2543,25 @@ if cfg!(target_endian = \"little\") {
 }", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(not(stage0))]
+            #[rustc_const_unstable(feature = "const_int_ops")]
+            #[inline]
+            pub const fn to_le(self) -> Self {
+                #[cfg(target_endian = "little")]
+                {
+                    self
+                }
+                #[cfg(not(target_endian = "little"))]
+                {
+                    self.swap_bytes()
+                }
+            }
+        }
+
+        doc_comment! {
+            concat!("Dummy docs. See !stage0 documentation"),
+            #[stable(feature = "rust1", since = "1.0.0")]
+            #[cfg(stage0)]
             #[inline]
             pub fn to_le(self) -> Self {
                 if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs
index 27ec4aaac75..37ae05309af 100644
--- a/src/libcore/panic.rs
+++ b/src/libcore/panic.rs
@@ -35,6 +35,7 @@ use fmt;
 ///
 /// panic!("Normal panic");
 /// ```
+#[cfg_attr(not(stage0), lang = "panic_info")]
 #[stable(feature = "panic_hooks", since = "1.10.0")]
 #[derive(Debug)]
 pub struct PanicInfo<'a> {
@@ -53,7 +54,8 @@ impl<'a> PanicInfo<'a> {
     pub fn internal_constructor(message: Option<&'a fmt::Arguments<'a>>,
                                 location: Location<'a>)
                                 -> Self {
-        PanicInfo { payload: &(), location, message }
+        struct NoPayload;
+        PanicInfo { payload: &NoPayload, location, message }
     }
 
     #[doc(hidden)]
@@ -121,7 +123,7 @@ impl<'a> PanicInfo<'a> {
     #[stable(feature = "panic_hooks", since = "1.10.0")]
     pub fn location(&self) -> Option<&Location> {
         // NOTE: If this is changed to sometimes return None,
-        // deal with that case in std::panicking::default_hook.
+        // deal with that case in std::panicking::default_hook and std::panicking::begin_panic_fmt.
         Some(&self.location)
     }
 }
diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs
index 6b3dc75af46..0d4f8d1141e 100644
--- a/src/libcore/panicking.rs
+++ b/src/libcore/panicking.rs
@@ -37,6 +37,8 @@
             issue = "0")]
 
 use fmt;
+#[cfg(not(stage0))]
+use panic::{Location, PanicInfo};
 
 #[cold] #[inline(never)] // this is the slow path, always
 #[lang = "panic"]
@@ -59,6 +61,7 @@ fn panic_bounds_check(file_line_col: &(&'static str, u32, u32),
                            len, index), file_line_col)
 }
 
+#[cfg(stage0)]
 #[cold] #[inline(never)]
 pub fn panic_fmt(fmt: fmt::Arguments, file_line_col: &(&'static str, u32, u32)) -> ! {
     #[allow(improper_ctypes)]
@@ -70,3 +73,21 @@ pub fn panic_fmt(fmt: fmt::Arguments, file_line_col: &(&'static str, u32, u32))
     let (file, line, col) = *file_line_col;
     unsafe { panic_impl(fmt, file, line, col) }
 }
+
+#[cfg(not(stage0))]
+#[cold] #[inline(never)]
+pub fn panic_fmt(fmt: fmt::Arguments, file_line_col: &(&'static str, u32, u32)) -> ! {
+    // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
+    #[allow(improper_ctypes)] // PanicInfo contains a trait object which is not FFI safe
+    extern "Rust" {
+        #[lang = "panic_impl"]
+        fn panic_impl(pi: &PanicInfo) -> !;
+    }
+
+    let (file, line, col) = *file_line_col;
+    let pi = PanicInfo::internal_constructor(
+        Some(&fmt),
+        Location::internal_constructor(file, line, col),
+    );
+    unsafe { panic_impl(&pi) }
+}
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 6c0709caa08..39315d8f0c8 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -239,8 +239,9 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
     }
 }
 
-/// Replaces the value at `dest` with `src`, returning the old
-/// value, without dropping either.
+/// Moves `src` into the pointed `dest`, returning the previous `dest` value.
+///
+/// Neither value is dropped.
 ///
 /// # Safety
 ///
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index d52cc8cbe3f..c5792d62aa9 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -1977,35 +1977,63 @@ fn slice_index_overflow_fail() -> ! {
     panic!("attempted to index slice up to maximum usize");
 }
 
+mod private_slice_index {
+    use super::ops;
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    pub trait Sealed {}
+
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for usize {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::Range<usize> {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::RangeTo<usize> {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::RangeFrom<usize> {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::RangeFull {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::RangeInclusive<usize> {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::RangeToInclusive<usize> {}
+}
+
 /// A helper trait used for indexing operations.
-#[unstable(feature = "slice_get_slice", issue = "35729")]
+#[stable(feature = "slice_get_slice", since = "1.28.0")]
 #[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
-pub trait SliceIndex<T: ?Sized> {
+pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
     /// The output type returned by methods.
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
     type Output: ?Sized;
 
     /// Returns a shared reference to the output at this location, if in
     /// bounds.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     fn get(self, slice: &T) -> Option<&Self::Output>;
 
     /// Returns a mutable reference to the output at this location, if in
     /// bounds.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
 
     /// Returns a shared reference to the output at this location, without
     /// performing any bounds checking.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     unsafe fn get_unchecked(self, slice: &T) -> &Self::Output;
 
     /// Returns a mutable reference to the output at this location, without
     /// performing any bounds checking.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output;
 
     /// Returns a shared reference to the output at this location, panicking
     /// if out of bounds.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     fn index(self, slice: &T) -> &Self::Output;
 
     /// Returns a mutable reference to the output at this location, panicking
     /// if out of bounds.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     fn index_mut(self, slice: &mut T) -> &mut Self::Output;
 }
 
@@ -2513,6 +2541,12 @@ macro_rules! iterator {
                 accum
             }
         }
+
+        #[stable(feature = "fused", since = "1.26.0")]
+        impl<'a, T> FusedIterator for $name<'a, T> {}
+
+        #[unstable(feature = "trusted_len", issue = "37572")]
+        unsafe impl<'a, T> TrustedLen for $name<'a, T> {}
     }
 }
 
@@ -2639,12 +2673,6 @@ impl<'a, T> ExactSizeIterator for Iter<'a, T> {
     }
 }
 
-#[stable(feature = "fused", since = "1.26.0")]
-impl<'a, T> FusedIterator for Iter<'a, T> {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<'a, T> TrustedLen for Iter<'a, T> {}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Clone for Iter<'a, T> {
     fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } }
@@ -2706,9 +2734,7 @@ impl<'a, T> IterMut<'a, T> {
     /// View the underlying data as a subslice of the original data.
     ///
     /// To avoid creating `&mut` references that alias, this is forced
-    /// to consume the iterator. Consider using the `Slice` and
-    /// `SliceMut` implementations for obtaining slices with more
-    /// restricted lifetimes that do not consume the iterator.
+    /// to consume the iterator.
     ///
     /// # Examples
     ///
@@ -2767,13 +2793,6 @@ impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
     }
 }
 
-#[stable(feature = "fused", since = "1.26.0")]
-impl<'a, T> FusedIterator for IterMut<'a, T> {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<'a, T> TrustedLen for IterMut<'a, T> {}
-
-
 // Return the number of elements of `T` from `start` to `end`.
 // Return the arithmetic difference if `T` is zero size.
 #[inline(always)]
@@ -3371,6 +3390,9 @@ impl<'a, T> DoubleEndedIterator for Windows<'a, T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> ExactSizeIterator for Windows<'a, T> {}
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T> TrustedLen for Windows<'a, T> {}
+
 #[stable(feature = "fused", since = "1.26.0")]
 impl<'a, T> FusedIterator for Windows<'a, T> {}
 
@@ -3490,6 +3512,9 @@ impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> ExactSizeIterator for Chunks<'a, T> {}
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T> TrustedLen for Chunks<'a, T> {}
+
 #[stable(feature = "fused", since = "1.26.0")]
 impl<'a, T> FusedIterator for Chunks<'a, T> {}
 
@@ -3606,6 +3631,9 @@ impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {}
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T> TrustedLen for ChunksMut<'a, T> {}
+
 #[stable(feature = "fused", since = "1.26.0")]
 impl<'a, T> FusedIterator for ChunksMut<'a, T> {}
 
@@ -3716,6 +3744,9 @@ impl<'a, T> ExactSizeIterator for ExactChunks<'a, T> {
     }
 }
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T> TrustedLen for ExactChunks<'a, T> {}
+
 #[unstable(feature = "exact_chunks", issue = "47115")]
 impl<'a, T> FusedIterator for ExactChunks<'a, T> {}
 
@@ -3813,6 +3844,9 @@ impl<'a, T> ExactSizeIterator for ExactChunksMut<'a, T> {
     }
 }
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T> TrustedLen for ExactChunksMut<'a, T> {}
+
 #[unstable(feature = "exact_chunks", issue = "47115")]
 impl<'a, T> FusedIterator for ExactChunksMut<'a, T> {}
 
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 3169893fcde..5e1a9c25a21 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -3875,6 +3875,12 @@ impl<'a> Default for &'a str {
     fn default() -> &'a str { "" }
 }
 
+#[stable(feature = "default_mut_str", since = "1.28.0")]
+impl<'a> Default for &'a mut str {
+    /// Creates an empty mutable str
+    fn default() -> &'a mut str { unsafe { from_utf8_unchecked_mut(&mut []) } }
+}
+
 /// An iterator over the non-whitespace substrings of a string,
 /// separated by any amount of whitespace.
 ///
diff --git a/src/libcore/time.rs b/src/libcore/time.rs
index a1815b5f5ef..563eea0066d 100644
--- a/src/libcore/time.rs
+++ b/src/libcore/time.rs
@@ -268,6 +268,57 @@ impl Duration {
     #[inline]
     pub const fn subsec_nanos(&self) -> u32 { self.nanos }
 
+    /// Returns the total number of milliseconds contained by this `Duration`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(duration_as_u128)]
+    /// use std::time::Duration;
+    ///
+    /// let duration = Duration::new(5, 730023852);
+    /// assert_eq!(duration.as_millis(), 5730);
+    /// ```
+    #[unstable(feature = "duration_as_u128", issue = "50202")]
+    #[inline]
+    pub fn as_millis(&self) -> u128 {
+        self.secs as u128 * MILLIS_PER_SEC as u128 + (self.nanos / NANOS_PER_MILLI) as u128
+    }
+
+    /// Returns the total number of microseconds contained by this `Duration`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(duration_as_u128)]
+    /// use std::time::Duration;
+    ///
+    /// let duration = Duration::new(5, 730023852);
+    /// assert_eq!(duration.as_micros(), 5730023);
+    /// ```
+    #[unstable(feature = "duration_as_u128", issue = "50202")]
+    #[inline]
+    pub fn as_micros(&self) -> u128 {
+        self.secs as u128 * MICROS_PER_SEC as u128 + (self.nanos / NANOS_PER_MICRO) as u128
+    }
+
+    /// Returns the total number of nanoseconds contained by this `Duration`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(duration_as_u128)]
+    /// use std::time::Duration;
+    ///
+    /// let duration = Duration::new(5, 730023852);
+    /// assert_eq!(duration.as_nanos(), 5730023852);
+    /// ```
+    #[unstable(feature = "duration_as_u128", issue = "50202")]
+    #[inline]
+    pub fn as_nanos(&self) -> u128 {
+        self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos as u128
+    }
+
     /// Checked `Duration` addition. Computes `self + other`, returning [`None`]
     /// if overflow occurred.
     ///
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index 2662e709991..61f05ca3473 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -637,8 +637,8 @@ Erroneous code example:
 ```compile_fail,E0152
 #![feature(lang_items)]
 
-#[lang = "panic_fmt"]
-struct Foo; // error: duplicate lang item found: `panic_fmt`
+#[lang = "panic_impl"]
+struct Foo; // error: duplicate lang item found: `panic_impl`
 ```
 
 Lang items are already implemented in the standard library. Unless you are
@@ -824,7 +824,7 @@ A list of available external lang items is available in
 #![feature(lang_items)]
 
 extern "C" {
-    #[lang = "panic_fmt"] // ok!
+    #[lang = "panic_impl"] // ok!
     fn cake();
 }
 ```
diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index ae1cf6046fb..0adbdbe9933 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -134,9 +134,6 @@ pub struct Export {
     /// The visibility of the export.
     /// We include non-`pub` exports for hygienic macros that get used from extern crates.
     pub vis: ty::Visibility,
-    /// True if from a `use` or and `extern crate`.
-    /// Used in rustdoc.
-    pub is_import: bool,
 }
 
 impl CtorKind {
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index f816ba9ab81..1e48a54e018 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -2433,7 +2433,7 @@ impl<'a> LoweringContext<'a> {
                     self.with_hir_id_owner(new_id, |this| {
                         let vis = match vis {
                             hir::Visibility::Public => hir::Visibility::Public,
-                            hir::Visibility::Crate => hir::Visibility::Crate,
+                            hir::Visibility::Crate(sugar) => hir::Visibility::Crate(sugar),
                             hir::Visibility::Inherited => hir::Visibility::Inherited,
                             hir::Visibility::Restricted { ref path, id: _ } => {
                                 hir::Visibility::Restricted {
@@ -3704,7 +3704,7 @@ impl<'a> LoweringContext<'a> {
     ) -> hir::Visibility {
         match v.node {
             VisibilityKind::Public => hir::Public,
-            VisibilityKind::Crate(..) => hir::Visibility::Crate,
+            VisibilityKind::Crate(sugar) => hir::Visibility::Crate(sugar),
             VisibilityKind::Restricted { ref path, id, .. } => hir::Visibility::Restricted {
                 path: P(self.lower_path(id, path, ParamMode::Explicit)),
                 id: if let Some(owner) = explicit_owner {
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index 13df1ced603..7835d4e782c 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -463,7 +463,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     fn visit_vis(&mut self, visibility: &'hir Visibility) {
         match *visibility {
             Visibility::Public |
-            Visibility::Crate |
+            Visibility::Crate(_) |
             Visibility::Inherited => {}
             Visibility::Restricted { id, .. } => {
                 self.insert(id, NodeVisibility(visibility));
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index ebc59964172..b7c66398f85 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -35,7 +35,7 @@ use mir::mono::Linkage;
 use syntax_pos::{Span, DUMMY_SP};
 use syntax::codemap::{self, Spanned};
 use rustc_target::spec::abi::Abi;
-use syntax::ast::{self, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
+use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, DUMMY_NODE_ID, AsmDialect};
 use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem};
 use syntax::attr::InlineAttr;
 use syntax::ext::hygiene::SyntaxContext;
@@ -1953,7 +1953,7 @@ pub struct PolyTraitRef {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Visibility {
     Public,
-    Crate,
+    Crate(CrateSugar),
     Restricted { path: P<Path>, id: NodeId },
     Inherited,
 }
@@ -1964,7 +1964,7 @@ impl Visibility {
         match self {
             &Public |
             &Inherited => false,
-            &Crate |
+            &Crate(_) |
             &Restricted { .. } => true,
         }
     }
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 4bee4f9add0..2cf627fdc16 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -801,15 +801,25 @@ impl<'a> State<'a> {
 
     pub fn print_visibility(&mut self, vis: &hir::Visibility) -> io::Result<()> {
         match *vis {
-            hir::Public => self.word_nbsp("pub"),
-            hir::Visibility::Crate => self.word_nbsp("pub(crate)"),
+            hir::Public => self.word_nbsp("pub")?,
+            hir::Visibility::Crate(ast::CrateSugar::JustCrate) => self.word_nbsp("crate")?,
+            hir::Visibility::Crate(ast::CrateSugar::PubCrate) => self.word_nbsp("pub(crate)")?,
             hir::Visibility::Restricted { ref path, .. } => {
                 self.s.word("pub(")?;
-                self.print_path(path, false)?;
-                self.word_nbsp(")")
+                if path.segments.len() == 1 && path.segments[0].name == keywords::Super.name() {
+                    // Special case: `super` can print like `pub(super)`.
+                    self.s.word("super")?;
+                } else {
+                    // Everything else requires `in` at present.
+                    self.word_nbsp("in")?;
+                    self.print_path(path, false)?;
+                }
+                self.word_nbsp(")")?;
             }
-            hir::Inherited => Ok(()),
+            hir::Inherited => ()
         }
+
+        Ok(())
     }
 
     pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) -> io::Result<()> {
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index 9b202f55f3c..a781fc7240a 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -751,6 +751,11 @@ impl_stable_hash_for!(enum hir::ImplItemKind {
     Type(t)
 });
 
+impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
+    JustCrate,
+    PubCrate,
+});
+
 impl<'a> HashStable<StableHashingContext<'a>> for hir::Visibility {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
@@ -758,10 +763,12 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Visibility {
         mem::discriminant(self).hash_stable(hcx, hasher);
         match *self {
             hir::Visibility::Public |
-            hir::Visibility::Crate |
             hir::Visibility::Inherited => {
                 // No fields to hash.
             }
+            hir::Visibility::Crate(sugar) => {
+                sugar.hash_stable(hcx, hasher);
+            }
             hir::Visibility::Restricted { ref path, id } => {
                 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
                     id.hash_stable(hcx, hasher);
@@ -1108,8 +1115,7 @@ impl_stable_hash_for!(struct hir::def::Export {
     ident,
     def,
     vis,
-    span,
-    is_import
+    span
 });
 
 impl<'a> HashStable<StableHashingContext<'a>>
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index e3b20789714..7ebc0d4a4de 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -284,7 +284,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
 fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt,
                                     id: ast::NodeId,
                                     attrs: &[ast::Attribute]) -> bool {
-    if attr::contains_name(attrs, "lang") {
+    if attr::contains_name(attrs, "lang") || attr::contains_name(attrs, "panic_implementation") {
         return true;
     }
 
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index d70f994e87b..fe676919a7d 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -185,6 +185,8 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
             if let Some(value) = attribute.value_str() {
                 return Some((value, attribute.span));
             }
+        } else if attribute.check_name("panic_implementation") {
+            return Some((Symbol::intern("panic_impl"), attribute.span))
         }
     }
 
@@ -299,7 +301,8 @@ language_item_table! {
     // lang item, but do not have it defined.
     PanicFnLangItem,                 "panic",                   panic_fn;
     PanicBoundsCheckFnLangItem,      "panic_bounds_check",      panic_bounds_check_fn;
-    PanicFmtLangItem,                "panic_fmt",               panic_fmt;
+    PanicInfoLangItem,               "panic_info",              panic_info;
+    PanicImplLangItem,               "panic_impl",              panic_impl;
 
     ExchangeMallocFnLangItem,        "exchange_malloc",         exchange_malloc_fn;
     BoxFreeFnLangItem,               "box_free",                box_free_fn;
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index f2120d97868..959dda69e30 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -936,16 +936,32 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                            span: Span,
                            expr_ty: Ty<'tcx>)
                            -> cmt_<'tcx> {
+        debug!(
+            "cat_rvalue_node(id={:?}, span={:?}, expr_ty={:?})",
+            id,
+            span,
+            expr_ty,
+        );
         let hir_id = self.tcx.hir.node_to_hir_id(id);
         let promotable = self.rvalue_promotable_map.as_ref().map(|m| m.contains(&hir_id.local_id))
                                                             .unwrap_or(false);
 
+        debug!(
+            "cat_rvalue_node: promotable = {:?}",
+            promotable,
+        );
+
         // Always promote `[T; 0]` (even when e.g. borrowed mutably).
         let promotable = match expr_ty.sty {
             ty::TyArray(_, len) if len.assert_usize(self.tcx) == Some(0) => true,
             _ => promotable,
         };
 
+        debug!(
+            "cat_rvalue_node: promotable = {:?} (2)",
+            promotable,
+        );
+
         // Compute maximum lifetime of this rvalue. This is 'static if
         // we can promote to a constant, otherwise equal to enclosing temp
         // lifetime.
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index 42e4d3861ba..3c2ea047218 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -148,7 +148,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
 ) }
 
 weak_lang_items! {
-    panic_fmt,          PanicFmtLangItem,           rust_begin_unwind;
+    panic_impl,         PanicImplLangItem,          rust_begin_unwind;
     eh_personality,     EhPersonalityLangItem,      rust_eh_personality;
     eh_unwind_resume,   EhUnwindResumeLangItem,     rust_eh_unwind_resume;
     oom,                OomLangItem,                rust_oom;
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index cc8e8c7c31c..2c8f021c6a5 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1304,8 +1304,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "enable polonius-based borrow-checker"),
     codegen_time_graph: bool = (false, parse_bool, [UNTRACKED],
         "generate a graphical HTML report of time spent in codegen and LLVM"),
-    trans_time_graph: bool = (false, parse_bool, [UNTRACKED],
-        "generate a graphical HTML report of time spent in trans and LLVM"),
     thinlto: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "enable ThinLTO when possible"),
     inline_in_all_cgus: Option<bool> = (None, parse_opt_bool, [TRACKED],
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index c6b1d94e597..82f351782bb 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -146,7 +146,7 @@ impl<'tcx> ProjectionTyCandidateSet<'tcx> {
         // was not used). On other paths, it is not assigned,
         // and hence if those paths *could* reach the code that
         // comes after the match, this fn would not compile.
-        let convert_to_ambigious;
+        let convert_to_ambiguous;
 
         match self {
             None => {
@@ -169,10 +169,10 @@ impl<'tcx> ProjectionTyCandidateSet<'tcx> {
                 // clauses are the safer choice. See the comment on
                 // `select::SelectionCandidate` and #21974 for more details.
                 match (current, candidate) {
-                    (ParamEnv(..), ParamEnv(..)) => convert_to_ambigious = (),
+                    (ParamEnv(..), ParamEnv(..)) => convert_to_ambiguous = (),
                     (ParamEnv(..), _) => return false,
                     (_, ParamEnv(..)) => { unreachable!(); }
-                    (_, _) => convert_to_ambigious = (),
+                    (_, _) => convert_to_ambiguous = (),
                 }
             }
 
@@ -183,7 +183,7 @@ impl<'tcx> ProjectionTyCandidateSet<'tcx> {
 
         // We only ever get here when we moved from a single candidate
         // to ambiguous.
-        let () = convert_to_ambigious;
+        let () = convert_to_ambiguous;
         *self = Ambiguous;
         false
     }
diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs
index 1e9e9c056c9..f08b95f59fa 100644
--- a/src/librustc/traits/query/normalize.rs
+++ b/src/librustc/traits/query/normalize.rs
@@ -33,7 +33,7 @@ impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
     /// normalized. If you don't care about regions, you should prefer
     /// `normalize_erasing_regions`, which is more efficient.
     ///
-    /// If the normalization succeeds and is unambigious, returns back
+    /// If the normalization succeeds and is unambiguous, returns back
     /// the normalized value along with various outlives relations (in
     /// the form of obligations that must be discharged).
     ///
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index f0f4adde7ee..0bb0208e2a1 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -270,7 +270,7 @@ impl Visibility {
     pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: TyCtxt) -> Self {
         match *visibility {
             hir::Public => Visibility::Public,
-            hir::Visibility::Crate => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
+            hir::Visibility::Crate(_) => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
             hir::Visibility::Restricted { ref path, .. } => match path.def {
                 // If there is no resolution, `resolve` will have already reported an error, so
                 // assume that the visibility is public to avoid reporting more privacy errors.
diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs
index 735c4d2f76f..4e9910e58f3 100644
--- a/src/librustc_codegen_llvm/back/link.rs
+++ b/src/librustc_codegen_llvm/back/link.rs
@@ -625,6 +625,11 @@ fn link_natively(sess: &Session,
     if let Some(args) = sess.target.target.options.pre_link_args.get(&flavor) {
         cmd.args(args);
     }
+    if let Some(args) = sess.target.target.options.pre_link_args_crt.get(&flavor) {
+        if sess.crt_static() {
+            cmd.args(args);
+        }
+    }
     if let Some(ref args) = sess.opts.debugging_opts.pre_link_args {
         cmd.args(args);
     }
@@ -639,6 +644,12 @@ fn link_natively(sess: &Session,
         cmd.arg(root.join(obj));
     }
 
+    if crate_type == config::CrateTypeExecutable && sess.crt_static() {
+        for obj in &sess.target.target.options.pre_link_objects_exe_crt {
+            cmd.arg(root.join(obj));
+        }
+    }
+
     if sess.target.target.options.is_like_emscripten {
         cmd.arg("-s");
         cmd.arg(if sess.panic_strategy() == PanicStrategy::Abort {
@@ -660,6 +671,11 @@ fn link_natively(sess: &Session,
     for obj in &sess.target.target.options.post_link_objects {
         cmd.arg(root.join(obj));
     }
+    if sess.crt_static() {
+        for obj in &sess.target.target.options.post_link_objects_crt {
+            cmd.arg(root.join(obj));
+        }
+    }
     if let Some(args) = sess.target.target.options.post_link_args.get(&flavor) {
         cmd.args(args);
     }
diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs
index 1669059a760..14d20b6dbe2 100644
--- a/src/librustc_codegen_llvm/mir/block.rs
+++ b/src/librustc_codegen_llvm/mir/block.rs
@@ -191,14 +191,23 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
 
             mir::TerminatorKind::SwitchInt { ref discr, switch_ty, ref values, ref targets } => {
                 let discr = self.codegen_operand(&bx, discr);
-                if switch_ty == bx.tcx().types.bool {
+                if targets.len() == 2 {
+                    // If there are two targets, emit br instead of switch
                     let lltrue = llblock(self, targets[0]);
                     let llfalse = llblock(self, targets[1]);
-                    if let [0] = values[..] {
-                        bx.cond_br(discr.immediate(), llfalse, lltrue);
+                    if switch_ty == bx.tcx().types.bool {
+                        // Don't generate trivial icmps when switching on bool
+                        if let [0] = values[..] {
+                            bx.cond_br(discr.immediate(), llfalse, lltrue);
+                        } else {
+                            assert_eq!(&values[..], &[1]);
+                            bx.cond_br(discr.immediate(), lltrue, llfalse);
+                        }
                     } else {
-                        assert_eq!(&values[..], &[1]);
-                        bx.cond_br(discr.immediate(), lltrue, llfalse);
+                        let switch_llty = bx.cx.layout_of(switch_ty).immediate_llvm_type(bx.cx);
+                        let llval = C_uint_big(switch_llty, values[0]);
+                        let cmp = bx.icmp(llvm::IntEQ, discr.immediate(), llval);
+                        bx.cond_br(cmp, lltrue, llfalse);
                     }
                 } else {
                     let (otherwise, targets) = targets.split_last().unwrap();
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 8a0850595c8..79c7a791147 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1548,72 +1548,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedBrokenConst {
     }
 }
 
-declare_lint! {
-    pub UNNECESSARY_EXTERN_CRATES,
-    Allow,
-    "suggest removing `extern crate` for the 2018 edition"
-}
-
-pub struct ExternCrate(/* depth */ u32);
-
-impl ExternCrate {
-    pub fn new() -> Self {
-        ExternCrate(0)
-    }
-}
-
-impl LintPass for ExternCrate {
-    fn get_lints(&self) -> LintArray {
-        lint_array!(UNNECESSARY_EXTERN_CRATES)
-    }
-}
-
-impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExternCrate {
-    fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
-        if !cx.tcx.features().extern_absolute_paths {
-            return
-        }
-        if let hir::ItemExternCrate(ref orig) =  it.node {
-            if it.attrs.iter().any(|a| a.check_name("macro_use")) {
-                return
-            }
-            let mut err = cx.struct_span_lint(UNNECESSARY_EXTERN_CRATES,
-                it.span, "`extern crate` is unnecessary in the new edition");
-            if it.vis == hir::Visibility::Public || self.0 > 1 || orig.is_some() {
-                let pub_ = if it.vis == hir::Visibility::Public {
-                    "pub "
-                } else {
-                    ""
-                };
-
-                let help = format!("use `{}use`", pub_);
-
-                if let Some(orig) = orig {
-                    err.span_suggestion(it.span, &help,
-                        format!("{}use {} as {};", pub_, orig, it.name));
-                } else {
-                    err.span_suggestion(it.span, &help,
-                        format!("{}use {};", pub_, it.name));
-                }
-            } else {
-                err.span_suggestion(it.span, "remove it", "".into());
-            }
-
-            err.emit();
-        }
-    }
-
-    fn check_mod(&mut self, _: &LateContext, _: &hir::Mod,
-                 _: Span, _: ast::NodeId) {
-        self.0 += 1;
-    }
-
-    fn check_mod_post(&mut self, _: &LateContext, _: &hir::Mod,
-                      _: Span, _: ast::NodeId) {
-        self.0 += 1;
-    }
-}
-
 /// Lint for trait and lifetime bounds that don't depend on type parameters
 /// which either do nothing, or stop the item from being used.
 pub struct TrivialConstraints;
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index c5994d0536e..d6ce5b2ea57 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -145,7 +145,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
                           TypeLimits,
                           MissingDoc,
                           MissingDebugImplementations,
-                          ExternCrate,
                           );
 
     add_lint_group!(sess,
@@ -185,7 +184,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
                     "rust_2018_idioms",
                     BARE_TRAIT_OBJECTS,
                     UNREACHABLE_PUB,
-                    UNNECESSARY_EXTERN_CRATES);
+                    UNUSED_EXTERN_CRATES);
 
     // Guidelines for creating a future incompatibility lint:
     //
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 69e873bb95d..fd00cde375b 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -665,7 +665,6 @@ impl<'a, 'tcx> CrateMetadata {
                         def: def,
                         vis: ty::Visibility::Public,
                         span: DUMMY_SP,
-                        is_import: false,
                     });
                 }
             }
@@ -705,7 +704,6 @@ impl<'a, 'tcx> CrateMetadata {
                                     ident: Ident::from_interned_str(self.item_name(child_index)),
                                     vis: self.get_visibility(child_index),
                                     span: self.entry(child_index).span.decode((self, sess)),
-                                    is_import: false,
                                 });
                             }
                         }
@@ -722,8 +720,7 @@ impl<'a, 'tcx> CrateMetadata {
                     (self.get_def(child_index), def_key.disambiguated_data.data.get_opt_name()) {
                     let ident = Ident::from_interned_str(name);
                     let vis = self.get_visibility(child_index);
-                    let is_import = false;
-                    callback(def::Export { def, ident, vis, span, is_import });
+                    callback(def::Export { def, ident, vis, span });
                     // For non-re-export structs and variants add their constructors to children.
                     // Re-export lists automatically contain constructors when necessary.
                     match def {
@@ -734,7 +731,7 @@ impl<'a, 'tcx> CrateMetadata {
                                 callback(def::Export {
                                     def: ctor_def,
                                     vis: self.get_visibility(ctor_def_id.index),
-                                    ident, span, is_import,
+                                    ident, span,
                                 });
                             }
                         }
@@ -744,7 +741,7 @@ impl<'a, 'tcx> CrateMetadata {
                             let ctor_kind = self.get_ctor_kind(child_index);
                             let ctor_def = Def::VariantCtor(def_id, ctor_kind);
                             let vis = self.get_visibility(child_index);
-                            callback(def::Export { def: ctor_def, ident, vis, span, is_import });
+                            callback(def::Export { def: ctor_def, ident, vis, span });
                         }
                         _ => {}
                     }
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index fedd0774df4..4c282f037a5 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -362,8 +362,8 @@ fn unsafe_derive_on_repr_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: D
         format!("#[derive] can't be used on a #[repr(packed)] struct with \
                  type parameters (error E0133)")
     } else {
-        format!("#[derive] can't be used on a non-Copy #[repr(packed)] struct \
-                 (error E0133)")
+        format!("#[derive] can't be used on a #[repr(packed)] struct that \
+                 does not derive Copy (error E0133)")
     };
     tcx.lint_node(SAFE_PACKED_BORROWS,
                   lint_node_id,
diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs
index 52ceb3ff595..74b9315f0c1 100644
--- a/src/librustc_passes/rvalue_promotion.rs
+++ b/src/librustc_passes/rvalue_promotion.rs
@@ -150,6 +150,23 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
                 span.allows_unstable();
         }
     }
+
+    /// While the `ExprUseVisitor` walks, we will identify which
+    /// expressions are borrowed, and insert their ids into this
+    /// table. Actually, we insert the "borrow-id", which is normally
+    /// the id of the expession being borrowed: but in the case of
+    /// `ref mut` borrows, the `id` of the pattern is
+    /// inserted. Therefore later we remove that entry from the table
+    /// and transfer it over to the value being matched. This will
+    /// then prevent said value from being promoted.
+    fn remove_mut_rvalue_borrow(&mut self, pat: &hir::Pat) -> bool {
+        let mut any_removed = false;
+        pat.walk(|p| {
+            any_removed |= self.mut_rvalue_borrows.remove(&p.id);
+            true
+        });
+        any_removed
+    }
 }
 
 impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
@@ -200,9 +217,15 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
     fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt) {
         match stmt.node {
             hir::StmtDecl(ref decl, _) => {
-                match decl.node {
-                    hir::DeclLocal(_) => {
+                match &decl.node {
+                    hir::DeclLocal(local) => {
                         self.promotable = false;
+
+                        if self.remove_mut_rvalue_borrow(&local.pat) {
+                            if let Some(init) = &local.init {
+                                self.mut_rvalue_borrows.insert(init.id);
+                            }
+                        }
                     }
                     // Item statements are allowed
                     hir::DeclItem(_) => {}
@@ -229,9 +252,7 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckCrateVisitor<'a, 'tcx> {
             // patterns and set that on the discriminator.
             let mut mut_borrow = false;
             for pat in arms.iter().flat_map(|arm| &arm.pats) {
-                if self.mut_rvalue_borrows.remove(&pat.id) {
-                    mut_borrow = true;
-                }
+                mut_borrow = self.remove_mut_rvalue_borrow(pat);
             }
             if mut_borrow {
                 self.mut_rvalue_borrows.insert(discr.id);
@@ -498,6 +519,14 @@ impl<'a, 'gcx, 'tcx> euv::Delegate<'tcx> for CheckCrateVisitor<'a, 'gcx> {
               _loan_region: ty::Region<'tcx>,
               bk: ty::BorrowKind,
               loan_cause: euv::LoanCause) {
+        debug!(
+            "borrow(borrow_id={:?}, cmt={:?}, bk={:?}, loan_cause={:?})",
+            borrow_id,
+            cmt,
+            bk,
+            loan_cause,
+        );
+
         // Kind of hacky, but we allow Unsafe coercions in constants.
         // These occur when we convert a &T or *T to a *U, as well as
         // when making a thin pointer (e.g., `*T`) into a fat pointer
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 0cc59e3129c..fe6909f7591 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -803,7 +803,6 @@ impl<'a> Resolver<'a> {
                     def: def,
                     vis: ty::Visibility::Public,
                     span: item.span,
-                    is_import: false,
                 });
             } else {
                 self.unused_macros.insert(def_id);
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 34f84597adf..c44f330128a 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -1008,7 +1008,6 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
                         def: def,
                         span: binding.span,
                         vis: binding.vis,
-                        is_import: true,
                     });
                 }
             }
diff --git a/src/librustc_target/spec/linux_musl_base.rs b/src/librustc_target/spec/linux_musl_base.rs
index 293f23eab38..7a3f3c2a518 100644
--- a/src/librustc_target/spec/linux_musl_base.rs
+++ b/src/librustc_target/spec/linux_musl_base.rs
@@ -15,7 +15,8 @@ pub fn opts() -> TargetOptions {
 
     // Make sure that the linker/gcc really don't pull in anything, including
     // default objects, libs, etc.
-    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-nostdlib".to_string());
+    base.pre_link_args_crt.insert(LinkerFlavor::Gcc, Vec::new());
+    base.pre_link_args_crt.get_mut(&LinkerFlavor::Gcc).unwrap().push("-nostdlib".to_string());
 
     // At least when this was tested, the linker would not add the
     // `GNU_EH_FRAME` program header to executables generated, which is required
@@ -55,9 +56,9 @@ pub fn opts() -> TargetOptions {
     //
     // Each target directory for musl has these object files included in it so
     // they'll be included from there.
-    base.pre_link_objects_exe.push("crt1.o".to_string());
-    base.pre_link_objects_exe.push("crti.o".to_string());
-    base.post_link_objects.push("crtn.o".to_string());
+    base.pre_link_objects_exe_crt.push("crt1.o".to_string());
+    base.pre_link_objects_exe_crt.push("crti.o".to_string());
+    base.post_link_objects_crt.push("crtn.o".to_string());
 
     // These targets statically link libc by default
     base.crt_static_default = true;
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index a0cbfe2fefa..e54cd773123 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -426,12 +426,13 @@ pub struct TargetOptions {
     /// Linker to invoke
     pub linker: Option<String>,
 
-    /// Linker arguments that are unconditionally passed *before* any
-    /// user-defined libraries.
-    pub pre_link_args: LinkArgs,
+    /// Linker arguments that are passed *before* any user-defined libraries.
+    pub pre_link_args: LinkArgs, // ... unconditionally
+    pub pre_link_args_crt: LinkArgs, // ... when linking with a bundled crt
     /// Objects to link before all others, always found within the
     /// sysroot folder.
-    pub pre_link_objects_exe: Vec<String>, // ... when linking an executable
+    pub pre_link_objects_exe: Vec<String>, // ... when linking an executable, unconditionally
+    pub pre_link_objects_exe_crt: Vec<String>, // ... when linking an executable with a bundled crt
     pub pre_link_objects_dll: Vec<String>, // ... when linking a dylib
     /// Linker arguments that are unconditionally passed after any
     /// user-defined but before post_link_objects.  Standard platform
@@ -439,7 +440,8 @@ pub struct TargetOptions {
     pub late_link_args: LinkArgs,
     /// Objects to link after all others, always found within the
     /// sysroot folder.
-    pub post_link_objects: Vec<String>,
+    pub post_link_objects: Vec<String>, // ... unconditionally
+    pub post_link_objects_crt: Vec<String>, // ... when linking with a bundled crt
     /// Linker arguments that are unconditionally passed *after* any
     /// user-defined libraries.
     pub post_link_args: LinkArgs,
@@ -639,6 +641,7 @@ impl Default for TargetOptions {
             is_builtin: false,
             linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.to_string()),
             pre_link_args: LinkArgs::new(),
+            pre_link_args_crt: LinkArgs::new(),
             post_link_args: LinkArgs::new(),
             asm_args: Vec::new(),
             cpu: "generic".to_string(),
@@ -672,8 +675,10 @@ impl Default for TargetOptions {
             position_independent_executables: false,
             relro_level: RelroLevel::None,
             pre_link_objects_exe: Vec::new(),
+            pre_link_objects_exe_crt: Vec::new(),
             pre_link_objects_dll: Vec::new(),
             post_link_objects: Vec::new(),
+            post_link_objects_crt: Vec::new(),
             late_link_args: LinkArgs::new(),
             link_env: Vec::new(),
             archive_format: "gnu".to_string(),
@@ -892,10 +897,13 @@ impl Target {
         key!(is_builtin, bool);
         key!(linker, optional);
         key!(pre_link_args, link_args);
+        key!(pre_link_args_crt, link_args);
         key!(pre_link_objects_exe, list);
+        key!(pre_link_objects_exe_crt, list);
         key!(pre_link_objects_dll, list);
         key!(late_link_args, link_args);
         key!(post_link_objects, list);
+        key!(post_link_objects_crt, list);
         key!(post_link_args, link_args);
         key!(link_env, env);
         key!(asm_args, list);
@@ -1097,10 +1105,13 @@ impl ToJson for Target {
         target_option_val!(is_builtin);
         target_option_val!(linker);
         target_option_val!(link_args - pre_link_args);
+        target_option_val!(link_args - pre_link_args_crt);
         target_option_val!(pre_link_objects_exe);
+        target_option_val!(pre_link_objects_exe_crt);
         target_option_val!(pre_link_objects_dll);
         target_option_val!(link_args - late_link_args);
         target_option_val!(post_link_objects);
+        target_option_val!(post_link_objects_crt);
         target_option_val!(link_args - post_link_args);
         target_option_val!(env - link_env);
         target_option_val!(asm_args);
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 6031984350b..86cd8d0fb2c 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -195,7 +195,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 let ty_string = self.ty_to_string(actual);
                 let is_method = mode == Mode::MethodCall;
                 let mut suggestion = None;
-                let type_str = if is_method {
+                let item_kind = if is_method {
                     "method"
                 } else if actual.is_enum() {
                     if let TyAdt(ref adt_def, _) = actual.sty {
@@ -235,7 +235,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                             span,
                             E0689,
                             "can't call {} `{}` on ambiguous numeric type `{}`",
-                            type_str,
+                            item_kind,
                             item_name,
                             ty_string
                         );
@@ -284,12 +284,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                             span,
                             E0599,
                             "no {} named `{}` found for type `{}` in the current scope",
-                            type_str,
+                            item_kind,
                             item_name,
                             ty_string
                         );
                         if let Some(suggestion) = suggestion {
-                            err.note(&format!("did you mean `{}::{}`?", type_str, suggestion));
+                            err.note(&format!("did you mean `{}::{}`?", ty_string, suggestion));
                         }
                         err
                     }
@@ -301,7 +301,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     if let Some(full_sp) = tcx.hir.span_if_local(def.did) {
                         let def_sp = tcx.sess.codemap().def_span(full_sp);
                         err.span_label(def_sp, format!("{} `{}` not found {}",
-                                                       type_str,
+                                                       item_kind,
                                                        item_name,
                                                        if def.is_enum() && !is_method {
                                                            "here"
@@ -355,7 +355,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         }
                     }
                 } else {
-                    err.span_label(span, format!("{} not found in `{}`", type_str, ty_string));
+                    err.span_label(span, format!("{} not found in `{}`", item_kind, ty_string));
                 }
 
                 if self.is_fn_ty(&rcvr_ty, span) {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 90b974fb972..c2c71d90f06 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -96,7 +96,7 @@ use rustc::middle::region;
 use rustc::mir::interpret::{GlobalId};
 use rustc::ty::subst::{UnpackedKind, Subst, Substs};
 use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
-use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate};
+use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate, RegionKind};
 use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::maps::Providers;
@@ -130,7 +130,7 @@ use syntax_pos::{self, BytePos, Span, MultiSpan};
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::hir::map::Node;
-use rustc::hir::{self, PatKind};
+use rustc::hir::{self, PatKind, Item_};
 use rustc::middle::lang_items;
 
 mod autoderef;
@@ -1129,6 +1129,60 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
         }
     }
 
+    // Check that a function marked as `#[panic_implementation]` has signature `fn(&PanicInfo) -> !`
+    if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
+        if panic_impl_did == fn_hir_id.owner_def_id() {
+            if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
+                if declared_ret_ty.sty != ty::TyNever {
+                    fcx.tcx.sess.span_err(
+                        decl.output.span(),
+                        "return type should be `!`",
+                    );
+                }
+
+                let inputs = fn_sig.inputs();
+                let span = fcx.tcx.hir.span(fn_id);
+                if inputs.len() == 1 {
+                    let arg_is_panic_info = match inputs[0].sty {
+                        ty::TyRef(region, ty, mutbl) => match ty.sty {
+                            ty::TyAdt(ref adt, _) => {
+                                adt.did == panic_info_did &&
+                                    mutbl == hir::Mutability::MutImmutable &&
+                                    *region != RegionKind::ReStatic
+                            },
+                            _ => false,
+                        },
+                        _ => false,
+                    };
+
+                    if !arg_is_panic_info {
+                        fcx.tcx.sess.span_err(
+                            decl.inputs[0].span,
+                            "argument should be `&PanicInfo`",
+                        );
+                    }
+
+                    if let Node::NodeItem(item) = fcx.tcx.hir.get(fn_id) {
+                        if let Item_::ItemFn(_, _, _, _, ref generics, _) = item.node {
+                            if !generics.params.is_empty() {
+                                fcx.tcx.sess.span_err(
+                                    span,
+                                    "`#[panic_implementation]` function should have no type \
+                                     parameters",
+                                );
+                            }
+                        }
+                    }
+                } else {
+                    fcx.tcx.sess.span_err(span, "function should have one argument");
+                }
+            } else {
+                fcx.tcx.sess.err("language item required, but not found: `panic_info`");
+            }
+        }
+
+    }
+
     (fcx, gen_ty)
 }
 
diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs
index bff849d7ae8..41adde0d4a1 100644
--- a/src/librustc_typeck/check_unused.rs
+++ b/src/librustc_typeck/check_unused.rs
@@ -14,11 +14,46 @@ use rustc::ty::TyCtxt;
 use syntax::ast;
 use syntax_pos::{Span, DUMMY_SP};
 
-use rustc::hir::def_id::LOCAL_CRATE;
+use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
+use rustc::hir::print::visibility_qualified;
 use rustc::hir;
 use rustc::util::nodemap::DefIdSet;
 
+use rustc_data_structures::fx::FxHashMap;
+
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
+    let mut used_trait_imports = DefIdSet();
+    for &body_id in tcx.hir.krate().bodies.keys() {
+        let item_def_id = tcx.hir.body_owner_def_id(body_id);
+        let imports = tcx.used_trait_imports(item_def_id);
+        debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);
+        used_trait_imports.extend(imports.iter());
+    }
+
+    let mut visitor = CheckVisitor { tcx, used_trait_imports };
+    tcx.hir.krate().visit_all_item_likes(&mut visitor);
+
+    unused_crates_lint(tcx);
+}
+
+impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CheckVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, item: &hir::Item) {
+        if item.vis == hir::Public || item.span == DUMMY_SP {
+            return;
+        }
+        if let hir::ItemUse(ref path, _) = item.node {
+            self.check_import(item.id, path.span);
+        }
+    }
+
+    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
+    }
+
+    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
+    }
+}
+
 struct CheckVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     used_trait_imports: DefIdSet,
@@ -45,70 +80,138 @@ impl<'a, 'tcx> CheckVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CheckVisitor<'a, 'tcx> {
-    fn visit_item(&mut self, item: &hir::Item) {
-        if item.vis == hir::Public || item.span == DUMMY_SP {
-            return;
+fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) {
+    let lint = lint::builtin::UNUSED_EXTERN_CRATES;
+
+    // Collect first the crates that are completely unused.  These we
+    // can always suggest removing (no matter which edition we are
+    // in).
+    let unused_extern_crates: FxHashMap<DefId, Span> =
+        tcx.maybe_unused_extern_crates(LOCAL_CRATE)
+        .iter()
+        .filter(|&&(def_id, _)| {
+            // The `def_id` here actually was calculated during resolution (at least
+            // at the time of this writing) and is being shipped to us via a side
+            // channel of the tcx. There may have been extra expansion phases,
+            // however, which ended up removing the `def_id` *after* expansion such
+            // as the `ReplaceBodyWithLoop` pass (which is a bit of a hack, but hey)
+            //
+            // As a result we need to verify that `def_id` is indeed still valid for
+            // our AST and actually present in the HIR map. If it's not there then
+            // there's safely nothing to warn about, and otherwise we carry on with
+            // our execution.
+            //
+            // Note that if we carry through to the `extern_mod_stmt_cnum` query
+            // below it'll cause a panic because `def_id` is actually bogus at this
+            // point in time otherwise.
+            if let Some(id) = tcx.hir.as_local_node_id(def_id) {
+                if tcx.hir.find(id).is_none() {
+                    return false;
+                }
+            }
+            true
+        })
+        .filter(|&&(def_id, _)| {
+            let cnum = tcx.extern_mod_stmt_cnum(def_id).unwrap();
+            !tcx.is_compiler_builtins(cnum)
+                && !tcx.is_panic_runtime(cnum)
+                && !tcx.has_global_allocator(cnum)
+        })
+        .cloned()
+        .collect();
+
+    // Collect all the extern crates (in a reliable order).
+    let mut crates_to_lint = vec![];
+    tcx.hir.krate().visit_all_item_likes(&mut CollectExternCrateVisitor {
+        tcx,
+        crates_to_lint: &mut crates_to_lint,
+    });
+
+    for extern_crate in &crates_to_lint {
+        assert!(extern_crate.def_id.is_local());
+
+        // If the crate is fully unused, we suggest removing it altogether.
+        // We do this in any edition.
+        if let Some(&span) = unused_extern_crates.get(&extern_crate.def_id) {
+            assert_eq!(extern_crate.def_id.krate, LOCAL_CRATE);
+            let hir_id = tcx.hir.definitions().def_index_to_hir_id(extern_crate.def_id.index);
+            let id = tcx.hir.hir_to_node_id(hir_id);
+            let msg = "unused extern crate";
+            tcx.struct_span_lint_node(lint, id, span, msg)
+                .span_suggestion_short(span, "remove it", "".to_string())
+                .emit();
+            continue;
         }
-        if let hir::ItemUse(ref path, _) = item.node {
-            self.check_import(item.id, path.span);
+
+        // If we are not in Rust 2018 edition, then we don't make any further
+        // suggestions.
+        if !tcx.sess.rust_2018() {
+            continue;
         }
-    }
 
-    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
-    }
+        // If the extern crate has any attributes, they may have funky
+        // semantics we can't faithfully represent using `use` (most
+        // notably `#[macro_use]`). Ignore it.
+        if !tcx.get_attrs(extern_crate.def_id).is_empty() {
+            continue;
+        }
 
-    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
+        // Otherwise, we can convert it into a `use` of some kind.
+        let hir_id = tcx.hir.definitions().def_index_to_hir_id(extern_crate.def_id.index);
+        let id = tcx.hir.hir_to_node_id(hir_id);
+        let item = tcx.hir.expect_item(id);
+        let msg = "`extern crate` is not idiomatic in the new edition";
+        let help = format!(
+            "convert it to a `{}`",
+            visibility_qualified(&item.vis, "use")
+        );
+        let base_replacement = match extern_crate.orig_name {
+            Some(orig_name) => format!("use {} as {};", orig_name, item.name),
+            None => format!("use {};", item.name),
+        };
+        let replacement = visibility_qualified(&item.vis, &base_replacement);
+        tcx.struct_span_lint_node(lint, id, extern_crate.span, msg)
+            .span_suggestion_short(extern_crate.span, &help, replacement)
+            .emit();
     }
 }
 
-pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    let mut used_trait_imports = DefIdSet();
-    for &body_id in tcx.hir.krate().bodies.keys() {
-        let item_def_id = tcx.hir.body_owner_def_id(body_id);
-        let imports = tcx.used_trait_imports(item_def_id);
-        debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);
-        used_trait_imports.extend(imports.iter());
-    }
+struct CollectExternCrateVisitor<'a, 'tcx: 'a> {
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    crates_to_lint: &'a mut Vec<ExternCrateToLint>,
+}
 
-    let mut visitor = CheckVisitor { tcx, used_trait_imports };
-    tcx.hir.krate().visit_all_item_likes(&mut visitor);
+struct ExternCrateToLint {
+    /// def-id of the extern crate
+    def_id: DefId,
 
-    for &(def_id, span) in tcx.maybe_unused_extern_crates(LOCAL_CRATE).iter() {
-        // The `def_id` here actually was calculated during resolution (at least
-        // at the time of this writing) and is being shipped to us via a side
-        // channel of the tcx. There may have been extra expansion phases,
-        // however, which ended up removing the `def_id` *after* expansion such
-        // as the `ReplaceBodyWithLoop` pass (which is a bit of a hack, but hey)
-        //
-        // As a result we need to verify that `def_id` is indeed still valid for
-        // our AST and actually present in the HIR map. If it's not there then
-        // there's safely nothing to warn about, and otherwise we carry on with
-        // our execution.
-        //
-        // Note that if we carry through to the `extern_mod_stmt_cnum` query
-        // below it'll cause a panic because `def_id` is actually bogus at this
-        // point in time otherwise.
-        if let Some(id) = tcx.hir.as_local_node_id(def_id) {
-            if tcx.hir.find(id).is_none() {
-                continue
-            }
-        }
-        let cnum = tcx.extern_mod_stmt_cnum(def_id).unwrap();
-        if tcx.is_compiler_builtins(cnum) {
-            continue
-        }
-        if tcx.is_panic_runtime(cnum) {
-            continue
-        }
-        if tcx.has_global_allocator(cnum) {
-            continue
+    /// span from the item
+    span: Span,
+
+    /// if `Some`, then this is renamed (`extern crate orig_name as
+    /// crate_name`), and -- perhaps surprisingly -- this stores the
+    /// *original* name (`item.name` will contain the new name)
+    orig_name: Option<ast::Name>,
+}
+
+impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CollectExternCrateVisitor<'a, 'tcx> {
+    fn visit_item(&mut self, item: &hir::Item) {
+        if let hir::ItemExternCrate(orig_name) = item.node {
+            let extern_crate_def_id = self.tcx.hir.local_def_id(item.id);
+            self.crates_to_lint.push(
+                ExternCrateToLint {
+                    def_id: extern_crate_def_id,
+                    span: item.span,
+                    orig_name,
+                }
+            );
         }
-        assert_eq!(def_id.krate, LOCAL_CRATE);
-        let hir_id = tcx.hir.definitions().def_index_to_hir_id(def_id.index);
-        let id = tcx.hir.hir_to_node_id(hir_id);
-        let lint = lint::builtin::UNUSED_EXTERN_CRATES;
-        let msg = "unused extern crate";
-        tcx.lint_node(lint, id, span, msg);
+    }
+
+    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
+    }
+
+    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
     }
 }
+
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 2e3ea3de7b0..1c1ba208678 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -57,6 +57,7 @@ use std::rc::Rc;
 use std::cell::RefCell;
 use std::sync::Arc;
 use std::u32;
+use std::ops::Range;
 
 use core::{self, DocContext};
 use doctree;
@@ -954,12 +955,20 @@ fn type_ns_kind(def: Def, path_str: &str) -> (&'static str, &'static str, String
     (kind, article, format!("{}@{}", kind, path_str))
 }
 
+fn span_of_attrs(attrs: &Attributes) -> syntax_pos::Span {
+    if attrs.doc_strings.is_empty() {
+        return DUMMY_SP;
+    }
+    let start = attrs.doc_strings[0].span();
+    let end = attrs.doc_strings.last().unwrap().span();
+    start.to(end)
+}
+
 fn ambiguity_error(cx: &DocContext, attrs: &Attributes,
                    path_str: &str,
                    article1: &str, kind1: &str, disambig1: &str,
                    article2: &str, kind2: &str, disambig2: &str) {
-    let sp = attrs.doc_strings.first()
-                  .map_or(DUMMY_SP, |a| a.span());
+    let sp = span_of_attrs(attrs);
     cx.sess()
       .struct_span_warn(sp,
                         &format!("`{}` is both {} {} and {} {}",
@@ -1174,8 +1183,39 @@ enum PathKind {
     Type,
 }
 
-fn resolution_failure(cx: &DocContext, path_str: &str) {
-    cx.sess().warn(&format!("[{}] cannot be resolved, ignoring it...", path_str));
+fn resolution_failure(
+    cx: &DocContext,
+    attrs: &Attributes,
+    path_str: &str,
+    dox: &str,
+    link_range: Option<Range<usize>>,
+) {
+    let sp = span_of_attrs(attrs);
+    let mut diag = cx.sess()
+        .struct_span_warn(sp, &format!("[{}] cannot be resolved, ignoring it...", path_str));
+
+    if let Some(link_range) = link_range {
+        // blah blah blah\nblah\nblah [blah] blah blah\nblah blah
+        //                       ^    ~~~~~~
+        //                       |    link_range
+        //                       last_new_line_offset
+
+        let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1);
+        let line = dox[last_new_line_offset..].lines().next().unwrap_or("");
+
+        // Print the line containing the `link_range` and manually mark it with '^'s
+        diag.note(&format!(
+            "the link appears in this line:\n\n{line}\n{indicator: <before$}{indicator:^<found$}",
+            line=line,
+            indicator="",
+            before=link_range.start - last_new_line_offset,
+            found=link_range.len(),
+        ));
+    } else {
+
+    }
+
+    diag.emit();
 }
 
 impl Clean<Attributes> for [ast::Attribute] {
@@ -1184,7 +1224,7 @@ impl Clean<Attributes> for [ast::Attribute] {
 
         if UnstableFeatures::from_environment().is_nightly_build() {
             let dox = attrs.collapsed_doc_value().unwrap_or_else(String::new);
-            for ori_link in markdown_links(&dox) {
+            for (ori_link, link_range) in markdown_links(&dox) {
                 // bail early for real links
                 if ori_link.contains('/') {
                     continue;
@@ -1228,7 +1268,7 @@ impl Clean<Attributes> for [ast::Attribute] {
                             if let Ok(def) = resolve(cx, path_str, true) {
                                 def
                             } else {
-                                resolution_failure(cx, path_str);
+                                resolution_failure(cx, &attrs, path_str, &dox, link_range);
                                 // this could just be a normal link or a broken link
                                 // we could potentially check if something is
                                 // "intra-doc-link-like" and warn in that case
@@ -1239,7 +1279,7 @@ impl Clean<Attributes> for [ast::Attribute] {
                             if let Ok(def) = resolve(cx, path_str, false) {
                                 def
                             } else {
-                                resolution_failure(cx, path_str);
+                                resolution_failure(cx, &attrs, path_str, &dox, link_range);
                                 // this could just be a normal link
                                 continue;
                             }
@@ -1284,7 +1324,7 @@ impl Clean<Attributes> for [ast::Attribute] {
                             } else if let Ok(value_def) = resolve(cx, path_str, true) {
                                 value_def
                             } else {
-                                resolution_failure(cx, path_str);
+                                resolution_failure(cx, &attrs, path_str, &dox, link_range);
                                 // this could just be a normal link
                                 continue;
                             }
@@ -1293,7 +1333,7 @@ impl Clean<Attributes> for [ast::Attribute] {
                             if let Some(def) = macro_resolve(cx, path_str) {
                                 (def, None)
                             } else {
-                                resolution_failure(cx, path_str);
+                                resolution_failure(cx, &attrs, path_str, &dox, link_range);
                                 continue
                             }
                         }
@@ -3030,7 +3070,7 @@ impl Clean<Option<Visibility>> for hir::Visibility {
         Some(match *self {
             hir::Visibility::Public => Visibility::Public,
             hir::Visibility::Inherited => Visibility::Inherited,
-            hir::Visibility::Crate => Visibility::Crate,
+            hir::Visibility::Crate(_) => Visibility::Crate,
             hir::Visibility::Restricted { ref path, .. } => {
                 let path = path.clean(cx);
                 let did = register_def(cx, path.def);
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index c09bd4cc84a..7088104cd7a 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -32,6 +32,8 @@ use std::cell::RefCell;
 use std::collections::{HashMap, VecDeque};
 use std::default::Default;
 use std::fmt::{self, Write};
+use std::borrow::Cow;
+use std::ops::Range;
 use std::str;
 use syntax::feature_gate::UnstableFeatures;
 use syntax::codemap::Span;
@@ -747,7 +749,7 @@ pub fn plain_summary_line(md: &str) -> String {
     s
 }
 
-pub fn markdown_links(md: &str) -> Vec<String> {
+pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
     if md.is_empty() {
         return vec![];
     }
@@ -760,8 +762,22 @@ pub fn markdown_links(md: &str) -> Vec<String> {
     let shortcut_links = RefCell::new(vec![]);
 
     {
+        let locate = |s: &str| unsafe {
+            let s_start = s.as_ptr();
+            let s_end = s_start.add(s.len());
+            let md_start = md.as_ptr();
+            let md_end = md_start.add(md.len());
+            if md_start <= s_start && s_end <= md_end {
+                let start = s_start.offset_from(md_start) as usize;
+                let end = s_end.offset_from(md_start) as usize;
+                Some(start..end)
+            } else {
+                None
+            }
+        };
+
         let push = |_: &str, s: &str| {
-            shortcut_links.borrow_mut().push(s.to_owned());
+            shortcut_links.borrow_mut().push((s.to_owned(), locate(s)));
             None
         };
         let p = Parser::new_with_broken_link_callback(md, opts,
@@ -772,7 +788,10 @@ pub fn markdown_links(md: &str) -> Vec<String> {
         for ev in iter {
             if let Event::Start(Tag::Link(dest, _)) = ev {
                 debug!("found link: {}", dest);
-                links.push(dest.into_owned());
+                links.push(match dest {
+                    Cow::Borrowed(s) => (s.to_owned(), locate(s)),
+                    Cow::Owned(s) => (s, None),
+                });
             }
         }
     }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 109765b6711..5377cd9a391 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -3055,6 +3055,7 @@ fn render_assoc_item(w: &mut fmt::Formatter,
         } else {
             (0, true)
         };
+        render_attributes(w, meth)?;
         write!(w, "{}{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
                    {generics}{decl}{where_clause}",
                VisSpace(&meth.visibility),
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index bb9a7e47232..0c937759120 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -2041,16 +2041,16 @@
 
     autoCollapseAllImpls(getPageId());
 
-    function createToggleWrapper() {
+    function createToggleWrapper(tog) {
         var span = document.createElement('span');
         span.className = 'toggle-label';
         span.style.display = 'none';
         span.innerHTML = '&nbsp;Expand&nbsp;attributes';
-        toggle.appendChild(span);
+        tog.appendChild(span);
 
         var wrapper = document.createElement('div');
         wrapper.className = 'toggle-wrapper toggle-attributes';
-        wrapper.appendChild(toggle);
+        wrapper.appendChild(tog);
         return wrapper;
     }
 
@@ -2078,13 +2078,11 @@
         });
     }
 
-    onEach(document.getElementById('main').getElementsByTagName('pre'), function(e) {
-        onEach(e.getElementsByClassName('attributes'), function(i_e) {
-            i_e.parentNode.insertBefore(createToggleWrapper(), i_e);
-            if (getCurrentValue("rustdoc-item-attributes") !== "false") {
-                collapseDocs(i_e.previousSibling.childNodes[0], "toggle");
-            }
-        });
+    onEach(document.getElementById('main').getElementsByClassName('attributes'), function(i_e) {
+        i_e.parentNode.insertBefore(createToggleWrapper(toggle.cloneNode(true)), i_e);
+        if (getCurrentValue("rustdoc-item-attributes") !== "false") {
+            collapseDocs(i_e.previousSibling.childNodes[0], "toggle");
+        }
     });
 
     onEach(document.getElementsByClassName('rust-example-rendered'), function(e) {
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 83abf35c854..773b8174e56 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -561,7 +561,8 @@ a {
 	content: '\2002\00a7\2002';
 }
 
-.docblock a:not(.srclink):hover, .docblock-short a:not(.srclink):hover, .stability a {
+.docblock a:not(.srclink):not(.test-arrow):hover,
+.docblock-short a:not(.srclink):not(.test-arrow):hover, .stability a {
 	text-decoration: underline;
 }
 
@@ -771,7 +772,7 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
 
 .toggle-wrapper {
 	position: relative;
-	margin-top: 5px;
+	margin-top: 0;
 }
 
 .toggle-wrapper.collapsed {
@@ -854,10 +855,19 @@ span.since {
 
 .attributes {
 	display: block;
-	margin: 0px 0px 0px 30px !important;
+	margin-top: 0px !important;
+	margin-right: 0px;
+	margin-bottom: 0px !important;
+	margin-left: 30px;
 }
 .toggle-attributes.collapsed {
-	margin-bottom: 5px;
+	margin-bottom: 0;
+}
+.impl-items > .toggle-attributes {
+	margin-left: 20px;
+}
+.impl-items .attributes {
+	font-weight: 500;
 }
 
 :target > code {
diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css
index 765ef0cd415..f96dcd9ec1c 100644
--- a/src/librustdoc/html/static/themes/dark.css
+++ b/src/librustdoc/html/static/themes/dark.css
@@ -163,7 +163,8 @@ a {
 	color: #ddd;
 }
 
-.docblock a:not(.srclink), .docblock-short a:not(.srclink), .stability a {
+.docblock a:not(.srclink):not(.test-arrow), .docblock-short a:not(.srclink):not(.test-arrow),
+.stability a {
 	color: #D2991D;
 }
 
diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css
index 5971dc43ded..54cf50cfffd 100644
--- a/src/librustdoc/html/static/themes/light.css
+++ b/src/librustdoc/html/static/themes/light.css
@@ -163,7 +163,8 @@ a {
 	color: #000;
 }
 
-.docblock a:not(.srclink), .docblock-short a:not(.srclink), .stability a {
+.docblock a:not(.srclink):not(.test-arrow), .docblock-short a:not(.srclink):not(.test-arrow),
+.stability a {
 	color: #3873AD;
 }
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 1b713a446a0..97c84d8348f 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -23,6 +23,7 @@
 #![feature(test)]
 #![feature(vec_remove_item)]
 #![feature(entry_and_modify)]
+#![feature(ptr_offset_from)]
 
 #![recursion_limit="256"]
 
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 15a8b58d0f6..4c773fc1dd7 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -68,7 +68,8 @@ impl<'a, 'tcx, 'rcx> LibEmbargoVisitor<'a, 'tcx, 'rcx> {
         }
 
         for item in self.cx.tcx.item_children(def_id).iter() {
-            if !item.is_import || item.vis == Visibility::Public {
+            if self.cx.tcx.def_key(item.def.def_id()).parent.map_or(false, |d| d == def_id.index) ||
+                item.vis == Visibility::Public {
                 self.visit_item(item.def);
             }
         }
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 935ea4b62b5..5cbd8891364 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -2250,6 +2250,11 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
 
     /// Gets a mutable reference to the value in the entry.
     ///
+    /// If you need a reference to the `OccupiedEntry` which may outlive the
+    /// destruction of the `Entry` value, see [`into_mut`].
+    ///
+    /// [`into_mut`]: #method.into_mut
+    ///
     /// # Examples
     ///
     /// ```
@@ -2261,10 +2266,14 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
     ///
     /// assert_eq!(map["poneyland"], 12);
     /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
-    ///      *o.get_mut() += 10;
+    ///     *o.get_mut() += 10;
+    ///     assert_eq!(*o.get(), 22);
+    ///
+    ///     // We can use the same Entry multiple times.
+    ///     *o.get_mut() += 2;
     /// }
     ///
-    /// assert_eq!(map["poneyland"], 22);
+    /// assert_eq!(map["poneyland"], 24);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut V {
@@ -2274,6 +2283,10 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
     /// Converts the OccupiedEntry into a mutable reference to the value in the entry
     /// with a lifetime bound to the map itself.
     ///
+    /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
+    ///
+    /// [`get_mut`]: #method.get_mut
+    ///
     /// # Examples
     ///
     /// ```
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index f7d06852f27..c576245edb7 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -317,6 +317,8 @@
 #![cfg_attr(windows, feature(used))]
 #![feature(doc_alias)]
 #![feature(float_internals)]
+#![feature(panic_info_message)]
+#![cfg_attr(not(stage0), feature(panic_implementation))]
 
 #![default_lib_allocator]
 
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 403056240bf..0808efa2ece 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -319,8 +319,8 @@ pub fn panicking() -> bool {
 
 /// Entry point of panic from the libcore crate.
 #[cfg(not(test))]
+#[cfg(stage0)]
 #[lang = "panic_fmt"]
-#[unwind(allowed)]
 pub extern fn rust_begin_panic(msg: fmt::Arguments,
                                file: &'static str,
                                line: u32,
@@ -328,59 +328,107 @@ pub extern fn rust_begin_panic(msg: fmt::Arguments,
     begin_panic_fmt(&msg, &(file, line, col))
 }
 
+/// Entry point of panic from the libcore crate.
+#[cfg(not(test))]
+#[cfg(not(stage0))]
+#[panic_implementation]
+#[unwind(allowed)]
+pub fn rust_begin_panic(info: &PanicInfo) -> ! {
+    continue_panic_fmt(&info)
+}
+
 /// The entry point for panicking with a formatted message.
 ///
 /// This is designed to reduce the amount of code required at the call
 /// site as much as possible (so that `panic!()` has as low an impact
 /// on (e.g.) the inlining of other functions as possible), by moving
 /// the actual formatting into this shared place.
+#[cfg(stage0)]
 #[unstable(feature = "libstd_sys_internals",
            reason = "used by the panic! macro",
            issue = "0")]
 #[inline(never)] #[cold]
 pub fn begin_panic_fmt(msg: &fmt::Arguments,
                        file_line_col: &(&'static str, u32, u32)) -> ! {
-    use fmt::Write;
-
     // We do two allocations here, unfortunately. But (a) they're
     // required with the current scheme, and (b) we don't handle
     // panic + OOM properly anyway (see comment in begin_panic
     // below).
 
     rust_panic_with_hook(&mut PanicPayload::new(msg), Some(msg), file_line_col);
+}
+
+// NOTE(stage0) move into `continue_panic_fmt` on next stage0 update
+struct PanicPayload<'a> {
+    inner: &'a fmt::Arguments<'a>,
+    string: Option<String>,
+}
 
-    struct PanicPayload<'a> {
-        inner: &'a fmt::Arguments<'a>,
-        string: Option<String>,
+impl<'a> PanicPayload<'a> {
+    fn new(inner: &'a fmt::Arguments<'a>) -> PanicPayload<'a> {
+        PanicPayload { inner, string: None }
     }
 
-    impl<'a> PanicPayload<'a> {
-        fn new(inner: &'a fmt::Arguments<'a>) -> PanicPayload<'a> {
-            PanicPayload { inner, string: None }
-        }
+    fn fill(&mut self) -> &mut String {
+        use fmt::Write;
 
-        fn fill(&mut self) -> &mut String {
-            let inner = self.inner;
-            self.string.get_or_insert_with(|| {
-                let mut s = String::new();
-                drop(s.write_fmt(*inner));
-                s
-            })
-        }
+        let inner = self.inner;
+        self.string.get_or_insert_with(|| {
+            let mut s = String::new();
+            drop(s.write_fmt(*inner));
+            s
+        })
     }
+}
 
-    unsafe impl<'a> BoxMeUp for PanicPayload<'a> {
-        fn box_me_up(&mut self) -> *mut (Any + Send) {
-            let contents = mem::replace(self.fill(), String::new());
-            Box::into_raw(Box::new(contents))
-        }
+unsafe impl<'a> BoxMeUp for PanicPayload<'a> {
+    fn box_me_up(&mut self) -> *mut (Any + Send) {
+        let contents = mem::replace(self.fill(), String::new());
+        Box::into_raw(Box::new(contents))
+    }
 
-        fn get(&mut self) -> &(Any + Send) {
-            self.fill()
-        }
+    fn get(&mut self) -> &(Any + Send) {
+        self.fill()
     }
 }
 
+/// The entry point for panicking with a formatted message.
+///
+/// This is designed to reduce the amount of code required at the call
+/// site as much as possible (so that `panic!()` has as low an impact
+/// on (e.g.) the inlining of other functions as possible), by moving
+/// the actual formatting into this shared place.
+#[cfg(not(stage0))]
+#[unstable(feature = "libstd_sys_internals",
+           reason = "used by the panic! macro",
+           issue = "0")]
+#[inline(never)] #[cold]
+pub fn begin_panic_fmt(msg: &fmt::Arguments,
+                       file_line_col: &(&'static str, u32, u32)) -> ! {
+    let (file, line, col) = *file_line_col;
+    let info = PanicInfo::internal_constructor(
+        Some(msg),
+        Location::internal_constructor(file, line, col),
+    );
+    continue_panic_fmt(&info)
+}
+
+#[cfg(not(stage0))]
+fn continue_panic_fmt(info: &PanicInfo) -> ! {
+    // We do two allocations here, unfortunately. But (a) they're
+    // required with the current scheme, and (b) we don't handle
+    // panic + OOM properly anyway (see comment in begin_panic
+    // below).
+
+    let loc = info.location().unwrap(); // The current implementation always returns Some
+    let msg = info.message().unwrap(); // The current implementation always returns Some
+    let file_line_col = (loc.file(), loc.line(), loc.column());
+    rust_panic_with_hook(
+        &mut PanicPayload::new(msg),
+        info.message(),
+        &file_line_col);
+}
+
 /// This is the entry point of panicking for panic!() and assert!().
 #[unstable(feature = "libstd_sys_internals",
            reason = "used by the panic! macro",
@@ -431,7 +479,7 @@ pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&'static str, u32, u3
 /// abort or unwind.
 fn rust_panic_with_hook(payload: &mut BoxMeUp,
                         message: Option<&fmt::Arguments>,
-                        file_line_col: &(&'static str, u32, u32)) -> ! {
+                        file_line_col: &(&str, u32, u32)) -> ! {
     let (file, line, col) = *file_line_col;
 
     let panics = update_panic_count(1);
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 9adfb61d92d..17118e4dff2 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -473,6 +473,8 @@ declare_features! (
     // 'a: { break 'a; }
     (active, label_break_value, "1.28.0", Some(48594), None),
 
+    // #[panic_implementation]
+    (active, panic_implementation, "1.28.0", Some(44489), None),
 );
 
 declare_features! (
@@ -1069,6 +1071,12 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
                                  "attribute is currently unstable",
                                  cfg_fn!(wasm_custom_section))),
 
+    // RFC 2070
+    ("panic_implementation", Normal, Gated(Stability::Unstable,
+                           "panic_implementation",
+                           "#[panic_implementation] is an unstable feature",
+                           cfg_fn!(panic_implementation))),
+
     // Crate level attributes
     ("crate_name", CrateLevel, Ungated),
     ("crate_type", CrateLevel, Ungated),
diff --git a/src/test/compile-fail/auxiliary/some-panic-impl.rs b/src/test/compile-fail/auxiliary/some-panic-impl.rs
new file mode 100644
index 00000000000..db16ac325ac
--- /dev/null
+++ b/src/test/compile-fail/auxiliary/some-panic-impl.rs
@@ -0,0 +1,22 @@
+// 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.
+
+// no-prefer-dynamic
+
+#![crate_type = "rlib"]
+#![feature(panic_implementation)]
+#![no_std]
+
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
diff --git a/src/test/compile-fail/duplicate_entry_error.rs b/src/test/compile-fail/duplicate_entry_error.rs
index 485519e8c3d..176aa7cca53 100644
--- a/src/test/compile-fail/duplicate_entry_error.rs
+++ b/src/test/compile-fail/duplicate_entry_error.rs
@@ -14,9 +14,11 @@
 
 #![feature(lang_items)]
 
-#[lang = "panic_fmt"]
-fn panic_fmt() -> ! {
-//~^ ERROR: duplicate lang item found: `panic_fmt`.
+use std::panic::PanicInfo;
+
+#[lang = "panic_impl"]
+fn panic_impl(info: &PanicInfo) -> ! {
+//~^ ERROR: duplicate lang item found: `panic_impl`.
     loop {}
 }
 
diff --git a/src/test/compile-fail/edition-extern-crate-allowed.rs b/src/test/compile-fail/edition-extern-crate-allowed.rs
index 286ee896161..7368564e250 100644
--- a/src/test/compile-fail/edition-extern-crate-allowed.rs
+++ b/src/test/compile-fail/edition-extern-crate-allowed.rs
@@ -12,8 +12,9 @@
 // compile-flags: --edition 2015
 // compile-pass
 
-#![deny(rust_2018_idioms)]
+#![warn(rust_2018_idioms)]
 
 extern crate edition_extern_crate_allowed;
+//~^ WARNING unused extern crate
 
 fn main() {}
diff --git a/src/test/compile-fail/feature-gate-panic-implementation.rs b/src/test/compile-fail/feature-gate-panic-implementation.rs
new file mode 100644
index 00000000000..ae9fbc7b13b
--- /dev/null
+++ b/src/test/compile-fail/feature-gate-panic-implementation.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.
+
+// compile-flags:-C panic=abort
+
+#![no_std]
+#![no_main]
+
+use core::panic::PanicInfo;
+
+#[panic_implementation] //~ ERROR #[panic_implementation] is an unstable feature (see issue #44489)
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
diff --git a/src/test/compile-fail/no_owned_box_lang_item.rs b/src/test/compile-fail/no_owned_box_lang_item.rs
index 72eb687adc6..1c2bf1573dc 100644
--- a/src/test/compile-fail/no_owned_box_lang_item.rs
+++ b/src/test/compile-fail/no_owned_box_lang_item.rs
@@ -21,4 +21,4 @@ fn main() {
 
 #[lang = "eh_personality"] extern fn eh_personality() {}
 #[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {}
-#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
+#[lang = "panic_impl"] fn panic_impl() -> ! { loop {} }
diff --git a/src/test/compile-fail/panic-implementation-bad-signature-1.rs b/src/test/compile-fail/panic-implementation-bad-signature-1.rs
new file mode 100644
index 00000000000..fec11fdbd7b
--- /dev/null
+++ b/src/test/compile-fail/panic-implementation-bad-signature-1.rs
@@ -0,0 +1,24 @@
+// 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.
+
+// compile-flags:-C panic=abort
+
+#![feature(panic_implementation)]
+#![no_std]
+#![no_main]
+
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic(
+    info: PanicInfo, //~ ERROR argument should be `&PanicInfo`
+) -> () //~ ERROR return type should be `!`
+{
+}
diff --git a/src/test/compile-fail/panic-implementation-bad-signature-2.rs b/src/test/compile-fail/panic-implementation-bad-signature-2.rs
new file mode 100644
index 00000000000..2a628c05699
--- /dev/null
+++ b/src/test/compile-fail/panic-implementation-bad-signature-2.rs
@@ -0,0 +1,25 @@
+// 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.
+
+// compile-flags:-C panic=abort
+
+#![feature(panic_implementation)]
+#![no_std]
+#![no_main]
+
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic(
+    info: &'static PanicInfo, //~ ERROR argument should be `&PanicInfo`
+) -> !
+{
+    loop {}
+}
diff --git a/src/test/compile-fail/panic-implementation-bad-signature-3.rs b/src/test/compile-fail/panic-implementation-bad-signature-3.rs
new file mode 100644
index 00000000000..29337025b70
--- /dev/null
+++ b/src/test/compile-fail/panic-implementation-bad-signature-3.rs
@@ -0,0 +1,22 @@
+// 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.
+
+// compile-flags:-C panic=abort
+
+#![feature(panic_implementation)]
+#![no_std]
+#![no_main]
+
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic() -> ! { //~ ERROR function should have one argument
+    loop {}
+}
diff --git a/src/test/compile-fail/panic-implementation-bad-signature-4.rs b/src/test/compile-fail/panic-implementation-bad-signature-4.rs
new file mode 100644
index 00000000000..d5f942ba2d6
--- /dev/null
+++ b/src/test/compile-fail/panic-implementation-bad-signature-4.rs
@@ -0,0 +1,23 @@
+// 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.
+
+// compile-flags:-C panic=abort
+
+#![feature(panic_implementation)]
+#![no_std]
+#![no_main]
+
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic<T>(pi: &PanicInfo) -> ! {
+    //~^ ERROR `#[panic_implementation]` function should have no type parameters
+    loop {}
+}
diff --git a/src/test/compile-fail/panic-implementation-duplicate.rs b/src/test/compile-fail/panic-implementation-duplicate.rs
new file mode 100644
index 00000000000..017113af409
--- /dev/null
+++ b/src/test/compile-fail/panic-implementation-duplicate.rs
@@ -0,0 +1,28 @@
+// 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.
+
+// compile-flags:-C panic=abort
+
+#![feature(lang_items)]
+#![feature(panic_implementation)]
+#![no_std]
+#![no_main]
+
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+#[lang = "panic_impl"]
+fn panic2(info: &PanicInfo) -> ! { //~ ERROR duplicate lang item found: `panic_impl`.
+    loop {}
+}
diff --git a/src/test/compile-fail/panic-implementation-requires-panic-info.rs b/src/test/compile-fail/panic-implementation-requires-panic-info.rs
new file mode 100644
index 00000000000..597f44d9832
--- /dev/null
+++ b/src/test/compile-fail/panic-implementation-requires-panic-info.rs
@@ -0,0 +1,26 @@
+// 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.
+
+// compile-flags:-C panic=abort
+// error-pattern: language item required, but not found: `panic_info`
+
+#![feature(lang_items)]
+#![feature(no_core)]
+#![feature(panic_implementation)]
+#![no_core]
+#![no_main]
+
+#[panic_implementation]
+fn panic() -> ! {
+    loop {}
+}
+
+#[lang = "sized"]
+trait Sized {}
diff --git a/src/test/compile-fail/panic-implementation-std.rs b/src/test/compile-fail/panic-implementation-std.rs
new file mode 100644
index 00000000000..f25cd3605c1
--- /dev/null
+++ b/src/test/compile-fail/panic-implementation-std.rs
@@ -0,0 +1,22 @@
+// 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.
+
+// error-pattern: duplicate lang item found: `panic_impl`.
+
+#![feature(panic_implementation)]
+
+use std::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic(info: PanicInfo) -> ! {
+    loop {}
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/panic-implementation-twice.rs b/src/test/compile-fail/panic-implementation-twice.rs
new file mode 100644
index 00000000000..78dc545c036
--- /dev/null
+++ b/src/test/compile-fail/panic-implementation-twice.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.
+
+// aux-build:some-panic-impl.rs
+
+#![feature(panic_implementation)]
+#![feature(lang_items)]
+#![no_std]
+#![no_main]
+
+extern crate some_panic_impl;
+
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic(info: &PanicInfo) -> ! {
+    //~^ error duplicate lang item found: `panic_impl`
+    loop {}
+}
+
+#[lang = "eh_personality"]
+fn eh() {}
diff --git a/src/test/compile-fail/panic-runtime/auxiliary/panic-runtime-lang-items.rs b/src/test/compile-fail/panic-runtime/auxiliary/panic-runtime-lang-items.rs
index fbf70b3d3fe..d9848a554ab 100644
--- a/src/test/compile-fail/panic-runtime/auxiliary/panic-runtime-lang-items.rs
+++ b/src/test/compile-fail/panic-runtime/auxiliary/panic-runtime-lang-items.rs
@@ -15,8 +15,10 @@
 #![no_std]
 #![feature(lang_items)]
 
-#[lang = "panic_fmt"]
-fn panic_fmt() {}
+use core::panic::PanicInfo;
+
+#[lang = "panic_impl"]
+fn panic_impl(info: &PanicInfo) -> ! { loop {} }
 #[lang = "eh_personality"]
 fn eh_personality() {}
 #[lang = "eh_unwind_resume"]
diff --git a/src/test/compile-fail/weak-lang-item.rs b/src/test/compile-fail/weak-lang-item.rs
index 8579611b938..7b988c3595f 100644
--- a/src/test/compile-fail/weak-lang-item.rs
+++ b/src/test/compile-fail/weak-lang-item.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // aux-build:weak-lang-items.rs
-// error-pattern: language item required, but not found: `panic_fmt`
+// error-pattern: language item required, but not found: `panic_impl`
 // error-pattern: language item required, but not found: `eh_personality`
 // ignore-wasm32-bare compiled with panic=abort, personality not required
 
diff --git a/src/test/run-make-fulldeps/issue-36710/Makefile b/src/test/run-make-fulldeps/issue-36710/Makefile
new file mode 100644
index 00000000000..928bdf532df
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue-36710/Makefile
@@ -0,0 +1,21 @@
+-include ../tools.mk
+
+ifeq (musl,$(findstring musl,$(TARGET)))
+all: skip
+else
+all: test
+endif
+
+test: foo
+	$(call RUN,foo)
+
+skip:
+	echo "expected failure"
+
+foo: foo.rs $(call NATIVE_STATICLIB,foo)
+	$(RUSTC) $< -lfoo $(EXTRACXXFLAGS)
+
+$(TMPDIR)/libfoo.o: foo.cpp
+	$(call COMPILE_OBJ_CXX,$@,$<)
+
+.PHONY: all test skip
diff --git a/src/test/run-make-fulldeps/issue-36710/foo.cpp b/src/test/run-make-fulldeps/issue-36710/foo.cpp
new file mode 100644
index 00000000000..fbd0ead7a50
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue-36710/foo.cpp
@@ -0,0 +1,25 @@
+// 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.
+
+#include <stdint.h>
+
+struct A {
+    A() { v = 1234; }
+    ~A() { v = 1; }
+    uint32_t v;
+};
+
+A a;
+
+extern "C" {
+    uint32_t get() {
+        return a.v;
+    }
+}
diff --git a/src/test/run-make-fulldeps/issue-36710/foo.rs b/src/test/run-make-fulldeps/issue-36710/foo.rs
new file mode 100644
index 00000000000..6e50566ddfd
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue-36710/foo.rs
@@ -0,0 +1,18 @@
+// 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.
+
+// Tests that linking to C++ code with global destructors works.
+
+extern { fn get() -> u32; }
+
+fn main() {
+    let i = unsafe { get() };
+    assert_eq!(i, 1234);
+}
diff --git a/src/test/run-make-fulldeps/panic-impl-transitive/Makefile b/src/test/run-make-fulldeps/panic-impl-transitive/Makefile
new file mode 100644
index 00000000000..1714578b2ba
--- /dev/null
+++ b/src/test/run-make-fulldeps/panic-impl-transitive/Makefile
@@ -0,0 +1,7 @@
+-include ../../run-make-fulldeps/tools.mk
+
+# NOTE we use --emit=llvm-ir to avoid running the linker (linking will fail because there's no main
+# in this crate)
+all:
+	$(RUSTC) panic-impl-provider.rs
+	$(RUSTC) panic-impl-consumer.rs -C panic=abort --emit=llvm-ir -L $(TMPDIR)
diff --git a/src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-consumer.rs b/src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-consumer.rs
new file mode 100644
index 00000000000..592fab8be85
--- /dev/null
+++ b/src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-consumer.rs
@@ -0,0 +1,15 @@
+// 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.
+
+#![no_std]
+#![no_main]
+
+// this crate provides the `panic_impl` lang item so we don't need to define it here
+extern crate panic_impl_provider;
diff --git a/src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-provider.rs b/src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-provider.rs
new file mode 100644
index 00000000000..46cdf2e2fa5
--- /dev/null
+++ b/src/test/run-make-fulldeps/panic-impl-transitive/panic-impl-provider.rs
@@ -0,0 +1,20 @@
+// 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.
+
+#![crate_type = "rlib"]
+#![feature(panic_implementation)]
+#![no_std]
+
+use core::panic::PanicInfo;
+
+#[panic_implementation]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
diff --git a/src/test/run-make-fulldeps/tools.mk b/src/test/run-make-fulldeps/tools.mk
index af1707de6c0..3de358fa500 100644
--- a/src/test/run-make-fulldeps/tools.mk
+++ b/src/test/run-make-fulldeps/tools.mk
@@ -59,12 +59,14 @@ endif
 
 ifdef IS_MSVC
 COMPILE_OBJ = $(CC) -c -Fo:`cygpath -w $(1)` $(2)
+COMPILE_OBJ_CXX = $(CXX) -c -Fo:`cygpath -w $(1)` $(2)
 NATIVE_STATICLIB_FILE = $(1).lib
 NATIVE_STATICLIB = $(TMPDIR)/$(call NATIVE_STATICLIB_FILE,$(1))
 OUT_EXE=-Fe:`cygpath -w $(TMPDIR)/$(call BIN,$(1))` \
 	-Fo:`cygpath -w $(TMPDIR)/$(1).obj`
 else
 COMPILE_OBJ = $(CC) -c -o $(1) $(2)
+COMPILE_OBJ_CXX = $(CXX) -c -o $(1) $(2)
 NATIVE_STATICLIB_FILE = lib$(1).a
 NATIVE_STATICLIB = $(call STATICLIB,$(1))
 OUT_EXE=-o $(TMPDIR)/$(1)
diff --git a/src/test/run-pass/const-endianess.rs b/src/test/run-pass/const-endianess.rs
new file mode 100644
index 00000000000..fa34b49210a
--- /dev/null
+++ b/src/test/run-pass/const-endianess.rs
@@ -0,0 +1,32 @@
+// 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(const_int_ops)]
+#![feature(test)]
+
+extern crate test;
+use test::black_box as b;
+
+const BE_U32: u32 = 55u32.to_be();
+const LE_U32: u32 = 55u32.to_le();
+
+
+fn main() {
+    assert_eq!(BE_U32, b(55u32).to_be());
+    assert_eq!(LE_U32, b(55u32).to_le());
+
+    #[cfg(not(target_arch = "asmjs"))]
+    {
+        const BE_U128: u128 = 999999u128.to_be();
+        const LE_I128: i128 = -999999i128.to_le();
+        assert_eq!(BE_U128, b(999999u128).to_be());
+        assert_eq!(LE_I128, b(-999999i128).to_le());
+    }
+}
diff --git a/src/test/rustdoc-ui/intra-links-warning.rs b/src/test/rustdoc-ui/intra-links-warning.rs
index 2a00d31e3d7..830aaabf9d2 100644
--- a/src/test/rustdoc-ui/intra-links-warning.rs
+++ b/src/test/rustdoc-ui/intra-links-warning.rs
@@ -10,7 +10,9 @@
 
 // compile-pass
 
-//! Test with [Foo::baz], [Bar::foo], [Uniooon::X]
+//! Test with [Foo::baz], [Bar::foo], ...
+//!
+//! and [Uniooon::X].
 
 pub struct Foo {
     pub bar: usize,
diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr
index 67d7bdd02b3..1e8e9f04c26 100644
--- a/src/test/rustdoc-ui/intra-links-warning.stderr
+++ b/src/test/rustdoc-ui/intra-links-warning.stderr
@@ -1,6 +1,39 @@
 warning: [Foo::baz] cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:13:1
+   |
+13 | / //! Test with [Foo::baz], [Bar::foo], ...
+14 | | //!
+15 | | //! and [Uniooon::X].
+   | |_____________________^
+   |
+   = note: the link appears in this line:
+           
+            Test with [Foo::baz], [Bar::foo], ...
+                       ^^^^^^^^
 
 warning: [Bar::foo] cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:13:1
+   |
+13 | / //! Test with [Foo::baz], [Bar::foo], ...
+14 | | //!
+15 | | //! and [Uniooon::X].
+   | |_____________________^
+   |
+   = note: the link appears in this line:
+           
+            Test with [Foo::baz], [Bar::foo], ...
+                                   ^^^^^^^^
 
 warning: [Uniooon::X] cannot be resolved, ignoring it...
+  --> $DIR/intra-links-warning.rs:13:1
+   |
+13 | / //! Test with [Foo::baz], [Bar::foo], ...
+14 | | //!
+15 | | //! and [Uniooon::X].
+   | |_____________________^
+   |
+   = note: the link appears in this line:
+           
+            and [Uniooon::X].
+                 ^^^^^^^^^^
 
diff --git a/src/test/rustdoc/rustc-macro-crate.rs b/src/test/rustdoc/rustc-macro-crate.rs
index dc28732b55e..d46f9684411 100644
--- a/src/test/rustdoc/rustc-macro-crate.rs
+++ b/src/test/rustdoc/rustc-macro-crate.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // no-prefer-dynamic
+// ignore-stage1
 
 #![crate_type = "proc-macro"]
 
diff --git a/src/test/rustdoc/trait-attributes.rs b/src/test/rustdoc/trait-attributes.rs
new file mode 100644
index 00000000000..00d10408b4c
--- /dev/null
+++ b/src/test/rustdoc/trait-attributes.rs
@@ -0,0 +1,32 @@
+// 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.
+
+#![crate_name = "foo"]
+
+// ignore-tidy-linelength
+
+pub trait Foo {
+    // @has foo/trait.Foo.html '//h3[@id="tymethod.foo"]//div[@class="docblock attributes"]' '#[must_use]'
+    #[must_use]
+    fn foo();
+}
+
+#[must_use]
+pub struct Bar;
+
+impl Bar {
+    // @has foo/struct.Bar.html '//h4[@id="method.bar"]//div[@class="docblock attributes"]' '#[must_use]'
+    #[must_use]
+    pub fn bar() {}
+
+    // @has foo/struct.Bar.html '//h4[@id="method.bar2"]//div[@class="docblock attributes"]' '#[must_use]'
+    #[must_use]
+    pub fn bar2() {}
+}
diff --git a/src/test/ui-fulldeps/unnecessary-extern-crate.rs b/src/test/ui-fulldeps/unnecessary-extern-crate.rs
index fc6cb6bd053..0811c79b0a4 100644
--- a/src/test/ui-fulldeps/unnecessary-extern-crate.rs
+++ b/src/test/ui-fulldeps/unnecessary-extern-crate.rs
@@ -10,48 +10,90 @@
 
 // compile-flags: --edition 2018
 
-#![deny(unnecessary_extern_crates)]
+#![deny(unused_extern_crates)]
 #![feature(alloc, test, libc)]
 
 extern crate alloc;
-//~^ ERROR `extern crate` is unnecessary in the new edition
+//~^ ERROR unused extern crate
 //~| HELP remove
 extern crate alloc as x;
-//~^ ERROR `extern crate` is unnecessary in the new edition
-//~| HELP use `use`
+//~^ ERROR unused extern crate
+//~| HELP remove
 
 #[macro_use]
 extern crate test;
+
 pub extern crate test as y;
-//~^ ERROR `extern crate` is unnecessary in the new edition
-//~| HELP use `pub use`
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+//~| HELP convert it to a `pub use`
+
 pub extern crate libc;
-//~^ ERROR `extern crate` is unnecessary in the new edition
-//~| HELP use `pub use`
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+//~| HELP convert it to a `pub use`
+
+pub(crate) extern crate libc as a;
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+//~| HELP convert it to a `pub(crate) use`
 
+crate extern crate libc as b;
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+//~| HELP convert it to a `crate use`
 
 mod foo {
+    pub(in crate::foo) extern crate libc as c;
+    //~^ ERROR `extern crate` is not idiomatic in the new edition
+    //~| HELP convert it to a `pub(in crate::foo) use`
+
+    pub(super) extern crate libc as d;
+    //~^ ERROR `extern crate` is not idiomatic in the new edition
+    //~| HELP convert it to a `pub(super) use`
+
     extern crate alloc;
-    //~^ ERROR `extern crate` is unnecessary in the new edition
-    //~| HELP use `use`
+    //~^ ERROR unused extern crate
+    //~| HELP remove
+
     extern crate alloc as x;
-    //~^ ERROR `extern crate` is unnecessary in the new edition
-    //~| HELP use `use`
+    //~^ ERROR unused extern crate
+    //~| HELP remove
+
     pub extern crate test;
-    //~^ ERROR `extern crate` is unnecessary in the new edition
-    //~| HELP use `pub use`
+    //~^ ERROR `extern crate` is not idiomatic in the new edition
+    //~| HELP convert it
+
     pub extern crate test as y;
-    //~^ ERROR `extern crate` is unnecessary in the new edition
-    //~| HELP use `pub use`
+    //~^ ERROR `extern crate` is not idiomatic in the new edition
+    //~| HELP convert it
+
     mod bar {
         extern crate alloc;
-        //~^ ERROR `extern crate` is unnecessary in the new edition
-        //~| HELP use `use`
+        //~^ ERROR unused extern crate
+        //~| HELP remove
+
         extern crate alloc as x;
-        //~^ ERROR `extern crate` is unnecessary in the new edition
-        //~| HELP use `use`
+        //~^ ERROR unused extern crate
+        //~| HELP remove
+
+        pub(in crate::foo::bar) extern crate libc as e;
+        //~^ ERROR `extern crate` is not idiomatic in the new edition
+        //~| HELP convert it to a `pub(in crate::foo::bar) use`
+
+        fn dummy() {
+            unsafe {
+                e::getpid();
+            }
+        }
+    }
+
+    fn dummy() {
+        unsafe {
+            c::getpid();
+            d::getpid();
+        }
     }
 }
 
 
-fn main() {}
+fn main() {
+    unsafe { a::getpid(); }
+    unsafe { b::getpid(); }
+}
diff --git a/src/test/ui-fulldeps/unnecessary-extern-crate.stderr b/src/test/ui-fulldeps/unnecessary-extern-crate.stderr
index b9ccf5b19e0..a4307112157 100644
--- a/src/test/ui-fulldeps/unnecessary-extern-crate.stderr
+++ b/src/test/ui-fulldeps/unnecessary-extern-crate.stderr
@@ -1,4 +1,4 @@
-error: `extern crate` is unnecessary in the new edition
+error: unused extern crate
   --> $DIR/unnecessary-extern-crate.rs:16:1
    |
 LL | extern crate alloc;
@@ -7,62 +7,92 @@ LL | extern crate alloc;
 note: lint level defined here
   --> $DIR/unnecessary-extern-crate.rs:13:9
    |
-LL | #![deny(unnecessary_extern_crates)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(unused_extern_crates)]
+   |         ^^^^^^^^^^^^^^^^^^^^
 
-error: `extern crate` is unnecessary in the new edition
+error: unused extern crate
   --> $DIR/unnecessary-extern-crate.rs:19:1
    |
 LL | extern crate alloc as x;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc as x;`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:25:1
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:26:1
    |
 LL | pub extern crate test as y;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test as y;`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:28:1
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:30:1
    |
 LL | pub extern crate libc;
-   | ^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use libc;`
+   | ^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:34:5
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:34:1
+   |
+LL | pub(crate) extern crate libc as a;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(crate) use`
+
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:38:1
+   |
+LL | crate extern crate libc as b;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `crate use`
+
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:43:5
+   |
+LL |     pub(in crate::foo) extern crate libc as c;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(in crate::foo) use`
+
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:47:5
+   |
+LL |     pub(super) extern crate libc as d;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(super) use`
+
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:51:5
    |
 LL |     extern crate alloc;
-   |     ^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc;`
+   |     ^^^^^^^^^^^^^^^^^^^ help: remove it
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:37:5
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:55:5
    |
 LL |     extern crate alloc as x;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc as x;`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:40:5
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:59:5
    |
 LL |     pub extern crate test;
-   |     ^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test;`
+   |     ^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:43:5
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:63:5
    |
 LL |     pub extern crate test as y;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `pub use`: `pub use test as y;`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub use`
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:47:9
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:68:9
    |
 LL |         extern crate alloc;
-   |         ^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc;`
+   |         ^^^^^^^^^^^^^^^^^^^ help: remove it
 
-error: `extern crate` is unnecessary in the new edition
-  --> $DIR/unnecessary-extern-crate.rs:50:9
+error: unused extern crate
+  --> $DIR/unnecessary-extern-crate.rs:72:9
    |
 LL |         extern crate alloc as x;
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use alloc as x;`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/unnecessary-extern-crate.rs:76:9
+   |
+LL |         pub(in crate::foo::bar) extern crate libc as e;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `pub(in crate::foo::bar) use`
 
-error: aborting due to 10 previous errors
+error: aborting due to 15 previous errors
 
diff --git a/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.nll.stderr b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.nll.stderr
new file mode 100644
index 00000000000..95acdab3e80
--- /dev/null
+++ b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.nll.stderr
@@ -0,0 +1,63 @@
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:15:21
+   |
+LL |   fn gimme_static_mut_let() -> &'static mut u32 {
+   |  _______________________________________________-
+LL | |     let ref mut x = 1234543; //~ ERROR
+   | |                     ^^^^^^^ temporary value does not live long enough
+LL | |     x
+LL | | }
+   | | -
+   | | |
+   | |_temporary value only lives until here
+   |   borrow later used here
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:20:25
+   |
+LL |   fn gimme_static_mut_let_nested() -> &'static mut u32 {
+   |  ______________________________________________________-
+LL | |     let (ref mut x, ) = (1234543, ); //~ ERROR
+   | |                         ^^^^^^^^^^^ temporary value does not live long enough
+LL | |     x
+LL | | }
+   | | -
+   | | |
+   | |_temporary value only lives until here
+   |   borrow later used here
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:25:11
+   |
+LL |     match 1234543 {
+   |           ^^^^^^^ temporary value does not live long enough
+...
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:31:11
+   |
+LL |     match (123443,) {
+   |           ^^^^^^^^^ temporary value does not live long enough
+...
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:37:10
+   |
+LL |     &mut 1234543 //~ ERROR
+   |          ^^^^^^^ temporary value does not live long enough
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.rs b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.rs
new file mode 100644
index 00000000000..4c5f458d6a3
--- /dev/null
+++ b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.rs
@@ -0,0 +1,41 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that we fail to promote the constant here which has a `ref
+// mut` borrow.
+
+fn gimme_static_mut_let() -> &'static mut u32 {
+    let ref mut x = 1234543; //~ ERROR
+    x
+}
+
+fn gimme_static_mut_let_nested() -> &'static mut u32 {
+    let (ref mut x, ) = (1234543, ); //~ ERROR
+    x
+}
+
+fn gimme_static_mut_match() -> &'static mut u32 {
+    match 1234543 {
+        ref mut x => x //~ ERROR
+    }
+}
+
+fn gimme_static_mut_match_nested() -> &'static mut u32 {
+    match (123443,) {
+        (ref mut x,) => x, //~ ERROR
+    }
+}
+
+fn gimme_static_mut_ampersand() -> &'static mut u32 {
+    &mut 1234543 //~ ERROR
+}
+
+fn main() {
+}
diff --git a/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.stderr b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.stderr
new file mode 100644
index 00000000000..931eb7da744
--- /dev/null
+++ b/src/test/ui/borrowck/promote-ref-mut-in-let-issue-46557.stderr
@@ -0,0 +1,57 @@
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:15:9
+   |
+LL |     let ref mut x = 1234543; //~ ERROR
+   |         ^^^^^^^^^ temporary value does not live long enough
+LL |     x
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:20:10
+   |
+LL |     let (ref mut x, ) = (1234543, ); //~ ERROR
+   |          ^^^^^^^^^ borrowed value does not live long enough
+LL |     x
+LL | }
+   | - borrowed value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:26:9
+   |
+LL |         ref mut x => x //~ ERROR
+   |         ^^^^^^^^^ temporary value does not live long enough
+LL |     }
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:32:10
+   |
+LL |         (ref mut x,) => x, //~ ERROR
+   |          ^^^^^^^^^ borrowed value does not live long enough
+LL |     }
+LL | }
+   | - borrowed value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error[E0597]: borrowed value does not live long enough
+  --> $DIR/promote-ref-mut-in-let-issue-46557.rs:37:10
+   |
+LL |     &mut 1234543 //~ ERROR
+   |          ^^^^^^^ temporary value does not live long enough
+LL | }
+   | - temporary value only lives until here
+   |
+   = note: borrowed value must be valid for the static lifetime...
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/deriving-with-repr-packed.rs b/src/test/ui/deriving-with-repr-packed.rs
index 0c52829799e..43375098cb5 100644
--- a/src/test/ui/deriving-with-repr-packed.rs
+++ b/src/test/ui/deriving-with-repr-packed.rs
@@ -33,7 +33,7 @@ pub struct Bar(u32, u32, u32);
 struct Y(usize);
 
 #[derive(PartialEq)]
-//~^ ERROR #[derive] can't be used on a non-Copy #[repr(packed)]
+//~^ ERROR #[derive] can't be used
 //~| hard error
 #[repr(packed)]
 struct X(Y);
diff --git a/src/test/ui/deriving-with-repr-packed.stderr b/src/test/ui/deriving-with-repr-packed.stderr
index 64aefbcd5df..a7599c1e7db 100644
--- a/src/test/ui/deriving-with-repr-packed.stderr
+++ b/src/test/ui/deriving-with-repr-packed.stderr
@@ -21,7 +21,7 @@ LL | #[derive(Copy, Clone, PartialEq, Eq)]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
 
-error: #[derive] can't be used on a non-Copy #[repr(packed)] struct (error E0133)
+error: #[derive] can't be used on a #[repr(packed)] struct that does not derive Copy (error E0133)
   --> $DIR/deriving-with-repr-packed.rs:26:10
    |
 LL | #[derive(PartialEq, Eq)]
@@ -30,7 +30,7 @@ LL | #[derive(PartialEq, Eq)]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #46043 <https://github.com/rust-lang/rust/issues/46043>
 
-error: #[derive] can't be used on a non-Copy #[repr(packed)] struct (error E0133)
+error: #[derive] can't be used on a #[repr(packed)] struct that does not derive Copy (error E0133)
   --> $DIR/deriving-with-repr-packed.rs:35:10
    |
 LL | #[derive(PartialEq)]
diff --git a/src/test/ui/error-codes/E0152.rs b/src/test/ui/error-codes/E0152.rs
index ae501b94e3f..8fbad7b3ff3 100644
--- a/src/test/ui/error-codes/E0152.rs
+++ b/src/test/ui/error-codes/E0152.rs
@@ -10,7 +10,7 @@
 
 #![feature(lang_items)]
 
-#[lang = "panic_fmt"]
+#[lang = "panic_impl"]
 struct Foo; //~ ERROR E0152
 
 fn main() {
diff --git a/src/test/ui/error-codes/E0152.stderr b/src/test/ui/error-codes/E0152.stderr
index f67022bd6d3..c7f5f362efb 100644
--- a/src/test/ui/error-codes/E0152.stderr
+++ b/src/test/ui/error-codes/E0152.stderr
@@ -1,4 +1,4 @@
-error[E0152]: duplicate lang item found: `panic_fmt`.
+error[E0152]: duplicate lang item found: `panic_impl`.
   --> $DIR/E0152.rs:14:1
    |
 LL | struct Foo; //~ ERROR E0152
diff --git a/src/test/ui/issue-23217.stderr b/src/test/ui/issue-23217.stderr
index d542a10e9b6..d87f239bca6 100644
--- a/src/test/ui/issue-23217.stderr
+++ b/src/test/ui/issue-23217.stderr
@@ -6,7 +6,7 @@ LL | pub enum SomeEnum {
 LL |     B = SomeEnum::A,
    |         ^^^^^^^^^^^ variant not found in `SomeEnum`
    |
-   = note: did you mean `variant::B`?
+   = note: did you mean `SomeEnum::B`?
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-28971.stderr b/src/test/ui/issue-28971.stderr
index df114351ff5..c04e21f7c58 100644
--- a/src/test/ui/issue-28971.stderr
+++ b/src/test/ui/issue-28971.stderr
@@ -7,7 +7,7 @@ LL | enum Foo {
 LL |             Foo::Baz(..) => (),
    |             ^^^^^^^^^^^^ variant not found in `Foo`
    |
-   = note: did you mean `variant::Bar`?
+   = note: did you mean `Foo::Bar`?
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.stderr b/src/test/ui/rfc-2166-underscore-imports/basic.stderr
index 4530d0fa604..c12c74b50e2 100644
--- a/src/test/ui/rfc-2166-underscore-imports/basic.stderr
+++ b/src/test/ui/rfc-2166-underscore-imports/basic.stderr
@@ -20,7 +20,7 @@ warning: unused extern crate
   --> $DIR/basic.rs:33:5
    |
 LL |     extern crate core as _; //~ WARN unused extern crate
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
    |
 note: lint level defined here
   --> $DIR/basic.rs:14:25
diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed
new file mode 100644
index 00000000000..4f99c1240f8
--- /dev/null
+++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed
@@ -0,0 +1,36 @@
+// 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.
+
+// aux-build:edition-lint-paths.rs
+// run-rustfix
+// compile-flags:--edition 2018
+
+// The "normal case". Ideally we would remove the `extern crate` here,
+// but we don't.
+
+#![feature(rust_2018_preview)]
+#![deny(rust_2018_idioms)]
+#![allow(dead_code)]
+
+
+//~^ ERROR unused extern crate
+
+use edition_lint_paths as bar;
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+
+fn main() {
+    // This is not considered to *use* the `extern crate` in Rust 2018:
+    use edition_lint_paths::foo;
+    foo();
+
+    // But this should be a use of the (renamed) crate:
+    crate::bar::foo();
+}
+
diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs
new file mode 100644
index 00000000000..9c1235a2967
--- /dev/null
+++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs
@@ -0,0 +1,36 @@
+// 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.
+
+// aux-build:edition-lint-paths.rs
+// run-rustfix
+// compile-flags:--edition 2018
+
+// The "normal case". Ideally we would remove the `extern crate` here,
+// but we don't.
+
+#![feature(rust_2018_preview)]
+#![deny(rust_2018_idioms)]
+#![allow(dead_code)]
+
+extern crate edition_lint_paths;
+//~^ ERROR unused extern crate
+
+extern crate edition_lint_paths as bar;
+//~^ ERROR `extern crate` is not idiomatic in the new edition
+
+fn main() {
+    // This is not considered to *use* the `extern crate` in Rust 2018:
+    use edition_lint_paths::foo;
+    foo();
+
+    // But this should be a use of the (renamed) crate:
+    crate::bar::foo();
+}
+
diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr
new file mode 100644
index 00000000000..b3afa2bd1d5
--- /dev/null
+++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr
@@ -0,0 +1,21 @@
+error: unused extern crate
+  --> $DIR/extern-crate-idiomatic-in-2018.rs:22:1
+   |
+LL | extern crate edition_lint_paths;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+   |
+note: lint level defined here
+  --> $DIR/extern-crate-idiomatic-in-2018.rs:19:9
+   |
+LL | #![deny(rust_2018_idioms)]
+   |         ^^^^^^^^^^^^^^^^
+   = note: #[deny(unused_extern_crates)] implied by #[deny(rust_2018_idioms)]
+
+error: `extern crate` is not idiomatic in the new edition
+  --> $DIR/extern-crate-idiomatic-in-2018.rs:25:1
+   |
+LL | extern crate edition_lint_paths as bar;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/suggestions/removing-extern-crate.fixed b/src/test/ui/suggestions/removing-extern-crate.fixed
index 723137f5db0..83b35cec809 100644
--- a/src/test/ui/suggestions/removing-extern-crate.fixed
+++ b/src/test/ui/suggestions/removing-extern-crate.fixed
@@ -16,12 +16,12 @@
 #![warn(rust_2018_idioms)]
 #![allow(unused_imports)]
 
-use std as foo;
+
 
 
 mod another {
-    use std as foo;
-    use std;
+    
+    
 }
 
 fn main() {}
diff --git a/src/test/ui/suggestions/removing-extern-crate.stderr b/src/test/ui/suggestions/removing-extern-crate.stderr
index 39d22de0277..f2eed27a266 100644
--- a/src/test/ui/suggestions/removing-extern-crate.stderr
+++ b/src/test/ui/suggestions/removing-extern-crate.stderr
@@ -1,31 +1,31 @@
-warning: `extern crate` is unnecessary in the new edition
+warning: unused extern crate
   --> $DIR/removing-extern-crate.rs:19:1
    |
 LL | extern crate std as foo;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use std as foo;`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
    |
 note: lint level defined here
   --> $DIR/removing-extern-crate.rs:16:9
    |
 LL | #![warn(rust_2018_idioms)]
    |         ^^^^^^^^^^^^^^^^
-   = note: #[warn(unnecessary_extern_crates)] implied by #[warn(rust_2018_idioms)]
+   = note: #[warn(unused_extern_crates)] implied by #[warn(rust_2018_idioms)]
 
-warning: `extern crate` is unnecessary in the new edition
+warning: unused extern crate
   --> $DIR/removing-extern-crate.rs:20:1
    |
 LL | extern crate core;
    | ^^^^^^^^^^^^^^^^^^ help: remove it
 
-warning: `extern crate` is unnecessary in the new edition
+warning: unused extern crate
   --> $DIR/removing-extern-crate.rs:23:5
    |
 LL |     extern crate std as foo;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `use`: `use std as foo;`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
 
-warning: `extern crate` is unnecessary in the new edition
+warning: unused extern crate
   --> $DIR/removing-extern-crate.rs:24:5
    |
 LL |     extern crate std;
-   |     ^^^^^^^^^^^^^^^^^ help: use `use`: `use std;`
+   |     ^^^^^^^^^^^^^^^^^ help: remove it
 
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 5daf192e2db..cc00f200171 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2529,7 +2529,7 @@ impl<'test> TestCx<'test> {
                 .env("IS_WINDOWS", "1")
                 .env("MSVC_LIB", format!("'{}' -nologo", lib.display()))
                 .env("CC", format!("'{}' {}", self.config.cc, cflags))
-                .env("CXX", &self.config.cxx);
+                .env("CXX", format!("'{}'", &self.config.cxx));
         } else {
             cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags))
                 .env("CXX", format!("{} {}", self.config.cxx, self.config.cflags))
diff --git a/src/tools/miri b/src/tools/miri
-Subproject 066a284557ff6e6a2aa19084f599f167a724af7
+Subproject e1734470e780e05a3366a2f74cfa25ea88a518a