about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-09-08 11:53:21 +0000
committerbors <bors@rust-lang.org>2018-09-08 11:53:21 +0000
commit05cb29e96f718a94d31afd094b1efd7c05be4269 (patch)
treed94400c78a25cb456fa3cc0a5666061b4f4dec73
parentff59ab127ac92885e4273bb73c8ac5a999c327bf (diff)
parent51c387931ed8df9b7daece4ad64b48bdd2b8335b (diff)
downloadrust-05cb29e96f718a94d31afd094b1efd7c05be4269.tar.gz
rust-05cb29e96f718a94d31afd094b1efd7c05be4269.zip
Auto merge of #54051 - kennytm:rollup, r=kennytm
Rollup of 10 pull requests

Successful merges:

 - #53315 (use `NonZeroU32` in `newtype_index!`macro, change syntax)
 - #53932 ([NLL] Remove base_place)
 - #53942 (Rewrite `precompute_borrows_out_of_scope` for fewer hash table lookups.)
 - #53973 (Have rust-lldb look for the rust-enabled lldb)
 - #53981 (Implement initializer() for FileDesc)
 - #53987 (rustbuild: allow configuring llvm version suffix)
 - #53993 (rustc_resolve: don't record uniform_paths canaries as reexports.)
 - #54007 (crates that provide a `panic_handler` are exempt from the `unused_extern_crates` lint)
 - #54040 (update books for next release)
 - #54050 (Update `petgraph` dependency to 0.4.13 to fix build with nightly)
-rw-r--r--config.toml.example4
-rw-r--r--src/Cargo.lock6
-rw-r--r--src/bootstrap/Cargo.toml2
-rw-r--r--src/bootstrap/config.rs3
-rw-r--r--src/bootstrap/dist.rs7
-rw-r--r--src/bootstrap/native.rs4
m---------src/doc/book0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
-rwxr-xr-xsrc/etc/rust-lldb26
-rw-r--r--src/librustc/dep_graph/dep_node.rs1
-rw-r--r--src/librustc/dep_graph/graph.rs12
-rw-r--r--src/librustc/dep_graph/serialized.rs4
-rw-r--r--src/librustc/hir/def_id.rs30
-rw-r--r--src/librustc/ich/impls_mir.rs5
-rw-r--r--src/librustc/ich/impls_ty.rs3
-rw-r--r--src/librustc/infer/error_reporting/mod.rs2
-rw-r--r--src/librustc/infer/region_constraints/mod.rs2
-rw-r--r--src/librustc/infer/unify_key.rs4
-rw-r--r--src/librustc/middle/region.rs10
-rw-r--r--src/librustc/mir/mod.rs38
-rw-r--r--src/librustc/session/mod.rs4
-rw-r--r--src/librustc/ty/query/config.rs6
-rw-r--r--src/librustc/ty/query/mod.rs1
-rw-r--r--src/librustc/ty/query/plumbing.rs1
-rw-r--r--src/librustc/ty/sty.rs43
-rw-r--r--src/librustc/util/ppaux.rs1
-rw-r--r--src/librustc_codegen_llvm/mir/mod.rs2
-rw-r--r--src/librustc_codegen_llvm/mir/operand.rs1
-rw-r--r--src/librustc_codegen_llvm/mir/place.rs1
-rw-r--r--src/librustc_data_structures/indexed_vec.rs214
-rw-r--r--src/librustc_data_structures/stable_hasher.rs8
-rw-r--r--src/librustc_driver/test.rs23
-rw-r--r--src/librustc_metadata/cstore_impl.rs1
-rw-r--r--src/librustc_metadata/encoder.rs2
-rw-r--r--src/librustc_metadata/schema.rs1
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs1
-rw-r--r--src/librustc_mir/borrow_check/location.rs6
-rw-r--r--src/librustc_mir/borrow_check/mod.rs50
-rw-r--r--src/librustc_mir/borrow_check/move_errors.rs1
-rw-r--r--src/librustc_mir/borrow_check/nll/constraints/mod.rs12
-rw-r--r--src/librustc_mir/borrow_check/nll/facts.rs12
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs1
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/values.rs8
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs6
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs4
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs1
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs2
-rw-r--r--src/librustc_mir/build/mod.rs4
-rw-r--r--src/librustc_mir/build/scope.rs1
-rw-r--r--src/librustc_mir/const_eval.rs2
-rw-r--r--src/librustc_mir/dataflow/at_location.rs1
-rw-r--r--src/librustc_mir/dataflow/graphviz.rs1
-rw-r--r--src/librustc_mir/dataflow/impls/borrows.rs120
-rw-r--r--src/librustc_mir/interpret/operand.rs2
-rw-r--r--src/librustc_mir/interpret/place.rs1
-rw-r--r--src/librustc_mir/lib.rs1
-rw-r--r--src/librustc_mir/transform/const_prop.rs3
-rw-r--r--src/librustc_mir/transform/elaborate_drops.rs1
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs2
-rw-r--r--src/librustc_mir/transform/rustc_peek.rs1
-rw-r--r--src/librustc_mir/util/graphviz.rs2
-rw-r--r--src/librustc_resolve/resolve_imports.rs10
-rw-r--r--src/librustc_typeck/astconv.rs7
-rw-r--r--src/librustc_typeck/check/mod.rs5
-rw-r--r--src/librustc_typeck/check_unused.rs1
-rw-r--r--src/libserialize/serialize.rs13
-rw-r--r--src/libstd/sys/unix/fd.rs7
-rw-r--r--src/test/run-make-fulldeps/issue-53964/Makefile5
-rw-r--r--src/test/run-make-fulldeps/issue-53964/app.rs8
-rw-r--r--src/test/run-make-fulldeps/issue-53964/panic.rs20
-rw-r--r--src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs19
-rw-r--r--src/test/run-pass/uniform-paths/issue-53691.rs18
-rw-r--r--src/test/ui/borrowck/borrowck-box-insensitivity.nll.stderr35
-rw-r--r--src/test/ui/borrowck/borrowck-box-insensitivity.rs3
-rw-r--r--src/test/ui/removing-extern-crate.rs6
-rw-r--r--src/test/ui/removing-extern-crate.stderr12
78 files changed, 549 insertions, 338 deletions
diff --git a/config.toml.example b/config.toml.example
index 35f69cd05b6..087dc418e2d 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -82,6 +82,10 @@
 # passed to prefer linking to shared libraries.
 #link-shared = false
 
+# When building llvm, this configures what is being appended to the version.
+# If absent, we let the version as-is.
+#version-suffix = "-rust"
+
 # On MSVC you can compile LLVM with clang-cl, but the test suite doesn't pass
 # with clang-cl, so this is special in that it only compiles LLVM with clang-cl
 #clang-cl = '/path/to/clang-cl.exe'
diff --git a/src/Cargo.lock b/src/Cargo.lock
index fc2dfcfd860..9828966fa95 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -138,7 +138,7 @@ dependencies = [
  "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1471,7 +1471,7 @@ dependencies = [
 
 [[package]]
 name = "petgraph"
-version = "0.4.12"
+version = "0.4.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3243,7 +3243,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
 "checksum pest 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0fce5d8b5cc33983fc74f78ad552b5522ab41442c4ca91606e4236eb4b5ceefc"
 "checksum pest_derive 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ab94faafeb93f4c5e3ce81ca0e5a779529a602ad5d09ae6d21996bfb8b6a52bf"
-"checksum petgraph 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8b30dc85588cd02b9b76f5e386535db546d21dc68506cff2abebee0b6445e8e4"
+"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
 "checksum phf 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "7d37a244c75a9748e049225155f56dbcb98fe71b192fd25fd23cb914b5ad62f2"
 "checksum phf_codegen 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "4e4048fe7dd7a06b8127ecd6d3803149126e9b33c7558879846da3a63f734f2b"
 "checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998"
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 57a52603804..3e91c2b3e86 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -47,7 +47,7 @@ serde_json = "1.0.2"
 toml = "0.4"
 lazy_static = "0.2"
 time = "0.1"
-petgraph = "0.4.12"
+petgraph = "0.4.13"
 
 [dev-dependencies]
 pretty_assertions = "0.5"
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index bf4d39c4947..70b21a1567b 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -86,6 +86,7 @@ pub struct Config {
     pub llvm_targets: Option<String>,
     pub llvm_experimental_targets: String,
     pub llvm_link_jobs: Option<u32>,
+    pub llvm_version_suffix: Option<String>,
 
     pub lld_enabled: bool,
     pub lldb_enabled: bool,
@@ -256,6 +257,7 @@ struct Llvm {
     experimental_targets: Option<String>,
     link_jobs: Option<u32>,
     link_shared: Option<bool>,
+    version_suffix: Option<String>,
     clang_cl: Option<String>
 }
 
@@ -516,6 +518,7 @@ impl Config {
             config.llvm_experimental_targets = llvm.experimental_targets.clone()
                 .unwrap_or("WebAssembly;RISCV".to_string());
             config.llvm_link_jobs = llvm.link_jobs;
+            config.llvm_version_suffix = llvm.version_suffix.clone();
             config.llvm_clang_cl = llvm.clang_cl.clone();
         }
 
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 167e4a78eda..2d94704fda7 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -2056,7 +2056,8 @@ impl Step for Lldb {
         drop(fs::remove_dir_all(&image));
 
         // Prepare the image directory
-        let dst = image.join("bin");
+        let root = image.join("lib/rustlib").join(&*target);
+        let dst = root.join("bin");
         t!(fs::create_dir_all(&dst));
         for program in &["lldb", "lldb-argdumper", "lldb-mi", "lldb-server"] {
             let exe = bindir.join(exe(program, &target));
@@ -2065,7 +2066,7 @@ impl Step for Lldb {
 
         // The libraries.
         let libdir = builder.llvm_out(target).join("lib");
-        let dst = image.join("lib");
+        let dst = root.join("lib");
         t!(fs::create_dir_all(&dst));
         for entry in t!(fs::read_dir(&libdir)) {
             let entry = entry.unwrap();
@@ -2093,7 +2094,7 @@ impl Step for Lldb {
             let entry = t!(entry);
             if let Ok(name) = entry.file_name().into_string() {
                 if name.starts_with("python") {
-                    let dst = image.join(libdir_name)
+                    let dst = root.join(libdir_name)
                         .join(entry.file_name());
                     t!(fs::create_dir_all(&dst));
                     builder.cp_r(&entry.path(), &dst);
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index caf38d766f5..828a7d14c04 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -239,6 +239,10 @@ impl Step for Llvm {
             cfg.define("LLVM_NATIVE_BUILD", builder.llvm_out(builder.config.build).join("build"));
         }
 
+        if let Some(ref suffix) = builder.config.llvm_version_suffix {
+            cfg.define("LLVM_VERSION_SUFFIX", suffix);
+        }
+
         if let Some(ref python) = builder.config.python {
             cfg.define("PYTHON_EXECUTABLE", python);
         }
diff --git a/src/doc/book b/src/doc/book
-Subproject 16c9dee7666c2b2766fd98d89003e028679d120
+Subproject cff0930664b688f1dd22aefb3d16944eb4cdbfd
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject ae42ad7aa4d7907cca941371c9eee8de8c2ee40
+Subproject 7fd493465b7dd6cf3476f0b834884059bbdd1d9
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 219e261ddb833a5683627b0a9be87a0f4486abb
+Subproject 821355a6fd642b71988a2f88a3162fb35873201
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject e3719fc78ff4a21dfd13cfcc9e2ca42cb5de29f
+Subproject e459fb3f07f2b930ccd25d348671b8eae233fd6
diff --git a/src/etc/rust-lldb b/src/etc/rust-lldb
index 6a2849b5548..6ed8210349e 100755
--- a/src/etc/rust-lldb
+++ b/src/etc/rust-lldb
@@ -12,27 +12,35 @@
 # Exit if anything fails
 set -e
 
-LLDB_VERSION=`lldb --version 2>/dev/null | head -1 | cut -d. -f1`
+# Find out where to look for the pretty printer Python module
+RUSTC_SYSROOT=`rustc --print sysroot`
+
+# Find the host triple so we can find lldb in rustlib.
+host=`rustc -vV | sed -n -e 's/^host: //p'`
+
+lldb=lldb
+if [ -f "$RUSTC_SYSROOT/lib/rustlib/$host/bin/lldb" ]; then
+    lldb="$RUSTC_SYSROOT/lib/rustlib/$host/bin/lldb"
+else
+    LLDB_VERSION=`"$lldb" --version 2>/dev/null | head -1 | cut -d. -f1`
 
-if [ "$LLDB_VERSION" = "lldb-350" ]
-then
-    echo "***"
+    if [ "$LLDB_VERSION" = "lldb-350" ]
+    then
+        echo "***"
 	echo \
 "WARNING: This version of LLDB has known issues with Rust and cannot \
 display the contents of local variables!"
-    echo "***"
+        echo "***"
+    fi
 fi
 
-# Find out where to look for the pretty printer Python module
-RUSTC_SYSROOT=`rustc --print sysroot`
-
 # Prepare commands that will be loaded before any file on the command line has been loaded
 script_import="command script import \"$RUSTC_SYSROOT/lib/rustlib/etc/lldb_rust_formatters.py\""
 category_definition="type summary add --no-value --python-function lldb_rust_formatters.print_val -x \".*\" --category Rust"
 category_enable="type category enable Rust"
 
 # Call LLDB with the commands added to the argument list
-exec lldb --one-line-before-file="$script_import" \
+exec "$lldb" --one-line-before-file="$script_import" \
     --one-line-before-file="$category_definition" \
     --one-line-before-file="$category_enable" \
     "$@"
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index dfe0a395ca1..d15568af6ae 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -574,6 +574,7 @@ define_dep_nodes!( <'tcx>
     [] IsPanicRuntime(CrateNum),
     [] IsCompilerBuiltins(CrateNum),
     [] HasGlobalAllocator(CrateNum),
+    [] HasPanicHandler(CrateNum),
     [input] ExternCrate(DefId),
     [eval_always] LintLevels,
     [] Specializes { impl1: DefId, impl2: DefId },
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
index 4df0fc443a2..f5a46060759 100644
--- a/src/librustc/dep_graph/graph.rs
+++ b/src/librustc/dep_graph/graph.rs
@@ -39,10 +39,12 @@ pub struct DepGraph {
     fingerprints: Lrc<Lock<IndexVec<DepNodeIndex, Fingerprint>>>
 }
 
-newtype_index!(DepNodeIndex);
+newtype_index! {
+    pub struct DepNodeIndex { .. }
+}
 
 impl DepNodeIndex {
-    const INVALID: DepNodeIndex = DepNodeIndex(::std::u32::MAX);
+    const INVALID: DepNodeIndex = DepNodeIndex::MAX;
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
@@ -1125,14 +1127,16 @@ impl DepNodeColorMap {
         match self.values[index] {
             COMPRESSED_NONE => None,
             COMPRESSED_RED => Some(DepNodeColor::Red),
-            value => Some(DepNodeColor::Green(DepNodeIndex(value - COMPRESSED_FIRST_GREEN)))
+            value => Some(DepNodeColor::Green(DepNodeIndex::from_u32(
+                value - COMPRESSED_FIRST_GREEN
+            )))
         }
     }
 
     fn insert(&mut self, index: SerializedDepNodeIndex, color: DepNodeColor) {
         self.values[index] = match color {
             DepNodeColor::Red => COMPRESSED_RED,
-            DepNodeColor::Green(index) => index.0 + COMPRESSED_FIRST_GREEN,
+            DepNodeColor::Green(index) => index.as_u32() + COMPRESSED_FIRST_GREEN,
         }
     }
 }
diff --git a/src/librustc/dep_graph/serialized.rs b/src/librustc/dep_graph/serialized.rs
index 60fc813a25d..4c896a33e59 100644
--- a/src/librustc/dep_graph/serialized.rs
+++ b/src/librustc/dep_graph/serialized.rs
@@ -14,7 +14,9 @@ use dep_graph::DepNode;
 use ich::Fingerprint;
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 
-newtype_index!(SerializedDepNodeIndex);
+newtype_index! {
+    pub struct SerializedDepNodeIndex { .. }
+}
 
 /// Data for use when recompiling the **current crate**.
 #[derive(Debug, RustcEncodable, RustcDecodable)]
diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs
index be37ea18457..420ffbcfee6 100644
--- a/src/librustc/hir/def_id.rs
+++ b/src/librustc/hir/def_id.rs
@@ -15,8 +15,8 @@ use serialize;
 use std::fmt;
 use std::u32;
 
-newtype_index!(CrateNum
-    {
+newtype_index! {
+    pub struct CrateNum {
         ENCODABLE = custom
         DEBUG_FORMAT = "crate{}",
 
@@ -27,32 +27,20 @@ newtype_index!(CrateNum
         /// Virtual crate for builtin macros
         // FIXME(jseyfried): this is also used for custom derives until proc-macro crates get
         // `CrateNum`s.
-        const BUILTIN_MACROS_CRATE = u32::MAX,
+        const BUILTIN_MACROS_CRATE = CrateNum::MAX_AS_U32,
 
         /// A CrateNum value that indicates that something is wrong.
-        const INVALID_CRATE = u32::MAX - 1,
+        const INVALID_CRATE = CrateNum::MAX_AS_U32 - 1,
 
         /// A special CrateNum that we use for the tcx.rcache when decoding from
         /// the incr. comp. cache.
-        const RESERVED_FOR_INCR_COMP_CACHE = u32::MAX - 2,
-    });
+        const RESERVED_FOR_INCR_COMP_CACHE = CrateNum::MAX_AS_U32 - 2,
+    }
+}
 
 impl CrateNum {
     pub fn new(x: usize) -> CrateNum {
-        assert!(x < (u32::MAX as usize));
-        CrateNum(x as u32)
-    }
-
-    pub fn from_u32(x: u32) -> CrateNum {
-        CrateNum(x)
-    }
-
-    pub fn as_usize(&self) -> usize {
-        self.0 as usize
-    }
-
-    pub fn as_u32(&self) -> u32 {
-        self.0
+        CrateNum::from_usize(x)
     }
 
     pub fn as_def_id(&self) -> DefId { DefId { krate: *self, index: CRATE_DEF_INDEX } }
@@ -60,7 +48,7 @@ impl CrateNum {
 
 impl fmt::Display for CrateNum {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        fmt::Display::fmt(&self.0, f)
+        fmt::Display::fmt(&self.as_u32(), f)
     }
 }
 
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs
index f11e4487964..8b7438cbe63 100644
--- a/src/librustc/ich/impls_mir.rs
+++ b/src/librustc/ich/impls_mir.rs
@@ -102,7 +102,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::Local {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
-        use rustc_data_structures::indexed_vec::Idx;
         self.index().hash_stable(hcx, hasher);
     }
 }
@@ -112,7 +111,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::BasicBlock {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
-        use rustc_data_structures::indexed_vec::Idx;
         self.index().hash_stable(hcx, hasher);
     }
 }
@@ -122,7 +120,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::Field {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
-        use rustc_data_structures::indexed_vec::Idx;
         self.index().hash_stable(hcx, hasher);
     }
 }
@@ -133,7 +130,6 @@ for mir::SourceScope {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
-        use rustc_data_structures::indexed_vec::Idx;
         self.index().hash_stable(hcx, hasher);
     }
 }
@@ -143,7 +139,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::Promoted {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
-        use rustc_data_structures::indexed_vec::Idx;
         self.index().hash_stable(hcx, hasher);
     }
 }
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index 68320dfddef..e90c4f62f59 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -143,7 +143,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
-        use rustc_data_structures::indexed_vec::Idx;
         self.index().hash_stable(hcx, hasher);
     }
 }
@@ -153,7 +152,6 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::CanonicalVar {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'gcx>,
                                           hasher: &mut StableHasher<W>) {
-        use rustc_data_structures::indexed_vec::Idx;
         self.index().hash_stable(hcx, hasher);
     }
 }
@@ -774,7 +772,6 @@ impl_stable_hash_for!(enum ty::cast::CastKind {
     FnPtrAddrCast
 });
 
-impl_stable_hash_for!(tuple_struct ::middle::region::FirstStatementIndex { idx });
 impl_stable_hash_for!(struct ::middle::region::Scope { id, code });
 
 impl<'a> ToStableHashKey<StableHashingContext<'a>> for region::Scope {
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index ac6a7f0c2ba..eabcf1ce413 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -73,8 +73,6 @@ use syntax::ast::DUMMY_NODE_ID;
 use syntax_pos::{Pos, Span};
 use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
 
-use rustc_data_structures::indexed_vec::Idx;
-
 mod note;
 
 mod need_type_info;
diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs
index 296808cea2b..d8f3b9a05bd 100644
--- a/src/librustc/infer/region_constraints/mod.rs
+++ b/src/librustc/infer/region_constraints/mod.rs
@@ -16,7 +16,7 @@ use self::CombineMapType::*;
 use super::{MiscVariable, RegionVariableOrigin, SubregionOrigin};
 use super::unify_key;
 
-use rustc_data_structures::indexed_vec::{IndexVec, Idx};
+use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::unify as ut;
 use ty::{self, Ty, TyCtxt};
diff --git a/src/librustc/infer/unify_key.rs b/src/librustc/infer/unify_key.rs
index a1145572b79..cdc92877a5a 100644
--- a/src/librustc/infer/unify_key.rs
+++ b/src/librustc/infer/unify_key.rs
@@ -49,8 +49,8 @@ impl UnifyValue for RegionVidKey {
 
 impl UnifyKey for ty::RegionVid {
     type Value = RegionVidKey;
-    fn index(&self) -> u32 { self.0 }
-    fn from_index(i: u32) -> ty::RegionVid { ty::RegionVid(i) }
+    fn index(&self) -> u32 { u32::from(*self) }
+    fn from_index(i: u32) -> ty::RegionVid { ty::RegionVid::from(i) }
     fn tag() -> &'static str { "RegionVid" }
 }
 
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index e281cbf9488..f6a8f8dc172 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -159,11 +159,13 @@ pub struct BlockRemainder {
     pub first_statement_index: FirstStatementIndex,
 }
 
-newtype_index!(FirstStatementIndex
-    {
-        pub idx
+newtype_index! {
+    pub struct FirstStatementIndex {
         MAX = SCOPE_DATA_REMAINDER_MAX
-    });
+    }
+}
+
+impl_stable_hash_for!(struct ::middle::region::FirstStatementIndex { private });
 
 impl From<ScopeData> for Scope {
     #[inline]
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index f66be6dc54d..c6a1281061f 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -131,9 +131,6 @@ pub struct Mir<'tcx> {
     cache: cache::Cache,
 }
 
-/// where execution begins
-pub const START_BLOCK: BasicBlock = BasicBlock(0);
-
 impl<'tcx> Mir<'tcx> {
     pub fn new(
         basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
@@ -239,7 +236,7 @@ impl<'tcx> Mir<'tcx> {
 
     #[inline]
     pub fn local_kind(&self, local: Local) -> LocalKind {
-        let index = local.0 as usize;
+        let index = local.as_usize();
         if index == 0 {
             debug_assert!(
                 self.local_decls[local].mutability == Mutability::Mut,
@@ -523,11 +520,12 @@ impl BorrowKind {
 ///////////////////////////////////////////////////////////////////////////
 // Variables and temps
 
-newtype_index!(Local
-    {
+newtype_index! {
+    pub struct Local {
         DEBUG_FORMAT = "_{}",
         const RETURN_PLACE = 0,
-    });
+    }
+}
 
 /// Classifies locals into categories. See `Mir::local_kind`.
 #[derive(PartialEq, Eq, Debug)]
@@ -852,7 +850,12 @@ pub struct UpvarDecl {
 ///////////////////////////////////////////////////////////////////////////
 // BasicBlock
 
-newtype_index!(BasicBlock { DEBUG_FORMAT = "bb{}" });
+newtype_index! {
+    pub struct BasicBlock {
+        DEBUG_FORMAT = "bb{}",
+        const START_BLOCK = 0,
+    }
+}
 
 impl BasicBlock {
     pub fn start_location(self) -> Location {
@@ -1822,7 +1825,11 @@ pub type PlaceProjection<'tcx> = Projection<'tcx, Place<'tcx>, Local, Ty<'tcx>>;
 /// and the index is a local.
 pub type PlaceElem<'tcx> = ProjectionElem<'tcx, Local, Ty<'tcx>>;
 
-newtype_index!(Field { DEBUG_FORMAT = "field[{}]" });
+newtype_index! {
+    pub struct Field {
+        DEBUG_FORMAT = "field[{}]"
+    }
+}
 
 impl<'tcx> Place<'tcx> {
     pub fn field(self, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
@@ -1895,11 +1902,12 @@ impl<'tcx> Debug for Place<'tcx> {
 ///////////////////////////////////////////////////////////////////////////
 // Scopes
 
-newtype_index!(SourceScope
-    {
+newtype_index! {
+    pub struct SourceScope {
         DEBUG_FORMAT = "scope[{}]",
         const OUTERMOST_SOURCE_SCOPE = 0,
-    });
+    }
+}
 
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub struct SourceScopeData {
@@ -2271,7 +2279,11 @@ pub struct Constant<'tcx> {
     pub literal: &'tcx ty::Const<'tcx>,
 }
 
-newtype_index!(Promoted { DEBUG_FORMAT = "promoted[{}]" });
+newtype_index! {
+    pub struct Promoted {
+        DEBUG_FORMAT = "promoted[{}]"
+    }
+}
 
 impl<'tcx> Debug for Constant<'tcx> {
     fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 778c388c7de..272967282e0 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -159,6 +159,9 @@ pub struct Session {
     /// Metadata about the allocators for the current crate being compiled
     pub has_global_allocator: Once<bool>,
 
+    /// Metadata about the panic handlers for the current crate being compiled
+    pub has_panic_handler: Once<bool>,
+
     /// Cap lint level specified by a driver specifically.
     pub driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
 }
@@ -1160,6 +1163,7 @@ pub fn build_session_(
             (*GLOBAL_JOBSERVER).clone()
         },
         has_global_allocator: Once::new(),
+        has_panic_handler: Once::new(),
         driver_lint_caps: FxHashMap(),
     };
 
diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs
index 837354bfcaf..2bbf5aacc1a 100644
--- a/src/librustc/ty/query/config.rs
+++ b/src/librustc/ty/query/config.rs
@@ -464,6 +464,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::has_global_allocator<'tcx> {
     }
 }
 
+impl<'tcx> QueryDescription<'tcx> for queries::has_panic_handler<'tcx> {
+    fn describe(_: TyCtxt, _: CrateNum) -> String {
+        "checking if the crate has_panic_handler".to_string()
+    }
+}
+
 impl<'tcx> QueryDescription<'tcx> for queries::extern_crate<'tcx> {
     fn describe(_: TyCtxt, _: DefId) -> String {
         "getting crate's ExternCrateData".to_string()
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index 993ba2fd13d..f0ca168e9e4 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -381,6 +381,7 @@ define_queries! { <'tcx>
         [fatal_cycle] fn is_panic_runtime: IsPanicRuntime(CrateNum) -> bool,
         [fatal_cycle] fn is_compiler_builtins: IsCompilerBuiltins(CrateNum) -> bool,
         [fatal_cycle] fn has_global_allocator: HasGlobalAllocator(CrateNum) -> bool,
+        [fatal_cycle] fn has_panic_handler: HasPanicHandler(CrateNum) -> bool,
         [fatal_cycle] fn is_sanitizer_runtime: IsSanitizerRuntime(CrateNum) -> bool,
         [fatal_cycle] fn is_profiler_runtime: IsProfilerRuntime(CrateNum) -> bool,
         [fatal_cycle] fn panic_strategy: GetPanicStrategy(CrateNum) -> PanicStrategy,
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index 215fba54499..3c26732fbac 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -1168,6 +1168,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
         DepKind::IsPanicRuntime => { force!(is_panic_runtime, krate!()); }
         DepKind::IsCompilerBuiltins => { force!(is_compiler_builtins, krate!()); }
         DepKind::HasGlobalAllocator => { force!(has_global_allocator, krate!()); }
+        DepKind::HasPanicHandler => { force!(has_panic_handler, krate!()); }
         DepKind::ExternCrate => { force!(extern_crate, def_id!()); }
         DepKind::LintLevels => { force!(lint_levels, LOCAL_CRATE); }
         DepKind::InScopeTraits => { force!(in_scope_traits_map, def_id!().index); }
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 7c7ee9b330e..b5ec1ad36ab 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -1034,11 +1034,12 @@ impl<'a, 'gcx, 'tcx> ParamTy {
 /// is the outer fn.
 ///
 /// [dbi]: http://en.wikipedia.org/wiki/De_Bruijn_index
-newtype_index!(DebruijnIndex
-    {
+newtype_index! {
+    pub struct DebruijnIndex {
         DEBUG_FORMAT = "DebruijnIndex({})",
         const INNERMOST = 0,
-    });
+    }
+}
 
 pub type Region<'tcx> = &'tcx RegionKind;
 
@@ -1176,11 +1177,11 @@ pub struct FloatVid {
     pub index: u32,
 }
 
-newtype_index!(RegionVid
-    {
-        pub idx
+newtype_index! {
+    pub struct RegionVid {
         DEBUG_FORMAT = custom,
-    });
+    }
+}
 
 impl Atom for RegionVid {
     fn index(self) -> usize {
@@ -1188,18 +1189,6 @@ impl Atom for RegionVid {
     }
 }
 
-impl From<usize> for RegionVid {
-    fn from(i: usize) -> RegionVid {
-        RegionVid::new(i)
-    }
-}
-
-impl From<RegionVid> for usize {
-    fn from(vid: RegionVid) -> usize {
-        Idx::index(vid)
-    }
-}
-
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
 pub enum InferTy {
     TyVar(TyVid),
@@ -1217,7 +1206,9 @@ pub enum InferTy {
     CanonicalTy(CanonicalVar),
 }
 
-newtype_index!(CanonicalVar);
+newtype_index! {
+    pub struct CanonicalVar { .. }
+}
 
 /// A `ProjectionPredicate` for an `ExistentialTraitRef`.
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
@@ -1282,8 +1273,8 @@ impl DebruijnIndex {
     ///
     /// you would need to shift the index for `'a` into 1 new binder.
     #[must_use]
-    pub const fn shifted_in(self, amount: u32) -> DebruijnIndex {
-        DebruijnIndex(self.0 + amount)
+    pub fn shifted_in(self, amount: u32) -> DebruijnIndex {
+        DebruijnIndex::from_u32(self.as_u32() + amount)
     }
 
     /// Update this index in place by shifting it "in" through
@@ -1295,8 +1286,8 @@ impl DebruijnIndex {
     /// Returns the resulting index when this value is moved out from
     /// `amount` number of new binders.
     #[must_use]
-    pub const fn shifted_out(self, amount: u32) -> DebruijnIndex {
-        DebruijnIndex(self.0 - amount)
+    pub fn shifted_out(self, amount: u32) -> DebruijnIndex {
+        DebruijnIndex::from_u32(self.as_u32() - amount)
     }
 
     /// Update in place by shifting out from `amount` binders.
@@ -1325,11 +1316,11 @@ impl DebruijnIndex {
     /// bound by one of the binders we are shifting out of, that is an
     /// error (and should fail an assertion failure).
     pub fn shifted_out_to_binder(self, to_binder: DebruijnIndex) -> Self {
-        self.shifted_out((to_binder.0 - INNERMOST.0) as u32)
+        self.shifted_out(to_binder.as_u32() - INNERMOST.as_u32())
     }
 }
 
-impl_stable_hash_for!(tuple_struct DebruijnIndex { index });
+impl_stable_hash_for!(struct DebruijnIndex { private });
 
 /// Region utilities
 impl RegionKind {
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 0f15c75c2fb..e8236e21e24 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -26,7 +26,6 @@ use std::cell::Cell;
 use std::fmt;
 use std::usize;
 
-use rustc_data_structures::indexed_vec::Idx;
 use rustc_target::spec::abi::Abi;
 use syntax::ast::CRATE_NODE_ID;
 use syntax::symbol::{Symbol, InternedString};
diff --git a/src/librustc_codegen_llvm/mir/mod.rs b/src/librustc_codegen_llvm/mir/mod.rs
index 9e65144bd60..258fe643c30 100644
--- a/src/librustc_codegen_llvm/mir/mod.rs
+++ b/src/librustc_codegen_llvm/mir/mod.rs
@@ -32,7 +32,7 @@ use syntax::symbol::keywords;
 use std::iter;
 
 use rustc_data_structures::bitvec::BitArray;
-use rustc_data_structures::indexed_vec::{IndexVec, Idx};
+use rustc_data_structures::indexed_vec::IndexVec;
 
 pub use self::constant::codegen_static_initializer;
 
diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs
index 419e7298588..bfa0e0a451e 100644
--- a/src/librustc_codegen_llvm/mir/operand.rs
+++ b/src/librustc_codegen_llvm/mir/operand.rs
@@ -13,7 +13,6 @@ use rustc::mir;
 use rustc::mir::interpret::{ConstValue, ScalarMaybeUndef};
 use rustc::ty;
 use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
-use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::sync::Lrc;
 
 use base;
diff --git a/src/librustc_codegen_llvm/mir/place.rs b/src/librustc_codegen_llvm/mir/place.rs
index 833dca8c75f..4baab1763c3 100644
--- a/src/librustc_codegen_llvm/mir/place.rs
+++ b/src/librustc_codegen_llvm/mir/place.rs
@@ -13,7 +13,6 @@ use rustc::ty::{self, Ty};
 use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, Size};
 use rustc::mir;
 use rustc::mir::tcx::PlaceTy;
-use rustc_data_structures::indexed_vec::Idx;
 use base;
 use builder::Builder;
 use common::{CodegenCx, C_undef, C_usize, C_u8, C_u32, C_uint, C_null, C_uint_big};
diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs
index c358f2f852e..186bc6d43cc 100644
--- a/src/librustc_data_structures/indexed_vec.rs
+++ b/src/librustc_data_structures/indexed_vec.rs
@@ -48,25 +48,42 @@ impl Idx for u32 {
     fn index(self) -> usize { self as usize }
 }
 
+/// Creates a struct type `S` that can be used as an index with
+/// `IndexVec` and so on.
+///
+/// There are two ways of interacting with these indices:
+///
+/// - The `From` impls are the preferred way. So you can do
+///   `S::from(v)` with a `usize` or `u32`. And you can convert back
+///   to an integer with `u32::from(s)`.
+///
+/// - Alternatively, you can use the methods `S::new(v)` and `s.index()`
+///   to create/return a value.
+///
+/// Internally, the index uses a u32, so the index must not exceed
+/// `u32::MAX`. You can also customize things like the `Debug` impl,
+/// what traits are derived, and so forth via the macro.
 #[macro_export]
 macro_rules! newtype_index {
     // ---- public rules ----
 
     // Use default constants
-    ($name:ident) => (
+    ($v:vis struct $name:ident { .. }) => (
         newtype_index!(
             // Leave out derives marker so we can use its absence to ensure it comes first
             @type         [$name]
-            @max          [::std::u32::MAX]
+            @max          [::std::u32::MAX - 1]
+            @vis          [$v]
             @debug_format ["{}"]);
     );
 
     // Define any constants
-    ($name:ident { $($tokens:tt)+ }) => (
+    ($v:vis struct $name:ident { $($tokens:tt)+ }) => (
         newtype_index!(
             // Leave out derives marker so we can use its absence to ensure it comes first
             @type         [$name]
-            @max          [::std::u32::MAX]
+            @max          [::std::u32::MAX - 1]
+            @vis          [$v]
             @debug_format ["{}"]
                           $($tokens)+);
     );
@@ -75,27 +92,92 @@ macro_rules! newtype_index {
 
     // Base case, user-defined constants (if any) have already been defined
     (@derives      [$($derives:ident,)*]
-     @pub          [$($pub:tt)*]
      @type         [$type:ident]
      @max          [$max:expr]
+     @vis          [$v:vis]
      @debug_format [$debug_format:tt]) => (
         #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, $($derives),*)]
-        pub struct $type($($pub)* u32);
+        $v struct $type {
+            private: u32
+        }
+
+        impl $type {
+            $v const MAX_AS_U32: u32 = $max;
+
+            $v const MAX: $type = $type::from_u32_const($max);
+
+            #[inline]
+            $v fn from_usize(value: usize) -> Self {
+                assert!(value <= ($max as usize));
+                unsafe {
+                    $type::from_u32_unchecked(value as u32)
+                }
+            }
+
+            #[inline]
+            $v fn from_u32(value: u32) -> Self {
+                assert!(value <= $max);
+                unsafe {
+                    $type::from_u32_unchecked(value)
+                }
+            }
+
+            /// Hacky variant of `from_u32` for use in constants.
+            /// This version checks the "max" constraint by using an
+            /// invalid array dereference.
+            #[inline]
+            $v const fn from_u32_const(value: u32) -> Self {
+                // This will fail at const eval time unless `value <=
+                // max` is true (in which case we get the index 0).
+                // It will also fail at runtime, of course, but in a
+                // kind of wacky way.
+                let _ = ["out of range value used"][
+                    !(value <= $max) as usize
+                ];
+
+                unsafe {
+                    $type { private: value }
+                }
+            }
+
+            #[inline]
+            $v const unsafe fn from_u32_unchecked(value: u32) -> Self {
+                $type { private: value }
+            }
+
+            /// Extract value of this index as an integer.
+            #[inline]
+            $v fn index(self) -> usize {
+                self.as_usize()
+            }
+
+            /// Extract value of this index as a usize.
+            #[inline]
+            $v fn as_u32(self) -> u32 {
+                self.private
+            }
+
+            /// Extract value of this index as a u32.
+            #[inline]
+            $v fn as_usize(self) -> usize {
+                self.as_u32() as usize
+            }
+        }
 
         impl Idx for $type {
             #[inline]
             fn new(value: usize) -> Self {
-                assert!(value < ($max) as usize);
-                $type(value as u32)
+                Self::from(value)
             }
 
             #[inline]
             fn index(self) -> usize {
-                self.0 as usize
+                usize::from(self)
             }
         }
 
         impl ::std::iter::Step for $type {
+            #[inline]
             fn steps_between(start: &Self, end: &Self) -> Option<usize> {
                 <usize as ::std::iter::Step>::steps_between(
                     &Idx::index(*start),
@@ -103,27 +185,60 @@ macro_rules! newtype_index {
                 )
             }
 
+            #[inline]
             fn replace_one(&mut self) -> Self {
                 ::std::mem::replace(self, Self::new(1))
             }
 
+            #[inline]
             fn replace_zero(&mut self) -> Self {
                 ::std::mem::replace(self, Self::new(0))
             }
 
+            #[inline]
             fn add_one(&self) -> Self {
                 Self::new(Idx::index(*self) + 1)
             }
 
+            #[inline]
             fn sub_one(&self) -> Self {
                 Self::new(Idx::index(*self) - 1)
             }
 
+            #[inline]
             fn add_usize(&self, u: usize) -> Option<Self> {
                 Idx::index(*self).checked_add(u).map(Self::new)
             }
         }
 
+        impl From<$type> for u32 {
+            #[inline]
+            fn from(v: $type) -> u32 {
+                v.as_u32()
+            }
+        }
+
+        impl From<$type> for usize {
+            #[inline]
+            fn from(v: $type) -> usize {
+                v.as_usize()
+            }
+        }
+
+        impl From<usize> for $type {
+            #[inline]
+            fn from(value: usize) -> Self {
+                $type::from_usize(value)
+            }
+        }
+
+        impl From<u32> for $type {
+            #[inline]
+            fn from(value: u32) -> Self {
+                $type::from_u32(value)
+            }
+        }
+
         newtype_index!(
             @handle_debug
             @derives      [$($derives,)*]
@@ -144,7 +259,7 @@ macro_rules! newtype_index {
      @debug_format [$debug_format:tt]) => (
         impl ::std::fmt::Debug for $type {
             fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
-                write!(fmt, $debug_format, self.0)
+                write!(fmt, $debug_format, self.as_u32())
             }
         }
     );
@@ -167,44 +282,17 @@ macro_rules! newtype_index {
             @debug_format [$debug_format]);
     );
 
-    // Handle the case where someone wants to make the internal field public
-    (@type         [$type:ident]
-     @max          [$max:expr]
-     @debug_format [$debug_format:tt]
-                   pub idx
-                   $($tokens:tt)*) => (
-        newtype_index!(
-            @pub          [pub]
-            @type         [$type]
-            @max          [$max]
-            @debug_format [$debug_format]
-                          $($tokens)*);
-    );
-
-    // The default case is that the internal field is private
-    (@type         [$type:ident]
-     @max          [$max:expr]
-     @debug_format [$debug_format:tt]
-                   $($tokens:tt)*) => (
-        newtype_index!(
-            @pub          []
-            @type         [$type]
-            @max          [$max]
-            @debug_format [$debug_format]
-                          $($tokens)*);
-    );
-
     // Append comma to end of derives list if it's missing
-    (@pub          [$($pub:tt)*]
-     @type         [$type:ident]
+    (@type         [$type:ident]
      @max          [$max:expr]
+     @vis          [$v:vis]
      @debug_format [$debug_format:tt]
                    derive [$($derives:ident),*]
                    $($tokens:tt)*) => (
         newtype_index!(
-            @pub          [$($pub)*]
             @type         [$type]
             @max          [$max]
+            @vis          [$v]
             @debug_format [$debug_format]
                           derive [$($derives,)*]
                           $($tokens)*);
@@ -212,154 +300,154 @@ macro_rules! newtype_index {
 
     // By not including the @derives marker in this list nor in the default args, we can force it
     // to come first if it exists. When encodable is custom, just use the derives list as-is.
-    (@pub          [$($pub:tt)*]
-     @type         [$type:ident]
+    (@type         [$type:ident]
      @max          [$max:expr]
+     @vis          [$v:vis]
      @debug_format [$debug_format:tt]
                    derive [$($derives:ident,)+]
                    ENCODABLE = custom
                    $($tokens:tt)*) => (
         newtype_index!(
             @derives      [$($derives,)+]
-            @pub          [$($pub)*]
             @type         [$type]
             @max          [$max]
+            @vis          [$v]
             @debug_format [$debug_format]
                           $($tokens)*);
     );
 
     // By not including the @derives marker in this list nor in the default args, we can force it
     // to come first if it exists. When encodable isn't custom, add serialization traits by default.
-    (@pub          [$($pub:tt)*]
-     @type         [$type:ident]
+    (@type         [$type:ident]
      @max          [$max:expr]
+     @vis          [$v:vis]
      @debug_format [$debug_format:tt]
                    derive [$($derives:ident,)+]
                    $($tokens:tt)*) => (
         newtype_index!(
             @derives      [$($derives,)+ RustcDecodable, RustcEncodable,]
-            @pub          [$($pub)*]
             @type         [$type]
             @max          [$max]
+            @vis          [$v]
             @debug_format [$debug_format]
                           $($tokens)*);
     );
 
     // The case where no derives are added, but encodable is overridden. Don't
     // derive serialization traits
-    (@pub          [$($pub:tt)*]
-     @type         [$type:ident]
+    (@type         [$type:ident]
      @max          [$max:expr]
+     @vis          [$v:vis]
      @debug_format [$debug_format:tt]
                    ENCODABLE = custom
                    $($tokens:tt)*) => (
         newtype_index!(
             @derives      []
-            @pub          [$($pub)*]
             @type         [$type]
             @max          [$max]
+            @vis          [$v]
             @debug_format [$debug_format]
                           $($tokens)*);
     );
 
     // The case where no derives are added, add serialization derives by default
-    (@pub          [$($pub:tt)*]
-     @type         [$type:ident]
+    (@type         [$type:ident]
      @max          [$max:expr]
+     @vis          [$v:vis]
      @debug_format [$debug_format:tt]
                    $($tokens:tt)*) => (
         newtype_index!(
             @derives      [RustcDecodable, RustcEncodable,]
-            @pub          [$($pub)*]
             @type         [$type]
             @max          [$max]
+            @vis          [$v]
             @debug_format [$debug_format]
                           $($tokens)*);
     );
 
     // Rewrite final without comma to one that includes comma
     (@derives      [$($derives:ident,)*]
-     @pub          [$($pub:tt)*]
      @type         [$type:ident]
      @max          [$max:expr]
+     @vis          [$v:vis]
      @debug_format [$debug_format:tt]
                    $name:ident = $constant:expr) => (
         newtype_index!(
             @derives      [$($derives,)*]
-            @pub          [$($pub)*]
             @type         [$type]
             @max          [$max]
+            @vis          [$v]
             @debug_format [$debug_format]
                           $name = $constant,);
     );
 
     // Rewrite final const without comma to one that includes comma
     (@derives      [$($derives:ident,)*]
-     @pub          [$($pub:tt)*]
      @type         [$type:ident]
      @max          [$_max:expr]
+     @vis          [$v:vis]
      @debug_format [$debug_format:tt]
                    $(#[doc = $doc:expr])*
                    const $name:ident = $constant:expr) => (
         newtype_index!(
             @derives      [$($derives,)*]
-            @pub          [$($pub)*]
             @type         [$type]
             @max          [$max]
+            @vis          [$v]
             @debug_format [$debug_format]
                           $(#[doc = $doc])* const $name = $constant,);
     );
 
     // Replace existing default for max
     (@derives      [$($derives:ident,)*]
-     @pub          [$($pub:tt)*]
      @type         [$type:ident]
      @max          [$_max:expr]
+     @vis          [$v:vis]
      @debug_format [$debug_format:tt]
                    MAX = $max:expr,
                    $($tokens:tt)*) => (
         newtype_index!(
             @derives      [$($derives,)*]
-            @pub          [$($pub)*]
             @type         [$type]
             @max          [$max]
+            @vis          [$v]
             @debug_format [$debug_format]
                           $($tokens)*);
     );
 
     // Replace existing default for debug_format
     (@derives      [$($derives:ident,)*]
-     @pub          [$($pub:tt)*]
      @type         [$type:ident]
      @max          [$max:expr]
+     @vis          [$v:vis]
      @debug_format [$_debug_format:tt]
                    DEBUG_FORMAT = $debug_format:tt,
                    $($tokens:tt)*) => (
         newtype_index!(
             @derives      [$($derives,)*]
-            @pub          [$($pub)*]
             @type         [$type]
             @max          [$max]
+            @vis          [$v]
             @debug_format [$debug_format]
                           $($tokens)*);
     );
 
     // Assign a user-defined constant
     (@derives      [$($derives:ident,)*]
-     @pub          [$($pub:tt)*]
      @type         [$type:ident]
      @max          [$max:expr]
+     @vis          [$v:vis]
      @debug_format [$debug_format:tt]
                    $(#[doc = $doc:expr])*
                    const $name:ident = $constant:expr,
                    $($tokens:tt)*) => (
         $(#[doc = $doc])*
-        pub const $name: $type = $type($constant);
+        pub const $name: $type = $type::from_u32_const($constant);
         newtype_index!(
             @derives      [$($derives,)*]
-            @pub          [$($pub)*]
             @type         [$type]
             @max          [$max]
+            @vis          [$v]
             @debug_format [$debug_format]
                           $($tokens)*);
     );
diff --git a/src/librustc_data_structures/stable_hasher.rs b/src/librustc_data_structures/stable_hasher.rs
index c70a0abe8c7..215c44dec69 100644
--- a/src/librustc_data_structures/stable_hasher.rs
+++ b/src/librustc_data_structures/stable_hasher.rs
@@ -217,6 +217,14 @@ impl_stable_hash_via_hash!(i128);
 impl_stable_hash_via_hash!(char);
 impl_stable_hash_via_hash!(());
 
+impl<CTX> HashStable<CTX> for ::std::num::NonZeroU32 {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          ctx: &mut CTX,
+                                          hasher: &mut StableHasher<W>) {
+        self.get().hash_stable(ctx, hasher)
+    }
+}
+
 impl<CTX> HashStable<CTX> for f32 {
     fn hash_stable<W: StableHasherResult>(&self,
                                           ctx: &mut CTX,
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index 175422975e0..57c00f252ef 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -183,8 +183,13 @@ fn test_env_with_pool<F>(
     });
 }
 
-const D1: ty::DebruijnIndex = ty::INNERMOST;
-const D2: ty::DebruijnIndex = D1.shifted_in(1);
+fn d1() -> ty::DebruijnIndex {
+    ty::INNERMOST
+}
+
+fn d2() -> ty::DebruijnIndex {
+    d1().shifted_in(1)
+}
 
 impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
     pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
@@ -337,7 +342,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
     }
 
     pub fn t_rptr_late_bound(&self, id: u32) -> Ty<'tcx> {
-        let r = self.re_late_bound_with_debruijn(id, D1);
+        let r = self.re_late_bound_with_debruijn(id, d1());
         self.infcx.tcx.mk_imm_ref(r, self.tcx().types.isize)
     }
 
@@ -494,7 +499,7 @@ fn subst_ty_renumber_bound() {
 
         // t_expected = fn(&'a isize)
         let t_expected = {
-            let t_ptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, D2);
+            let t_ptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, d2());
             env.t_fn(&[t_ptr_bound2], env.t_nil())
         };
 
@@ -531,7 +536,7 @@ fn subst_ty_renumber_some_bounds() {
         //
         // but not that the Debruijn index is different in the different cases.
         let t_expected = {
-            let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, D2);
+            let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, d2());
             env.t_pair(t_rptr_bound1, env.t_fn(&[t_rptr_bound2], env.t_nil()))
         };
 
@@ -559,10 +564,10 @@ fn escaping() {
         let t_rptr_free1 = env.t_rptr_free(1);
         assert!(!t_rptr_free1.has_escaping_regions());
 
-        let t_rptr_bound1 = env.t_rptr_late_bound_with_debruijn(1, D1);
+        let t_rptr_bound1 = env.t_rptr_late_bound_with_debruijn(1, d1());
         assert!(t_rptr_bound1.has_escaping_regions());
 
-        let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, D2);
+        let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, d2());
         assert!(t_rptr_bound2.has_escaping_regions());
 
         // t_fn = fn(A)
@@ -578,7 +583,7 @@ fn escaping() {
 #[test]
 fn subst_region_renumber_region() {
     test_env(EMPTY_SOURCE_STR, errors(&[]), |env| {
-        let re_bound1 = env.re_late_bound_with_debruijn(1, D1);
+        let re_bound1 = env.re_late_bound_with_debruijn(1, d1());
 
         // type t_source<'a> = fn(&'a isize)
         let t_source = {
@@ -593,7 +598,7 @@ fn subst_region_renumber_region() {
         //
         // but not that the Debruijn index is different in the different cases.
         let t_expected = {
-            let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, D2);
+            let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, d2());
             env.t_fn(&[t_rptr_bound2], env.t_nil())
         };
 
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 5aa05270a2a..87a32b5a53e 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -173,6 +173,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     is_panic_runtime => { cdata.root.panic_runtime }
     is_compiler_builtins => { cdata.root.compiler_builtins }
     has_global_allocator => { cdata.root.has_global_allocator }
+    has_panic_handler => { cdata.root.has_panic_handler }
     is_sanitizer_runtime => { cdata.root.sanitizer_runtime }
     is_profiler_runtime => { cdata.root.profiler_runtime }
     panic_strategy => { cdata.root.panic_strategy }
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 0fd43c592c8..aae45c17c67 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -484,6 +484,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
         let has_default_lib_allocator = attr::contains_name(&attrs, "default_lib_allocator");
         let has_global_allocator = *tcx.sess.has_global_allocator.get();
+        let has_panic_handler = *tcx.sess.has_panic_handler.try_get().unwrap_or(&false);
 
         let root = self.lazy(&CrateRoot {
             name: tcx.crate_name(LOCAL_CRATE),
@@ -494,6 +495,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             panic_strategy: tcx.sess.panic_strategy(),
             edition: hygiene::default_edition(),
             has_global_allocator: has_global_allocator,
+            has_panic_handler: has_panic_handler,
             has_default_lib_allocator: has_default_lib_allocator,
             plugin_registrar_fn: tcx.sess
                 .plugin_registrar_fn
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 8e454ddc0ad..ab22a8e4db9 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -193,6 +193,7 @@ pub struct CrateRoot {
     pub panic_strategy: PanicStrategy,
     pub edition: Edition,
     pub has_global_allocator: bool,
+    pub has_panic_handler: bool,
     pub has_default_lib_allocator: bool,
     pub plugin_registrar_fn: Option<DefIndex>,
     pub macro_derive_registrar: Option<DefIndex>,
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index a0b0aabf73e..3f8cd03660c 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -16,7 +16,6 @@ use rustc::mir::{LocalDecl, LocalKind, Location, Operand, Place};
 use rustc::mir::{ProjectionElem, Rvalue, Statement, StatementKind};
 use rustc::ty;
 use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::DiagnosticBuilder;
 use syntax_pos::Span;
diff --git a/src/librustc_mir/borrow_check/location.rs b/src/librustc_mir/borrow_check/location.rs
index 28da1b2d733..91008e8f969 100644
--- a/src/librustc_mir/borrow_check/location.rs
+++ b/src/librustc_mir/borrow_check/location.rs
@@ -27,7 +27,11 @@ crate struct LocationTable {
     statements_before_block: IndexVec<BasicBlock, usize>,
 }
 
-newtype_index!(LocationIndex { DEBUG_FORMAT = "LocationIndex({})" });
+newtype_index! {
+    pub struct LocationIndex {
+        DEBUG_FORMAT = "LocationIndex({})"
+    }
+}
 
 #[derive(Copy, Clone, Debug)]
 crate enum RichLocation {
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 272f5024f9f..5050b5ab2b4 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -1605,10 +1605,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         place_span: (&Place<'tcx>, Span),
         flow_state: &Flows<'cx, 'gcx, 'tcx>,
     ) {
-        // FIXME: analogous code in check_loans first maps `place` to
-        // its base_path ... but is that what we want here?
-        let place = self.base_path(place_span.0);
-
         let maybe_uninits = &flow_state.uninits;
 
         // Bad scenarios:
@@ -1646,8 +1642,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         //
         // This code covers scenarios 1, 2, and 3.
 
-        debug!("check_if_full_path_is_moved place: {:?}", place);
-        match self.move_path_closest_to(place) {
+        debug!("check_if_full_path_is_moved place: {:?}", place_span.0);
+        match self.move_path_closest_to(place_span.0) {
             Ok(mpi) => {
                 if maybe_uninits.contains(&mpi) {
                     self.report_use_of_moved_or_uninitialized(
@@ -1677,10 +1673,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         place_span: (&Place<'tcx>, Span),
         flow_state: &Flows<'cx, 'gcx, 'tcx>,
     ) {
-        // FIXME: analogous code in check_loans first maps `place` to
-        // its base_path ... but is that what we want here?
-        let place = self.base_path(place_span.0);
-
         let maybe_uninits = &flow_state.uninits;
 
         // Bad scenarios:
@@ -1709,8 +1701,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         //
         // This code covers scenario 1.
 
-        debug!("check_if_path_or_subpath_is_moved place: {:?}", place);
-        if let Some(mpi) = self.move_path_for_place(place) {
+        debug!("check_if_path_or_subpath_is_moved place: {:?}", place_span.0);
+        if let Some(mpi) = self.move_path_for_place(place_span.0) {
             if let Some(child_mpi) = maybe_uninits.has_any_child_of(mpi) {
                 self.report_use_of_moved_or_uninitialized(
                     context,
@@ -1813,11 +1805,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                             let tcx = self.tcx;
                             match base.ty(self.mir, tcx).to_ty(tcx).sty {
                                 ty::Adt(def, _) if def.has_dtor(tcx) => {
-
-                                    // FIXME: analogous code in
-                                    // check_loans.rs first maps
-                                    // `base` to its base_path.
-
                                     self.check_if_path_or_subpath_is_moved(
                                         context, InitializationRequiringAction::Assignment,
                                         (base, span), flow_state);
@@ -2190,35 +2177,6 @@ enum Overlap {
     Disjoint,
 }
 
-impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
-    // FIXME (#16118): function intended to allow the borrow checker
-    // to be less precise in its handling of Box while still allowing
-    // moves out of a Box. They should be removed when/if we stop
-    // treating Box specially (e.g. when/if DerefMove is added...)
-
-    fn base_path<'d>(&self, place: &'d Place<'tcx>) -> &'d Place<'tcx> {
-        //! Returns the base of the leftmost (deepest) dereference of an
-        //! Box in `place`. If there is no dereference of an Box
-        //! in `place`, then it just returns `place` itself.
-
-        let mut cursor = place;
-        let mut deepest = place;
-        loop {
-            let proj = match *cursor {
-                Place::Promoted(_) |
-                Place::Local(..) | Place::Static(..) => return deepest,
-                Place::Projection(ref proj) => proj,
-            };
-            if proj.elem == ProjectionElem::Deref
-                && place.ty(self.mir, self.tcx).to_ty(self.tcx).is_box()
-            {
-                deepest = &proj.base;
-            }
-            cursor = &proj.base;
-        }
-    }
-}
-
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 struct Context {
     kind: ContextKind,
diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs
index 497e8e07853..290c7032388 100644
--- a/src/librustc_mir/borrow_check/move_errors.rs
+++ b/src/librustc_mir/borrow_check/move_errors.rs
@@ -12,7 +12,6 @@ use core::unicode::property::Pattern_White_Space;
 use rustc::mir::*;
 use rustc::ty;
 use rustc_errors::DiagnosticBuilder;
-use rustc_data_structures::indexed_vec::Idx;
 use syntax_pos::Span;
 
 use borrow_check::MirBorrowckCtxt;
diff --git a/src/librustc_mir/borrow_check/nll/constraints/mod.rs b/src/librustc_mir/borrow_check/nll/constraints/mod.rs
index 9a8b0f391de..41c846509cd 100644
--- a/src/librustc_mir/borrow_check/nll/constraints/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/constraints/mod.rs
@@ -99,6 +99,14 @@ impl fmt::Debug for OutlivesConstraint {
     }
 }
 
-newtype_index!(ConstraintIndex { DEBUG_FORMAT = "ConstraintIndex({})" });
+newtype_index! {
+    pub struct ConstraintIndex {
+        DEBUG_FORMAT = "ConstraintIndex({})"
+    }
+}
 
-newtype_index!(ConstraintSccIndex { DEBUG_FORMAT = "ConstraintSccIndex({})" });
+newtype_index! {
+    pub struct ConstraintSccIndex {
+        DEBUG_FORMAT = "ConstraintSccIndex({})"
+    }
+}
diff --git a/src/librustc_mir/borrow_check/nll/facts.rs b/src/librustc_mir/borrow_check/nll/facts.rs
index 8eb052f88e1..465707ecc17 100644
--- a/src/librustc_mir/borrow_check/nll/facts.rs
+++ b/src/librustc_mir/borrow_check/nll/facts.rs
@@ -100,18 +100,6 @@ impl Atom for LocationIndex {
     }
 }
 
-impl From<usize> for LocationIndex {
-    fn from(i: usize) -> LocationIndex {
-        LocationIndex::new(i)
-    }
-}
-
-impl From<LocationIndex> for usize {
-    fn from(vid: LocationIndex) -> usize {
-        Idx::index(vid)
-    }
-}
-
 struct FactWriter<'w> {
     location_table: &'w LocationTable,
     dir: &'w Path,
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs b/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
index dd508084d7d..34e893d2a59 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
@@ -15,7 +15,6 @@
 use super::*;
 use borrow_check::nll::constraints::OutlivesConstraint;
 use dot::{self, IntoCow};
-use rustc_data_structures::indexed_vec::Idx;
 use std::borrow::Cow;
 use std::io::{self, Write};
 
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs
index ae5d5790673..3dafab2f5a9 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs
@@ -123,13 +123,17 @@ impl RegionValueElements {
 
 /// A single integer representing a `Location` in the MIR control-flow
 /// graph. Constructed efficiently from `RegionValueElements`.
-newtype_index!(PointIndex { DEBUG_FORMAT = "PointIndex({})" });
+newtype_index! {
+    pub struct PointIndex { DEBUG_FORMAT = "PointIndex({})" }
+}
 
 /// A single integer representing a (non-zero) `UniverseIndex`.
 /// Computed just by subtracting one from `UniverseIndex`; this is
 /// because the `0` value for `UniverseIndex` represents the root
 /// universe, and we don't need/want a bit for that one.
-newtype_index!(PlaceholderIndex { DEBUG_FORMAT = "PlaceholderIndex({})" });
+newtype_index! {
+    pub struct PlaceholderIndex { DEBUG_FORMAT = "PlaceholderIndex({})" }
+}
 
 /// An individual element in a region value -- the value of a
 /// particular region variable consists of a set of these elements.
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs
index 15affbbc27a..467554dc38a 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/liveness_map.rs
@@ -97,6 +97,6 @@ impl NllLivenessMap {
 /// compute liveness information. For many locals, we are able to
 /// skip liveness information: for example, those variables whose
 /// types contain no regions.
-newtype_index!(
-    LiveVar
-);
+newtype_index! {
+    pub struct LiveVar { .. }
+}
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
index 73d285c2f2e..4b39d58cd96 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
@@ -48,7 +48,9 @@ struct Appearance {
     next: Option<AppearanceIndex>,
 }
 
-newtype_index!(AppearanceIndex);
+newtype_index! {
+    pub struct AppearanceIndex { .. }
+}
 
 impl vll::LinkElem for Appearance {
     type LinkIndex = AppearanceIndex;
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 61c99832448..82158acc9e6 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -42,7 +42,6 @@ use syntax_pos::{Span, DUMMY_SP};
 use transform::{MirPass, MirSource};
 
 use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::indexed_vec::Idx;
 
 macro_rules! span_mirbug {
     ($context:expr, $elem:expr, $($message:tt)*) => ({
diff --git a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
index deb972ee046..8ffce9c9492 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
@@ -20,7 +20,7 @@ use rustc::ty::relate::{self, Relate, RelateResult, TypeRelation};
 use rustc::ty::subst::Kind;
 use rustc::ty::{self, CanonicalTy, CanonicalVar, RegionVid, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::indexed_vec::{Idx, IndexVec};
+use rustc_data_structures::indexed_vec::IndexVec;
 use std::mem;
 
 pub(super) fn sub_types<'tcx>(
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index f178ea8bdba..322a6977bed 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -402,7 +402,9 @@ struct CFG<'tcx> {
     basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
 }
 
-newtype_index!(ScopeId);
+newtype_index! {
+    pub struct ScopeId { .. }
+}
 
 ///////////////////////////////////////////////////////////////////////////
 /// The `BlockAnd` "monad" packages up the new basic block along with a
diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index 8e99a45c87f..38e0854bcd6 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -95,7 +95,6 @@ use rustc::hir;
 use rustc::hir::def_id::LOCAL_CRATE;
 use rustc::mir::*;
 use syntax_pos::{Span};
-use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::fx::FxHashMap;
 
 #[derive(Debug)]
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 92ddd8777f7..154830c2e77 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -19,7 +19,7 @@ use rustc::mir;
 use rustc::ty::{self, TyCtxt, Instance, query::TyCtxtAt};
 use rustc::ty::layout::{LayoutOf, TyLayout};
 use rustc::ty::subst::Subst;
-use rustc_data_structures::indexed_vec::{IndexVec, Idx};
+use rustc_data_structures::indexed_vec::IndexVec;
 
 use syntax::ast::Mutability;
 use syntax::source_map::Span;
diff --git a/src/librustc_mir/dataflow/at_location.rs b/src/librustc_mir/dataflow/at_location.rs
index d97c0c9b430..1dc91cd05b3 100644
--- a/src/librustc_mir/dataflow/at_location.rs
+++ b/src/librustc_mir/dataflow/at_location.rs
@@ -13,7 +13,6 @@
 
 use rustc::mir::{BasicBlock, Location};
 use rustc_data_structures::indexed_set::{HybridIdxSet, IdxSet, Iter};
-use rustc_data_structures::indexed_vec::Idx;
 
 use dataflow::{BitDenotation, BlockSets, DataflowResults};
 use dataflow::move_paths::{HasMoveData, MovePathIndex};
diff --git a/src/librustc_mir/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs
index 1d35bb85a21..2b5d26c7487 100644
--- a/src/librustc_mir/dataflow/graphviz.rs
+++ b/src/librustc_mir/dataflow/graphviz.rs
@@ -13,7 +13,6 @@
 use syntax::ast::NodeId;
 use rustc::mir::{BasicBlock, Mir};
 use rustc_data_structures::bitslice::bits_to_string;
-use rustc_data_structures::indexed_vec::Idx;
 
 use dot;
 use dot::IntoCow;
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index cb551df9106..995e70fb382 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -21,7 +21,7 @@ use rustc::ty::{RegionKind, RegionVid};
 use rustc::ty::RegionKind::ReScope;
 
 use rustc_data_structures::bitslice::{BitwiseOperator, Word};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_set::IdxSet;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::sync::Lrc;
@@ -53,6 +53,13 @@ pub struct Borrows<'a, 'gcx: 'tcx, 'tcx: 'a> {
     _nonlexical_regioncx: Rc<RegionInferenceContext<'tcx>>,
 }
 
+struct StackEntry {
+    bb: mir::BasicBlock,
+    lo: usize,
+    hi: usize,
+    first_part_only: bool
+}
+
 fn precompute_borrows_out_of_scope<'tcx>(
     mir: &Mir<'tcx>,
     regioncx: &Rc<RegionInferenceContext<'tcx>>,
@@ -61,48 +68,79 @@ fn precompute_borrows_out_of_scope<'tcx>(
     borrow_region: RegionVid,
     location: Location,
 ) {
-    // Keep track of places we've locations to check and locations that we have checked.
-    let mut stack = vec![ location ];
-    let mut visited = FxHashSet();
-    visited.insert(location);
-
-    debug!(
-        "borrow {:?} has region {:?} with value {:?}",
-        borrow_index,
-        borrow_region,
-        regioncx.region_value_str(borrow_region),
-    );
-    debug!("borrow {:?} starts at {:?}", borrow_index, location);
-    while let Some(location) = stack.pop() {
-        // If region does not contain a point at the location, then add to list and skip
-        // successor locations.
-        if !regioncx.region_contains(borrow_region, location) {
-            debug!("borrow {:?} gets killed at {:?}", borrow_index, location);
-            borrows_out_of_scope_at_location
-                .entry(location)
-                .or_default()
-                .push(borrow_index);
-            continue;
+    // We visit one BB at a time. The complication is that we may start in the
+    // middle of the first BB visited (the one containing `location`), in which
+    // case we may have to later on process the first part of that BB if there
+    // is a path back to its start.
+
+    // For visited BBs, we record the index of the first statement processed.
+    // (In fully processed BBs this index is 0.) Note also that we add BBs to
+    // `visited` once they are added to `stack`, before they are actually
+    // processed, because this avoids the need to look them up again on
+    // completion.
+    let mut visited = FxHashMap();
+    visited.insert(location.block, location.statement_index);
+
+    let mut stack = vec![];
+    stack.push(StackEntry {
+        bb: location.block,
+        lo: location.statement_index,
+        hi: mir[location.block].statements.len(),
+        first_part_only: false,
+    });
+
+    while let Some(StackEntry { bb, lo, hi, first_part_only }) = stack.pop() {
+        let mut finished_early = first_part_only;
+        for i in lo ..= hi {
+            let location = Location { block: bb, statement_index: i };
+            // If region does not contain a point at the location, then add to list and skip
+            // successor locations.
+            if !regioncx.region_contains(borrow_region, location) {
+                debug!("borrow {:?} gets killed at {:?}", borrow_index, location);
+                borrows_out_of_scope_at_location
+                    .entry(location)
+                    .or_default()
+                    .push(borrow_index);
+                finished_early = true;
+                break;
+            }
         }
 
-        let bb_data = &mir[location.block];
-        // If this is the last statement in the block, then add the
-        // terminator successors next.
-        if location.statement_index == bb_data.statements.len() {
-            // Add successors to locations to visit, if not visited before.
-            if let Some(ref terminator) = bb_data.terminator {
-                for block in terminator.successors() {
-                    let loc = block.start_location();
-                    if visited.insert(loc) {
-                        stack.push(loc);
-                    }
-                }
-            }
-        } else {
-            // Visit next statement in block.
-            let loc = location.successor_within_block();
-            if visited.insert(loc) {
-                stack.push(loc);
+        if !finished_early {
+            // Add successor BBs to the work list, if necessary.
+            let bb_data = &mir[bb];
+            assert!(hi == bb_data.statements.len());
+            for &succ_bb in bb_data.terminator.as_ref().unwrap().successors() {
+                visited.entry(succ_bb)
+                    .and_modify(|lo| {
+                        // `succ_bb` has been seen before. If it wasn't
+                        // fully processed, add its first part to `stack`
+                        // for processing.
+                        if *lo > 0 {
+                            stack.push(StackEntry {
+                                bb: succ_bb,
+                                lo: 0,
+                                hi: *lo - 1,
+                                first_part_only: true,
+                            });
+                        }
+                        // And update this entry with 0, to represent the
+                        // whole BB being processed.
+                        *lo = 0;
+                    })
+                    .or_insert_with(|| {
+                        // succ_bb hasn't been seen before. Add it to
+                        // `stack` for processing.
+                        stack.push(StackEntry {
+                            bb: succ_bb,
+                            lo: 0,
+                            hi: mir[succ_bb].statements.len(),
+                            first_part_only: false,
+                        });
+                        // Insert 0 for this BB, to represent the whole BB
+                        // being processed.
+                        0
+                    });
             }
         }
     }
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 4093a6304b3..461285ff9bc 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -16,7 +16,7 @@ use std::convert::TryInto;
 
 use rustc::{mir, ty};
 use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt};
-use rustc_data_structures::indexed_vec::Idx;
+
 use rustc::mir::interpret::{
     GlobalId, AllocId,
     ConstValue, Pointer, Scalar, ScalarMaybeUndef,
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 51a42944527..d01593ca5e9 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -18,7 +18,6 @@ use rustc::ich::StableHashingContext;
 use rustc::mir;
 use rustc::ty::{self, Ty};
 use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout};
-use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult};
 
 use rustc::mir::interpret::{
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index be04f75c726..d4024981c37 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -24,6 +24,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 #![feature(box_syntax)]
 #![feature(crate_visibility_modifier)]
 #![feature(core_intrinsics)]
+#![feature(const_fn)]
 #![feature(decl_macro)]
 #![cfg_attr(stage0, feature(macro_vis_matcher))]
 #![feature(exhaustive_patterns)]
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index e2b1a255eac..4d19e9dfbf9 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -26,7 +26,7 @@ use interpret::{self, Value, OpTy, MemoryKind};
 use transform::{MirPass, MirSource};
 use syntax::source_map::{Span, DUMMY_SP};
 use rustc::ty::subst::Substs;
-use rustc_data_structures::indexed_vec::{IndexVec, Idx};
+use rustc_data_structures::indexed_vec::IndexVec;
 use rustc::ty::ParamEnv;
 use rustc::ty::layout::{
     LayoutOf, TyLayout, LayoutError,
@@ -133,7 +133,6 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
         self.ecx.tcx.span = source_info.span;
         let lint_root = match self.mir.source_scope_local_data {
             ClearCrossCrate::Set(ref ivs) => {
-                use rustc_data_structures::indexed_vec::Idx;
                 //FIXME(#51314): remove this check
                 if source_info.scope.index() >= ivs.len() {
                     return None;
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index 225de03a329..bf538112e41 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -19,7 +19,6 @@ use rustc::ty::{self, TyCtxt};
 use rustc::mir::*;
 use rustc::util::nodemap::FxHashMap;
 use rustc_data_structures::indexed_set::IdxSet;
-use rustc_data_structures::indexed_vec::Idx;
 use transform::{MirPass, MirSource};
 use util::patch::MirPatch;
 use util::elaborate_drops::{DropFlagState, Unwind, elaborate_drop};
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 050901b9b50..81fc235c233 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -16,7 +16,7 @@
 
 use rustc_data_structures::bitvec::BitArray;
 use rustc_data_structures::indexed_set::IdxSet;
-use rustc_data_structures::indexed_vec::{IndexVec, Idx};
+use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::fx::FxHashSet;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index eda7de0fd79..9faaeea3f5b 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -15,7 +15,6 @@ use syntax_pos::Span;
 use rustc::ty::{self, TyCtxt};
 use rustc::mir::{self, Mir, Location};
 use rustc_data_structures::indexed_set::IdxSet;
-use rustc_data_structures::indexed_vec::Idx;
 use transform::{MirPass, MirSource};
 
 use dataflow::{do_dataflow, DebugFormatted};
diff --git a/src/librustc_mir/util/graphviz.rs b/src/librustc_mir/util/graphviz.rs
index 22e2b1b0b09..0b883f68bff 100644
--- a/src/librustc_mir/util/graphviz.rs
+++ b/src/librustc_mir/util/graphviz.rs
@@ -15,8 +15,6 @@ use rustc::ty::TyCtxt;
 use std::fmt::Debug;
 use std::io::{self, Write};
 
-use rustc_data_structures::indexed_vec::Idx;
-
 use super::pretty::dump_mir_def_ids;
 
 /// Write a graphviz DOT graph of a list of MIRs.
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 73c9af0d11c..a72ee7ae379 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -1147,7 +1147,15 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
                 None => continue,
             };
 
-            if binding.is_import() || binding.is_macro_def() {
+            // Don't reexport `uniform_path` canaries.
+            let non_canary_import = match binding.kind {
+                NameBindingKind::Import { directive, .. } => {
+                    !directive.is_uniform_paths_canary
+                }
+                _ => false,
+            };
+
+            if non_canary_import || binding.is_macro_def() {
                 let def = binding.def();
                 if def != Def::Err {
                     if !def.def_id().is_local() {
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 804aad3c0ec..65dd71de144 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -25,10 +25,11 @@ use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
 use rustc::ty::{GenericParamDef, GenericParamDefKind};
 use rustc::ty::wf::object_region_bounds;
 use rustc_target::spec::abi;
+use std::collections::BTreeSet;
 use std::slice;
 use require_c_abi_if_variadic;
 use util::common::ErrorReported;
-use util::nodemap::{FxHashSet, FxHashMap};
+use util::nodemap::FxHashMap;
 use errors::{FatalError, DiagnosticId};
 use lint;
 
@@ -996,7 +997,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
             return tcx.types.err;
         }
 
-        let mut associated_types = FxHashSet::default();
+        // use a btreeset to keep output in a more consistent order
+        let mut associated_types = BTreeSet::default();
+
         for tr in traits::supertraits(tcx, principal) {
             associated_types.extend(tcx.associated_items(tr.def_id())
                 .filter(|item| item.kind == ty::AssociatedKind::Type)
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index a45e5c8ec2a..a1e4c85f821 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1138,6 +1138,11 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
     if let Some(panic_impl_did) = fcx.tcx.lang_items().panic_impl() {
         if panic_impl_did == fcx.tcx.hir.local_def_id(fn_id) {
             if let Some(panic_info_did) = fcx.tcx.lang_items().panic_info() {
+                // at this point we don't care if there are duplicate handlers or if the handler has
+                // the wrong signature as this value we'll be used when writing metadata and that
+                // only happens if compilation succeeded
+                fcx.tcx.sess.has_panic_handler.try_set_same(true);
+
                 if declared_ret_ty.sty != ty::Never {
                     fcx.tcx.sess.span_err(
                         decl.output.span(),
diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs
index fa152b386a8..5967bd1ba3e 100644
--- a/src/librustc_typeck/check_unused.rs
+++ b/src/librustc_typeck/check_unused.rs
@@ -117,6 +117,7 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) {
             !tcx.is_compiler_builtins(cnum)
                 && !tcx.is_panic_runtime(cnum)
                 && !tcx.has_global_allocator(cnum)
+                && !tcx.has_panic_handler(cnum)
         })
         .cloned()
         .collect();
diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs
index 60bb5a0fec2..416be50bfe9 100644
--- a/src/libserialize/serialize.rs
+++ b/src/libserialize/serialize.rs
@@ -361,6 +361,18 @@ impl Decodable for u32 {
     }
 }
 
+impl Encodable for ::std::num::NonZeroU32 {
+    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+        s.emit_u32(self.get())
+    }
+}
+
+impl Decodable for ::std::num::NonZeroU32 {
+    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
+        d.read_u32().map(|d| ::std::num::NonZeroU32::new(d).unwrap())
+    }
+}
+
 impl Encodable for u64 {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         s.emit_u64(*self)
@@ -895,3 +907,4 @@ impl<T: UseSpecializedDecodable> Decodable for T {
 impl<'a, T: ?Sized + Encodable> UseSpecializedEncodable for &'a T {}
 impl<T: ?Sized + Encodable> UseSpecializedEncodable for Box<T> {}
 impl<T: Decodable> UseSpecializedDecodable for Box<T> {}
+
diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs
index 12e14734ff5..db2ea6b660a 100644
--- a/src/libstd/sys/unix/fd.rs
+++ b/src/libstd/sys/unix/fd.rs
@@ -11,7 +11,7 @@
 #![unstable(reason = "not public", issue = "0", feature = "fd")]
 
 use cmp;
-use io::{self, Read};
+use io::{self, Read, Initializer};
 use libc::{self, c_int, c_void, ssize_t};
 use mem;
 use sync::atomic::{AtomicBool, Ordering};
@@ -270,6 +270,11 @@ impl<'a> Read for &'a FileDesc {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         (**self).read(buf)
     }
+
+    #[inline]
+    unsafe fn initializer(&self) -> Initializer {
+        Initializer::nop()
+    }
 }
 
 impl AsInner<c_int> for FileDesc {
diff --git a/src/test/run-make-fulldeps/issue-53964/Makefile b/src/test/run-make-fulldeps/issue-53964/Makefile
new file mode 100644
index 00000000000..c56beb52fdd
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue-53964/Makefile
@@ -0,0 +1,5 @@
+-include ../tools.mk
+
+all:
+	$(RUSTC) panic.rs
+	$(RUSTC) -C panic=abort --emit=obj app.rs -L $(TMPDIR)
diff --git a/src/test/run-make-fulldeps/issue-53964/app.rs b/src/test/run-make-fulldeps/issue-53964/app.rs
new file mode 100644
index 00000000000..8127b9578bf
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue-53964/app.rs
@@ -0,0 +1,8 @@
+#![crate_type = "bin"]
+#![no_main]
+#![no_std]
+
+#![deny(unused_extern_crates)]
+
+// `panic` provides a `panic_handler` so it shouldn't trip the `unused_extern_crates` lint
+extern crate panic;
diff --git a/src/test/run-make-fulldeps/issue-53964/panic.rs b/src/test/run-make-fulldeps/issue-53964/panic.rs
new file mode 100644
index 00000000000..87c7b218822
--- /dev/null
+++ b/src/test/run-make-fulldeps/issue-53964/panic.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 = "lib"]
+#![feature(panic_handler)]
+#![no_std]
+
+use core::panic::PanicInfo;
+
+#[panic_handler]
+fn panic(_: &PanicInfo) -> ! {
+    loop {}
+}
diff --git a/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs b/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs
new file mode 100644
index 00000000000..5845afd72fb
--- /dev/null
+++ b/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs
@@ -0,0 +1,19 @@
+// 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.
+
+// edition:2018
+
+#![feature(uniform_paths)]
+
+mod m { pub fn f() {} }
+mod n { pub fn g() {} }
+
+pub use m::f;
+pub use n::g;
diff --git a/src/test/run-pass/uniform-paths/issue-53691.rs b/src/test/run-pass/uniform-paths/issue-53691.rs
new file mode 100644
index 00000000000..62be31d6b85
--- /dev/null
+++ b/src/test/run-pass/uniform-paths/issue-53691.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.
+
+// aux-build:issue-53691.rs
+
+extern crate issue_53691;
+
+fn main() {
+    issue_53691::f();
+    issue_53691::g();
+}
diff --git a/src/test/ui/borrowck/borrowck-box-insensitivity.nll.stderr b/src/test/ui/borrowck/borrowck-box-insensitivity.nll.stderr
index 601f05b499c..0e380e90e75 100644
--- a/src/test/ui/borrowck/borrowck-box-insensitivity.nll.stderr
+++ b/src/test/ui/borrowck/borrowck-box-insensitivity.nll.stderr
@@ -1,25 +1,14 @@
-error[E0382]: use of moved value: `a.y`
-  --> $DIR/borrowck-box-insensitivity.rs:46:14
-   |
-LL |     let _x = a.x;
-   |              --- value moved here
-LL |     //~^ value moved here
-LL |     let _y = a.y; //~ ERROR use of moved
-   |              ^^^ value used here after move
-   |
-   = note: move occurs because `a.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
-
-error[E0382]: use of moved value: `a.y`
-  --> $DIR/borrowck-box-insensitivity.rs:108:14
-   |
-LL |     let _x = a.x.x;
-   |              ----- value moved here
-LL |     //~^ value moved here
-LL |     let _y = a.y; //~ ERROR use of collaterally moved
-   |              ^^^ value used here after move
-   |
-   = note: move occurs because `a.x.x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
+error: compilation successful
+  --> $DIR/borrowck-box-insensitivity.rs:160:1
+   |
+LL | / fn main() {
+LL | |     copy_after_move();
+LL | |     move_after_move();
+LL | |     borrow_after_move();
+...  |
+LL | |     mut_borrow_after_borrow_nested();
+LL | | }
+   | |_^
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/borrowck/borrowck-box-insensitivity.rs b/src/test/ui/borrowck/borrowck-box-insensitivity.rs
index 75bf6bce04b..eabb8d7bca3 100644
--- a/src/test/ui/borrowck/borrowck-box-insensitivity.rs
+++ b/src/test/ui/borrowck/borrowck-box-insensitivity.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(box_syntax)]
+#![feature(box_syntax, rustc_attrs)]
 
 struct A {
     x: Box<isize>,
@@ -156,6 +156,7 @@ fn mut_borrow_after_borrow_nested() {
     //~^ mutable borrow occurs here
 }
 
+#[rustc_error]
 fn main() {
     copy_after_move();
     move_after_move();
diff --git a/src/test/ui/removing-extern-crate.rs b/src/test/ui/removing-extern-crate.rs
index 3905d285bec..9762db38a1c 100644
--- a/src/test/ui/removing-extern-crate.rs
+++ b/src/test/ui/removing-extern-crate.rs
@@ -16,12 +16,12 @@
 #![warn(rust_2018_idioms)]
 #![allow(unused_imports)]
 
-extern crate std as foo;
+extern crate removing_extern_crate as foo;
 extern crate core;
 
 mod another {
-    extern crate std as foo;
-    extern crate std;
+    extern crate removing_extern_crate as foo;
+    extern crate core;
 }
 
 fn main() {}
diff --git a/src/test/ui/removing-extern-crate.stderr b/src/test/ui/removing-extern-crate.stderr
index f2eed27a266..758ec67d178 100644
--- a/src/test/ui/removing-extern-crate.stderr
+++ b/src/test/ui/removing-extern-crate.stderr
@@ -1,8 +1,8 @@
 warning: unused extern crate
   --> $DIR/removing-extern-crate.rs:19:1
    |
-LL | extern crate std as foo;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+LL | extern crate removing_extern_crate as foo;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
    |
 note: lint level defined here
   --> $DIR/removing-extern-crate.rs:16:9
@@ -20,12 +20,12 @@ LL | extern crate core;
 warning: unused extern crate
   --> $DIR/removing-extern-crate.rs:23:5
    |
-LL |     extern crate std as foo;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
+LL |     extern crate removing_extern_crate as foo;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
 
 warning: unused extern crate
   --> $DIR/removing-extern-crate.rs:24:5
    |
-LL |     extern crate std;
-   |     ^^^^^^^^^^^^^^^^^ help: remove it
+LL |     extern crate core;
+   |     ^^^^^^^^^^^^^^^^^^ help: remove it