about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-10-18 07:02:11 +0000
committerbors <bors@rust-lang.org>2018-10-18 07:02:11 +0000
commitaf204b1f3e83d77427f5fe78285537378be103ec (patch)
tree9cb6f52d303dfd226216893cb08a28860ffa2301 /src
parentf7eb7fbbf6bca0eaa146c4a48cd39c133a257706 (diff)
parent1c090061e9a7dbe7ce65c34f81b8fd55318adeb0 (diff)
downloadrust-af204b1f3e83d77427f5fe78285537378be103ec.tar.gz
rust-af204b1f3e83d77427f5fe78285537378be103ec.zip
Auto merge of #55171 - kennytm:rollup, r=kennytm
Rollup of 18 pull requests

Successful merges:

 - #54646 (improve documentation on std::thread::sleep)
 - #54933 (Cleanup the rest of codegen_llvm)
 - #54964 (Run both lldb and gdb tests)
 - #55016 (Deduplicate some code and compile-time values around vtables)
 - #55031 (Improve verify_llvm_ir config option)
 - #55050 (doc std::fmt: the Python inspiration is already mentioned in precedin…)
 - #55077 (rustdoc: Use dyn keyword when rendering dynamic traits)
 - #55080 (Detect if access to localStorage is forbidden by the user's browser)
 - #55090 (regression test for move out of borrow via pattern)
 - #55102 (resolve: Do not skip extern prelude during speculative resolution)
 - #55104 (Add test for #34229)
 - #55111 ([Rustc Book] Explain --cfg's arguments)
 - #55122 (Cleanup mir/borrowck)
 - #55127 (Remove HybridBitSet::dummy)
 - #55128 (Fix LLVMRustInlineAsmVerify return type mismatch)
 - #55142 (miri: layout should not affect CTFE checks (outside of validation))
 - #55151 (Cleanup nll)
 - #55161 ([librustdoc] Disable spellcheck for search field)
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/bin/rustc.rs4
-rw-r--r--src/bootstrap/builder.rs4
-rw-r--r--src/bootstrap/compile.rs3
-rw-r--r--src/bootstrap/test.rs20
-rwxr-xr-xsrc/ci/run.sh3
-rw-r--r--src/doc/rustc/src/command-line-arguments.md5
-rw-r--r--src/liballoc/fmt.rs3
-rw-r--r--src/librustc/build.rs7
-rw-r--r--src/librustc/session/mod.rs1
-rw-r--r--src/librustc/ty/query/mod.rs16
-rw-r--r--src/librustc_codegen_llvm/builder.rs2
-rw-r--r--src/librustc_codegen_llvm/debuginfo/create_scope_map.rs2
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs93
-rw-r--r--src/librustc_codegen_llvm/debuginfo/mod.rs18
-rw-r--r--src/librustc_codegen_llvm/debuginfo/source_loc.rs7
-rw-r--r--src/librustc_codegen_llvm/debuginfo/type_names.rs2
-rw-r--r--src/librustc_codegen_llvm/llvm/archive_ro.rs2
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs4
-rw-r--r--src/librustc_codegen_llvm/meth.rs4
-rw-r--r--src/librustc_codegen_llvm/mir/block.rs39
-rw-r--r--src/librustc_codegen_llvm/mir/mod.rs8
-rw-r--r--src/librustc_data_structures/bit_set.rs50
-rw-r--r--src/librustc_mir/borrow_check/borrow_set.rs100
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs341
-rw-r--r--src/librustc_mir/borrow_check/mod.rs26
-rw-r--r--src/librustc_mir/borrow_check/move_errors.rs6
-rw-r--r--src/librustc_mir/borrow_check/mutability_errors.rs7
-rw-r--r--src/librustc_mir/borrow_check/nll/constraint_generation.rs5
-rw-r--r--src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs73
-rw-r--r--src/librustc_mir/borrow_check/nll/invalidation.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs12
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs11
-rw-r--r--src/librustc_mir/interpret/cast.rs7
-rw-r--r--src/librustc_mir/interpret/eval_context.rs5
-rw-r--r--src/librustc_mir/interpret/operand.rs3
-rw-r--r--src/librustc_mir/interpret/traits.rs23
-rw-r--r--src/librustc_resolve/lib.rs12
-rw-r--r--src/librustdoc/html/format.rs3
-rw-r--r--src/librustdoc/html/layout.rs1
-rw-r--r--src/librustdoc/html/static/storage.js22
-rw-r--r--src/libstd/thread/mod.rs24
-rw-r--r--src/test/debuginfo/lexical-scope-with-macro.rs2
-rw-r--r--src/test/run-pass/extern/extern-prelude-no-speculative.rs2
-rw-r--r--src/test/rustdoc/assoc-consts.rs2
-rw-r--r--src/test/rustdoc/inline_cross/issue-32881.rs4
-rw-r--r--src/test/rustdoc/test-parens.rs2
-rw-r--r--src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs22
-rw-r--r--src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr12
-rw-r--r--src/test/ui/impl-trait/auxiliary/extra-item.rs1
-rw-r--r--src/test/ui/impl-trait/extra-item.rs10
-rw-r--r--src/test/ui/impl-trait/extra-item.stderr9
-rw-r--r--src/test/ui/issues/issue-34229.rs4
-rw-r--r--src/test/ui/issues/issue-34229.stderr12
-rw-r--r--src/tools/compiletest/src/common.rs3
-rw-r--r--src/tools/compiletest/src/header.rs157
-rw-r--r--src/tools/compiletest/src/main.rs34
-rw-r--r--src/tools/compiletest/src/runtest.rs29
58 files changed, 740 insertions, 547 deletions
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index b89976eca26..b6764c1aaea 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -287,10 +287,6 @@ fn main() {
         cmd.arg("--cfg").arg("parallel_queries");
     }
 
-    if env::var_os("RUSTC_VERIFY_LLVM_IR").is_some() {
-        cmd.arg("-Z").arg("verify-llvm-ir");
-    }
-
     if env::var_os("RUSTC_DENY_WARNINGS").is_some() && env::var_os("RUSTC_EXTERNAL_TOOL").is_none()
     {
         cmd.arg("-Dwarnings");
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index b842bc43f5b..aa4e44df2ef 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1000,10 +1000,6 @@ impl<'a> Builder<'a> {
             cargo.env("RUSTC_BACKTRACE_ON_ICE", "1");
         }
 
-        if self.config.rust_verify_llvm_ir {
-            cargo.env("RUSTC_VERIFY_LLVM_IR", "1");
-        }
-
         cargo.env("RUSTC_VERBOSE", self.verbosity.to_string());
 
         // in std, we want to avoid denying warnings for stage 0 as that makes cfg's painful.
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 7d235743c2c..69d45acdeda 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -569,6 +569,9 @@ pub fn rustc_cargo_env(builder: &Builder, cargo: &mut Command) {
     if builder.config.rustc_parallel_queries {
         cargo.env("RUSTC_PARALLEL_QUERIES", "1");
     }
+    if builder.config.rust_verify_llvm_ir {
+        cargo.env("RUSTC_VERIFY_LLVM_IR", "1");
+    }
 }
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 633c15b54b9..80c89b9ff38 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -812,8 +812,7 @@ default_test!(Incremental {
 
 default_test!(Debuginfo {
     path: "src/test/debuginfo",
-    // What this runs varies depending on the native platform being apple
-    mode: "debuginfo-XXX",
+    mode: "debuginfo",
     suite: "debuginfo"
 });
 
@@ -950,18 +949,11 @@ impl Step for Compiletest {
                 return;
             }
 
-            if mode == "debuginfo-XXX" {
-                return if builder.config.build.contains("apple") {
-                    builder.ensure(Compiletest {
-                        mode: "debuginfo-lldb",
-                        ..self
-                    });
-                } else {
-                    builder.ensure(Compiletest {
-                        mode: "debuginfo-gdb",
-                        ..self
-                    });
-                };
+            if mode == "debuginfo" {
+                return builder.ensure(Compiletest {
+                    mode: "debuginfo-both",
+                    ..self
+                });
             }
 
             builder.ensure(dist::DebuggerScripts {
diff --git a/src/ci/run.sh b/src/ci/run.sh
index a9e506645f1..42561cf95d3 100755
--- a/src/ci/run.sh
+++ b/src/ci/run.sh
@@ -61,6 +61,7 @@ if [ "$DEPLOY$DEPLOY_ALT" != "" ]; then
     RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-llvm-assertions"
   elif [ "$DEPLOY_ALT" != "" ]; then
     RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-assertions"
+    RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir"
   fi
 else
   # We almost always want debug assertions enabled, but sometimes this takes too
@@ -74,6 +75,8 @@ else
   if [ "$NO_LLVM_ASSERTIONS" = "" ]; then
     RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-llvm-assertions"
   fi
+
+  RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.verify-llvm-ir"
 fi
 
 if [ "$RUST_RELEASE_CHANNEL" = "nightly" ] || [ "$DIST_REQUIRE_ALL_TOOLS" = "" ]; then
diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md
index e2b001832fe..b60c5524014 100644
--- a/src/doc/rustc/src/command-line-arguments.md
+++ b/src/doc/rustc/src/command-line-arguments.md
@@ -10,6 +10,11 @@ This flag will print out help information for `rustc`.
 
 This flag can turn on or off various `#[cfg]` settings.
 
+The value can either be a single identifier or two identifiers separated by `=`.
+
+For examples, `--cfg 'verbose'` or `--cfg 'feature="serde"'`. These correspond
+to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively.
+
 ## `-L`: add a directory to the library search path
 
 When looking for external crates, a directory passed to this flag will be searched.
diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs
index a2e68a223f1..b857964ccb3 100644
--- a/src/liballoc/fmt.rs
+++ b/src/liballoc/fmt.rs
@@ -335,8 +335,7 @@
 //!
 //! Each argument being formatted can be transformed by a number of formatting
 //! parameters (corresponding to `format_spec` in the syntax above). These
-//! parameters affect the string representation of what's being formatted. This
-//! syntax draws heavily from Python's, so it may seem a bit familiar.
+//! parameters affect the string representation of what's being formatted.
 //!
 //! ## Fill/Alignment
 //!
diff --git a/src/librustc/build.rs b/src/librustc/build.rs
index 4df5f0e6405..bde503d86de 100644
--- a/src/librustc/build.rs
+++ b/src/librustc/build.rs
@@ -8,8 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::env;
+
 fn main() {
     println!("cargo:rerun-if-changed=build.rs");
     println!("cargo:rerun-if-env-changed=CFG_LIBDIR_RELATIVE");
     println!("cargo:rerun-if-env-changed=CFG_COMPILER_HOST_TRIPLE");
+    println!("cargo:rerun-if-env-changed=RUSTC_VERIFY_LLVM_IR");
+
+    if env::var_os("RUSTC_VERIFY_LLVM_IR").is_some() {
+        println!("cargo:rustc-cfg=always_verify_llvm_ir");
+    }
 }
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 1ca60d54f7a..2b90a27b6a8 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -525,6 +525,7 @@ impl Session {
     }
     pub fn verify_llvm_ir(&self) -> bool {
         self.opts.debugging_opts.verify_llvm_ir
+            || cfg!(always_verify_llvm_ir)
     }
     pub fn borrowck_stats(&self) -> bool {
         self.opts.debugging_opts.borrowck_stats
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index c4f39ffcd20..14e4ddfcdd6 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -369,16 +369,16 @@ define_queries! { <'tcx>
             -> Lrc<specialization_graph::Graph>,
         [] fn is_object_safe: ObjectSafety(DefId) -> bool,
 
-        // Get the ParameterEnvironment for a given item; this environment
-        // will be in "user-facing" mode, meaning that it is suitabe for
-        // type-checking etc, and it does not normalize specializable
-        // associated types. This is almost always what you want,
-        // unless you are doing MIR optimizations, in which case you
-        // might want to use `reveal_all()` method to change modes.
+        /// Get the ParameterEnvironment for a given item; this environment
+        /// will be in "user-facing" mode, meaning that it is suitabe for
+        /// type-checking etc, and it does not normalize specializable
+        /// associated types. This is almost always what you want,
+        /// unless you are doing MIR optimizations, in which case you
+        /// might want to use `reveal_all()` method to change modes.
         [] fn param_env: ParamEnv(DefId) -> ty::ParamEnv<'tcx>,
 
-        // Trait selection queries. These are best used by invoking `ty.moves_by_default()`,
-        // `ty.is_copy()`, etc, since that will prune the environment where possible.
+        /// Trait selection queries. These are best used by invoking `ty.moves_by_default()`,
+        /// `ty.is_copy()`, etc, since that will prune the environment where possible.
         [] fn is_copy_raw: is_copy_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
         [] fn is_sized_raw: is_sized_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
         [] fn is_freeze_raw: is_freeze_dep_node(ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool,
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index df9c4e874bd..169bd9a8466 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -756,7 +756,7 @@ impl Builder<'a, 'll, 'tcx> {
             // Ask LLVM to verify that the constraints are well-formed.
             let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons);
             debug!("Constraint verification result: {:?}", constraints_ok);
-            if constraints_ok == llvm::True {
+            if constraints_ok {
                 let v = llvm::LLVMRustInlineAsm(
                     fty, asm, cons, volatile, alignstack, dia);
                 Some(self.call(v, inputs, None))
diff --git a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
index 0484837a48d..56352ae963f 100644
--- a/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
+++ b/src/librustc_codegen_llvm/debuginfo/create_scope_map.rs
@@ -37,7 +37,7 @@ pub struct MirDebugScope<'ll> {
 
 impl MirDebugScope<'ll> {
     pub fn is_valid(&self) -> bool {
-        !self.scope_metadata.is_none()
+        self.scope_metadata.is_some()
     }
 }
 
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index 6eff086a2ba..f5e5287cd42 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -163,10 +163,10 @@ impl TypeMap<'ll, 'tcx> {
     fn get_unique_type_id_of_type<'a>(&mut self, cx: &CodegenCx<'a, 'tcx>,
                                       type_: Ty<'tcx>) -> UniqueTypeId {
         // Let's see if we already have something in the cache
-        match self.type_to_unique_id.get(&type_).cloned() {
-            Some(unique_type_id) => return unique_type_id,
-            None => { /* generate one */}
-        };
+        if let Some(unique_type_id) = self.type_to_unique_id.get(&type_).cloned() {
+            return unique_type_id;
+        }
+        // if not, generate one
 
         // The hasher we are using to generate the UniqueTypeId. We want
         // something that provides more than the 64 bits of the DefaultHasher.
@@ -286,11 +286,11 @@ impl RecursiveTypeDescription<'ll, 'tcx> {
 // unique id can be found in the type map
 macro_rules! return_if_metadata_created_in_meantime {
     ($cx: expr, $unique_type_id: expr) => (
-        match debug_context($cx).type_map
-                                .borrow()
-                                .find_metadata_for_unique_id($unique_type_id) {
-            Some(metadata) => return MetadataCreationResult::new(metadata, true),
-            None => { /* proceed normally */ }
+        if let Some(metadata) = debug_context($cx).type_map
+            .borrow()
+            .find_metadata_for_unique_id($unique_type_id)
+        {
+            return MetadataCreationResult::new(metadata, true);
         }
     )
 }
@@ -352,7 +352,7 @@ fn vec_slice_metadata(
 
     let member_descriptions = vec![
         MemberDescription {
-            name: "data_ptr".to_string(),
+            name: "data_ptr".to_owned(),
             type_metadata: data_ptr_metadata,
             offset: Size::ZERO,
             size: pointer_size,
@@ -360,7 +360,7 @@ fn vec_slice_metadata(
             flags: DIFlags::FlagZero,
         },
         MemberDescription {
-            name: "length".to_string(),
+            name: "length".to_owned(),
             type_metadata: type_metadata(cx, cx.tcx.types.usize, span),
             offset: pointer_size,
             size: usize_size,
@@ -458,7 +458,7 @@ fn trait_pointer_metadata(
     let vtable_field = layout.field(cx, 1);
     let member_descriptions = vec![
         MemberDescription {
-            name: "pointer".to_string(),
+            name: "pointer".to_owned(),
             type_metadata: type_metadata(cx,
                 cx.tcx.mk_mut_ptr(cx.tcx.types.u8),
                 syntax_pos::DUMMY_SP),
@@ -468,7 +468,7 @@ fn trait_pointer_metadata(
             flags: DIFlags::FlagArtificial,
         },
         MemberDescription {
-            name: "vtable".to_string(),
+            name: "vtable".to_owned(),
             type_metadata: type_metadata(cx, vtable_field.ty, syntax_pos::DUMMY_SP),
             offset: layout.fields.offset(1),
             size: vtable_field.size,
@@ -543,12 +543,12 @@ pub fn type_metadata(
             _ => {
                 let pointee_metadata = type_metadata(cx, ty, usage_site_span);
 
-                match debug_context(cx).type_map
-                                        .borrow()
-                                        .find_metadata_for_unique_id(unique_type_id) {
-                    Some(metadata) => return Err(metadata),
-                    None => { /* proceed normally */ }
-                };
+                if let Some(metadata) = debug_context(cx).type_map
+                    .borrow()
+                    .find_metadata_for_unique_id(unique_type_id)
+                {
+                    return Err(metadata);
+                }
 
                 Ok(MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata),
                    false))
@@ -577,12 +577,12 @@ pub fn type_metadata(
         }
         ty::Dynamic(..) => {
             MetadataCreationResult::new(
-                        trait_pointer_metadata(cx, t, None, unique_type_id),
-            false)
+                trait_pointer_metadata(cx, t, None, unique_type_id),
+                false)
         }
         ty::Foreign(..) => {
             MetadataCreationResult::new(
-                        foreign_type_metadata(cx, t, unique_type_id),
+            foreign_type_metadata(cx, t, unique_type_id),
             false)
         }
         ty::RawPtr(ty::TypeAndMut{ty, ..}) |
@@ -603,12 +603,12 @@ pub fn type_metadata(
                                                        unique_type_id,
                                                        t.fn_sig(cx.tcx),
                                                        usage_site_span).metadata;
-            match debug_context(cx).type_map
-                                   .borrow()
-                                   .find_metadata_for_unique_id(unique_type_id) {
-                Some(metadata) => return metadata,
-                None => { /* proceed normally */ }
-            };
+            if let Some(metadata) = debug_context(cx).type_map
+               .borrow()
+               .find_metadata_for_unique_id(unique_type_id)
+            {
+                return metadata;
+            }
 
             // This is actually a function pointer, so wrap it in pointer DI
             MetadataCreationResult::new(pointer_type_metadata(cx, t, fn_metadata), false)
@@ -641,16 +641,16 @@ pub fn type_metadata(
             }
             AdtKind::Union => {
                 prepare_union_metadata(cx,
-                                    t,
-                                    unique_type_id,
-                                    usage_site_span).finalize(cx)
+                                       t,
+                                       unique_type_id,
+                                       usage_site_span).finalize(cx)
             }
             AdtKind::Enum => {
                 prepare_enum_metadata(cx,
-                                    t,
-                                    def.did,
-                                    unique_type_id,
-                                    usage_site_span).finalize(cx)
+                                      t,
+                                      def.did,
+                                      unique_type_id,
+                                      usage_site_span).finalize(cx)
             }
         },
         ty::Tuple(ref elements) => {
@@ -938,7 +938,7 @@ enum MemberDescriptionFactory<'ll, 'tcx> {
 
 impl MemberDescriptionFactory<'ll, 'tcx> {
     fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
-                                      -> Vec<MemberDescription<'ll>> {
+                                  -> Vec<MemberDescription<'ll>> {
         match *self {
             StructMDF(ref this) => {
                 this.create_member_descriptions(cx)
@@ -972,7 +972,7 @@ struct StructMemberDescriptionFactory<'tcx> {
 
 impl<'tcx> StructMemberDescriptionFactory<'tcx> {
     fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
-                                      -> Vec<MemberDescription<'ll>> {
+                                  -> Vec<MemberDescription<'ll>> {
         let layout = cx.layout_of(self.ty);
         self.variant.fields.iter().enumerate().map(|(i, f)| {
             let name = if self.variant.ctor_kind == CtorKind::Fn {
@@ -1042,7 +1042,7 @@ struct TupleMemberDescriptionFactory<'tcx> {
 
 impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
     fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
-                                      -> Vec<MemberDescription<'ll>> {
+                                  -> Vec<MemberDescription<'ll>> {
         let layout = cx.layout_of(self.ty);
         self.component_types.iter().enumerate().map(|(i, &component_type)| {
             let (size, align) = cx.size_and_align_of(component_type);
@@ -1096,7 +1096,7 @@ struct UnionMemberDescriptionFactory<'tcx> {
 
 impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
     fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
-                                      -> Vec<MemberDescription<'ll>> {
+                                  -> Vec<MemberDescription<'ll>> {
         self.variant.fields.iter().enumerate().map(|(i, f)| {
             let field = self.layout.field(cx, i);
             let (size, align) = field.size_and_align();
@@ -1165,7 +1165,7 @@ struct EnumMemberDescriptionFactory<'ll, 'tcx> {
 
 impl EnumMemberDescriptionFactory<'ll, 'tcx> {
     fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
-                                      -> Vec<MemberDescription<'ll>> {
+                                  -> Vec<MemberDescription<'ll>> {
         let adt = &self.enum_type.ty_adt_def().unwrap();
         match self.layout.variants {
             layout::Variants::Single { .. } if adt.variants.is_empty() => vec![],
@@ -1357,7 +1357,7 @@ fn describe_enum_variant(
             // We have the layout of an enum variant, we need the layout of the outer enum
             let enum_layout = cx.layout_of(layout.ty);
             (Some(enum_layout.fields.offset(0)),
-             Some(("RUST$ENUM$DISR".to_string(), enum_layout.field(cx, 0).ty)))
+             Some(("RUST$ENUM$DISR".to_owned(), enum_layout.field(cx, 0).ty)))
         }
         _ => (None, None),
     };
@@ -1471,9 +1471,8 @@ fn prepare_enum_metadata(
         }
     };
 
-    match (&layout.abi, discriminant_type_metadata) {
-        (&layout::Abi::Scalar(_), Some(discr)) => return FinalMetadata(discr),
-        _ => {}
+    if let (&layout::Abi::Scalar(_), Some(discr)) = (&layout.abi, discriminant_type_metadata) {
+        return FinalMetadata(discr);
     }
 
     let (enum_type_size, enum_type_align) = layout.size_and_align();
@@ -1546,7 +1545,7 @@ fn composite_type_metadata(
                                   composite_type_metadata,
                                   member_descriptions);
 
-    return composite_type_metadata;
+    composite_type_metadata
 }
 
 fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>,
@@ -1634,7 +1633,7 @@ fn create_struct_stub(
             unique_type_id.as_ptr())
     };
 
-    return metadata_stub;
+    metadata_stub
 }
 
 fn create_union_stub(
@@ -1670,7 +1669,7 @@ fn create_union_stub(
             unique_type_id.as_ptr())
     };
 
-    return metadata_stub;
+    metadata_stub
 }
 
 /// Creates debug information for the given global variable.
diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs
index 7b0c413e857..acb79d6f568 100644
--- a/src/librustc_codegen_llvm/debuginfo/mod.rs
+++ b/src/librustc_codegen_llvm/debuginfo/mod.rs
@@ -271,16 +271,14 @@ pub fn create_function_debug_context(
     let mut flags = DIFlags::FlagPrototyped;
 
     let local_id = cx.tcx.hir.as_local_node_id(def_id);
-    match *cx.sess().entry_fn.borrow() {
-        Some((id, _, _)) => {
-            if local_id == Some(id) {
-                flags = flags | DIFlags::FlagMainSubprogram;
-            }
+    if let Some((id, _, _)) = *cx.sess().entry_fn.borrow() {
+        if local_id == Some(id) {
+            flags |= DIFlags::FlagMainSubprogram;
         }
-        None => {}
-    };
+    }
+
     if cx.layout_of(sig.output()).abi.is_uninhabited() {
-        flags = flags | DIFlags::FlagNoReturn;
+        flags |= DIFlags::FlagNoReturn;
     }
 
     let fn_metadata = unsafe {
@@ -371,7 +369,7 @@ pub fn create_function_debug_context(
             }
         }
 
-        return create_DIArray(DIB(cx), &signature[..]);
+        create_DIArray(DIB(cx), &signature[..])
     }
 
     fn get_template_parameters(
@@ -428,7 +426,7 @@ pub fn create_function_debug_context(
             vec![]
         };
 
-        return create_DIArray(DIB(cx), &template_params[..]);
+        create_DIArray(DIB(cx), &template_params[..])
     }
 
     fn get_parameter_names(cx: &CodegenCx,
diff --git a/src/librustc_codegen_llvm/debuginfo/source_loc.rs b/src/librustc_codegen_llvm/debuginfo/source_loc.rs
index c59b5e2b8f5..60ebcb88816 100644
--- a/src/librustc_codegen_llvm/debuginfo/source_loc.rs
+++ b/src/librustc_codegen_llvm/debuginfo/source_loc.rs
@@ -56,11 +56,8 @@ pub fn set_source_location(
 /// switches source location emitting on and must therefore be called before the
 /// first real statement/expression of the function is codegened.
 pub fn start_emitting_source_locations(dbg_context: &FunctionDebugContext<'ll>) {
-    match *dbg_context {
-        FunctionDebugContext::RegularContext(ref data) => {
-            data.source_locations_enabled.set(true)
-        },
-        _ => { /* safe to ignore */ }
+    if let FunctionDebugContext::RegularContext(ref data) = *dbg_context {
+        data.source_locations_enabled.set(true);
     }
 }
 
diff --git a/src/librustc_codegen_llvm/debuginfo/type_names.rs b/src/librustc_codegen_llvm/debuginfo/type_names.rs
index 06b9318a5e8..f5abb527e43 100644
--- a/src/librustc_codegen_llvm/debuginfo/type_names.rs
+++ b/src/librustc_codegen_llvm/debuginfo/type_names.rs
@@ -177,7 +177,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
         ty::GeneratorWitness(..) |
         ty::Param(_) => {
             bug!("debuginfo: Trying to create type name for \
-                unexpected type: {:?}", t);
+                  unexpected type: {:?}", t);
         }
     }
 
diff --git a/src/librustc_codegen_llvm/llvm/archive_ro.rs b/src/librustc_codegen_llvm/llvm/archive_ro.rs
index 4cbf0d92d7b..e0a9f31e508 100644
--- a/src/librustc_codegen_llvm/llvm/archive_ro.rs
+++ b/src/librustc_codegen_llvm/llvm/archive_ro.rs
@@ -40,7 +40,7 @@ impl ArchiveRO {
         return unsafe {
             let s = path2cstr(dst);
             let ar = super::LLVMRustOpenArchive(s.as_ptr()).ok_or_else(|| {
-                super::last_error().unwrap_or("failed to open archive".to_string())
+                super::last_error().unwrap_or("failed to open archive".to_owned())
             })?;
             Ok(ArchiveRO { raw: ar })
         };
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index 6108af6c884..0b98fa4eaf5 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -1212,8 +1212,8 @@ extern "C" {
                              Dialect: AsmDialect)
                              -> &Value;
     pub fn LLVMRustInlineAsmVerify(Ty: &Type,
-                             Constraints: *const c_char)
-                             -> Bool;
+                                   Constraints: *const c_char)
+                                   -> bool;
 
     pub fn LLVMRustDebugMetadataVersion() -> u32;
     pub fn LLVMRustVersionMajor() -> u32;
diff --git a/src/librustc_codegen_llvm/meth.rs b/src/librustc_codegen_llvm/meth.rs
index db06b87f44e..29c2e71960c 100644
--- a/src/librustc_codegen_llvm/meth.rs
+++ b/src/librustc_codegen_llvm/meth.rs
@@ -94,6 +94,10 @@ pub fn get_vtable(
     });
 
     let (size, align) = cx.size_and_align_of(ty);
+    // /////////////////////////////////////////////////////////////////////////////////////////////
+    // If you touch this code, be sure to also make the corresponding changes to
+    // `get_vtable` in rust_mir/interpret/traits.rs
+    // /////////////////////////////////////////////////////////////////////////////////////////////
     let components: Vec<_> = [
         callee::get_fn(cx, monomorphize::resolve_drop_in_place(cx.tcx, ty)),
         C_usize(cx, size.bytes()),
diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs
index 5be176f75c9..68e30227185 100644
--- a/src/librustc_codegen_llvm/mir/block.rs
+++ b/src/librustc_codegen_llvm/mir/block.rs
@@ -125,10 +125,10 @@ impl FunctionCx<'a, 'll, 'tcx> {
                     this.unreachable_block()
                 };
                 let invokeret = bx.invoke(fn_ptr,
-                                           &llargs,
-                                           ret_bx,
-                                           llblock(this, cleanup),
-                                           cleanup_bundle);
+                                          &llargs,
+                                          ret_bx,
+                                          llblock(this, cleanup),
+                                          cleanup_bundle);
                 fn_ty.apply_attrs_callsite(&bx, invokeret);
 
                 if let Some((ret_dest, target)) = destination {
@@ -213,7 +213,8 @@ impl FunctionCx<'a, 'll, 'tcx> {
                 } else {
                     let (otherwise, targets) = targets.split_last().unwrap();
                     let switch = bx.switch(discr.immediate(),
-                                            llblock(self, *otherwise), values.len());
+                                           llblock(self, *otherwise),
+                                           values.len());
                     let switch_llty = bx.cx.layout_of(switch_ty).immediate_llvm_type(bx.cx);
                     for (&value, target) in values.iter().zip(targets) {
                         let llval = C_uint_big(switch_llty, value);
@@ -387,8 +388,8 @@ impl FunctionCx<'a, 'll, 'tcx> {
                         let msg_str = Symbol::intern(str).as_str();
                         let msg_str = C_str_slice(bx.cx, msg_str);
                         let msg_file_line_col = C_struct(bx.cx,
-                                                     &[msg_str, filename, line, col],
-                                                     false);
+                                                         &[msg_str, filename, line, col],
+                                                         false);
                         let msg_file_line_col = consts::addr_of(bx.cx,
                                                                 msg_file_line_col,
                                                                 align,
@@ -509,8 +510,8 @@ impl FunctionCx<'a, 'll, 'tcx> {
                     let msg_str = Symbol::intern(&str).as_str();
                     let msg_str = C_str_slice(bx.cx, msg_str);
                     let msg_file_line_col = C_struct(bx.cx,
-                                                    &[msg_str, filename, line, col],
-                                                    false);
+                                                     &[msg_str, filename, line, col],
+                                                     false);
                     let msg_file_line_col = consts::addr_of(bx.cx,
                                                             msg_file_line_col,
                                                             align,
@@ -619,7 +620,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
 
                     let callee_ty = instance.as_ref().unwrap().ty(bx.cx.tcx);
                     codegen_intrinsic_call(&bx, callee_ty, &fn_ty, &args, dest,
-                                         terminator.source_info.span);
+                                           terminator.source_info.span);
 
                     if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
                         self.store_return(&bx, ret_dest, &fn_ty.ret, dst.llval);
@@ -756,7 +757,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
             // Have to load the argument, maybe while casting it.
             if let PassMode::Cast(ty) = arg.mode {
                 llval = bx.load(bx.pointercast(llval, ty.llvm_type(bx.cx).ptr_to()),
-                                 align.min(arg.layout.align));
+                                align.min(arg.layout.align));
             } else {
                 // We can't use `PlaceRef::load` here because the argument
                 // may have a type we don't treat as immediate, but the ABI
@@ -778,10 +779,10 @@ impl FunctionCx<'a, 'll, 'tcx> {
     }
 
     fn codegen_arguments_untupled(&mut self,
-                                bx: &Builder<'a, 'll, 'tcx>,
-                                operand: &mir::Operand<'tcx>,
-                                llargs: &mut Vec<&'ll Value>,
-                                args: &[ArgType<'tcx, Ty<'tcx>>]) {
+                                  bx: &Builder<'a, 'll, 'tcx>,
+                                  operand: &mir::Operand<'tcx>,
+                                  llargs: &mut Vec<&'ll Value>,
+                                  args: &[ArgType<'tcx, Ty<'tcx>>]) {
         let tuple = self.codegen_operand(bx, operand);
 
         // Handle both by-ref and immediate tuples.
@@ -933,8 +934,8 @@ impl FunctionCx<'a, 'll, 'tcx> {
     }
 
     fn codegen_transmute(&mut self, bx: &Builder<'a, 'll, 'tcx>,
-                       src: &mir::Operand<'tcx>,
-                       dst: &mir::Place<'tcx>) {
+                         src: &mir::Operand<'tcx>,
+                         dst: &mir::Place<'tcx>) {
         if let mir::Place::Local(index) = *dst {
             match self.locals[index] {
                 LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place),
@@ -961,8 +962,8 @@ impl FunctionCx<'a, 'll, 'tcx> {
     }
 
     fn codegen_transmute_into(&mut self, bx: &Builder<'a, 'll, 'tcx>,
-                            src: &mir::Operand<'tcx>,
-                            dst: PlaceRef<'ll, 'tcx>) {
+                              src: &mir::Operand<'tcx>,
+                              dst: PlaceRef<'ll, 'tcx>) {
         let src = self.codegen_operand(bx, src);
         let llty = src.layout.llvm_type(bx.cx);
         let cast_ptr = bx.pointercast(dst.llval, llty.ptr_to());
diff --git a/src/librustc_codegen_llvm/mir/mod.rs b/src/librustc_codegen_llvm/mir/mod.rs
index c61a326e7c8..a6e2ccf92e4 100644
--- a/src/librustc_codegen_llvm/mir/mod.rs
+++ b/src/librustc_codegen_llvm/mir/mod.rs
@@ -162,16 +162,16 @@ impl FunctionCx<'a, 'll, 'tcx> {
     // corresponding to span's containing source scope.  If so, we need to create a DIScope
     // "extension" into that file.
     fn scope_metadata_for_loc(&self, scope_id: mir::SourceScope, pos: BytePos)
-                               -> Option<&'ll DIScope> {
+                              -> Option<&'ll DIScope> {
         let scope_metadata = self.scopes[scope_id].scope_metadata;
         if pos < self.scopes[scope_id].file_start_pos ||
            pos >= self.scopes[scope_id].file_end_pos {
             let cm = self.cx.sess().source_map();
             let defining_crate = self.debug_context.get_ref(DUMMY_SP).defining_crate;
             Some(debuginfo::extend_scope_to_file(self.cx,
-                                            scope_metadata.unwrap(),
-                                            &cm.lookup_char_pos(pos).file,
-                                            defining_crate))
+                                                 scope_metadata.unwrap(),
+                                                 &cm.lookup_char_pos(pos).file,
+                                                 defining_crate))
         } else {
             scope_metadata
         }
diff --git a/src/librustc_data_structures/bit_set.rs b/src/librustc_data_structures/bit_set.rs
index 1fba57fa541..28aad49b09b 100644
--- a/src/librustc_data_structures/bit_set.rs
+++ b/src/librustc_data_structures/bit_set.rs
@@ -423,15 +423,6 @@ pub enum HybridBitSet<T: Idx> {
 }
 
 impl<T: Idx> HybridBitSet<T> {
-    // FIXME: This function is used in conjunction with `mem::replace()` in
-    // several pieces of awful code below. I can't work out how else to appease
-    // the borrow checker.
-    fn dummy() -> Self {
-        // The cheapest HybridBitSet to construct, which is only used to get
-        // around the borrow checker.
-        HybridBitSet::Sparse(SparseBitSet::new_empty(0))
-    }
-
     pub fn new_empty(domain_size: usize) -> Self {
         HybridBitSet::Sparse(SparseBitSet::new_empty(domain_size))
     }
@@ -487,20 +478,14 @@ impl<T: Idx> HybridBitSet<T> {
                 // that doesn't matter because `elem` is already present.
                 false
             }
-            HybridBitSet::Sparse(_) => {
+            HybridBitSet::Sparse(sparse) => {
                 // The set is sparse and full. Convert to a dense set.
-                match mem::replace(self, HybridBitSet::dummy()) {
-                    HybridBitSet::Sparse(sparse) => {
-                        let mut dense = sparse.to_dense();
-                        let changed = dense.insert(elem);
-                        assert!(changed);
-                        *self = HybridBitSet::Dense(dense);
-                        changed
-                    }
-                    _ => unreachable!()
-                }
+                let mut dense = sparse.to_dense();
+                let changed = dense.insert(elem);
+                assert!(changed);
+                *self = HybridBitSet::Dense(dense);
+                changed
             }
-
             HybridBitSet::Dense(dense) => dense.insert(elem),
         }
     }
@@ -525,33 +510,26 @@ impl<T: Idx> HybridBitSet<T> {
 
     pub fn union(&mut self, other: &HybridBitSet<T>) -> bool {
         match self {
-            HybridBitSet::Sparse(_) => {
+            HybridBitSet::Sparse(self_sparse) => {
                 match other {
                     HybridBitSet::Sparse(other_sparse) => {
                         // Both sets are sparse. Add the elements in
-                        // `other_sparse` to `self_hybrid` one at a time. This
-                        // may or may not cause `self_hybrid` to be densified.
+                        // `other_sparse` to `self` one at a time. This
+                        // may or may not cause `self` to be densified.
                         assert_eq!(self.domain_size(), other.domain_size());
-                        let mut self_hybrid = mem::replace(self, HybridBitSet::dummy());
                         let mut changed = false;
                         for elem in other_sparse.iter() {
-                            changed |= self_hybrid.insert(*elem);
+                            changed |= self.insert(*elem);
                         }
-                        *self = self_hybrid;
                         changed
                     }
                     HybridBitSet::Dense(other_dense) => {
                         // `self` is sparse and `other` is dense. Densify
                         // `self` and then do the bitwise union.
-                        match mem::replace(self, HybridBitSet::dummy()) {
-                            HybridBitSet::Sparse(self_sparse) => {
-                                let mut new_dense = self_sparse.to_dense();
-                                let changed = new_dense.union(other_dense);
-                                *self = HybridBitSet::Dense(new_dense);
-                                changed
-                            }
-                            _ => unreachable!()
-                        }
+                        let mut new_dense = self_sparse.to_dense();
+                        let changed = new_dense.union(other_dense);
+                        *self = HybridBitSet::Dense(new_dense);
+                        changed
                     }
                 }
             }
diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs
index bcf37722130..a316fc5ca10 100644
--- a/src/librustc_mir/borrow_check/borrow_set.rs
+++ b/src/librustc_mir/borrow_check/borrow_set.rs
@@ -92,12 +92,12 @@ impl<'tcx> fmt::Display for BorrowData<'tcx> {
             mir::BorrowKind::Mut { .. } => "mut ",
         };
         let region = self.region.to_string();
-        let region = if region.len() > 0 {
-            format!("{} ", region)
+        let separator = if !region.is_empty() {
+            " "
         } else {
-            region
+            ""
         };
-        write!(w, "&{}{}{:?}", region, kind, self.borrowed_place)
+        write!(w, "&{}{}{}{:?}", region, separator, kind, self.borrowed_place)
     }
 }
 
@@ -244,7 +244,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
             K: Clone + Eq + Hash,
             V: Eq + Hash,
         {
-            map.entry(k.clone()).or_insert(FxHashSet()).insert(v);
+            map.entry(k.clone()).or_default().insert(v);
         }
     }
 
@@ -261,57 +261,53 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
             // ... check whether we (earlier) saw a 2-phase borrow like
             //
             //     TMP = &mut place
-            match self.pending_activations.get(temp) {
-                Some(&borrow_index) => {
-                    let borrow_data = &mut self.idx_vec[borrow_index];
-
-                    // Watch out: the use of TMP in the borrow itself
-                    // doesn't count as an activation. =)
-                    if borrow_data.reserve_location == location && context == PlaceContext::Store {
-                        return;
-                    }
+            if let Some(&borrow_index) = self.pending_activations.get(temp) {
+                let borrow_data = &mut self.idx_vec[borrow_index];
 
-                    if let TwoPhaseActivation::ActivatedAt(other_location) =
-                            borrow_data.activation_location {
-                        span_bug!(
-                            self.mir.source_info(location).span,
-                            "found two uses for 2-phase borrow temporary {:?}: \
-                             {:?} and {:?}",
-                            temp,
-                            location,
-                            other_location,
-                        );
-                    }
+                // Watch out: the use of TMP in the borrow itself
+                // doesn't count as an activation. =)
+                if borrow_data.reserve_location == location && context == PlaceContext::Store {
+                    return;
+                }
 
-                    // Otherwise, this is the unique later use
-                    // that we expect.
-                    borrow_data.activation_location = match context {
-                        // The use of TMP in a shared borrow does not
-                        // count as an actual activation.
-                        PlaceContext::Borrow { kind: mir::BorrowKind::Shared, .. }
-                        | PlaceContext::Borrow { kind: mir::BorrowKind::Shallow, .. } => {
-                            TwoPhaseActivation::NotActivated
-                        }
-                        _ => {
-                            // Double check: This borrow is indeed a two-phase borrow (that is,
-                            // we are 'transitioning' from `NotActivated` to `ActivatedAt`) and
-                            // we've not found any other activations (checked above).
-                            assert_eq!(
-                                borrow_data.activation_location,
-                                TwoPhaseActivation::NotActivated,
-                                "never found an activation for this borrow!",
-                            );
-
-                            self.activation_map
-                                .entry(location)
-                                .or_default()
-                                .push(borrow_index);
-                            TwoPhaseActivation::ActivatedAt(location)
-                        }
-                    };
+                if let TwoPhaseActivation::ActivatedAt(other_location) =
+                        borrow_data.activation_location {
+                    span_bug!(
+                        self.mir.source_info(location).span,
+                        "found two uses for 2-phase borrow temporary {:?}: \
+                         {:?} and {:?}",
+                        temp,
+                        location,
+                        other_location,
+                    );
                 }
 
-                None => {}
+                // Otherwise, this is the unique later use
+                // that we expect.
+                borrow_data.activation_location = match context {
+                    // The use of TMP in a shared borrow does not
+                    // count as an actual activation.
+                    PlaceContext::Borrow { kind: mir::BorrowKind::Shared, .. }
+                    | PlaceContext::Borrow { kind: mir::BorrowKind::Shallow, .. } => {
+                        TwoPhaseActivation::NotActivated
+                    }
+                    _ => {
+                        // Double check: This borrow is indeed a two-phase borrow (that is,
+                        // we are 'transitioning' from `NotActivated` to `ActivatedAt`) and
+                        // we've not found any other activations (checked above).
+                        assert_eq!(
+                            borrow_data.activation_location,
+                            TwoPhaseActivation::NotActivated,
+                            "never found an activation for this borrow!",
+                        );
+
+                        self.activation_map
+                            .entry(location)
+                            .or_default()
+                            .push(borrow_index);
+                        TwoPhaseActivation::ActivatedAt(location)
+                    }
+                };
             }
         }
     }
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index 546746aa72e..759b842e9df 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -77,9 +77,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         if move_out_indices.is_empty() {
             let root_place = self.prefixes(&used_place, PrefixSet::All).last().unwrap();
 
-            if self.uninitialized_error_reported
-                .contains(&root_place.clone())
-            {
+            if self.uninitialized_error_reported.contains(root_place) {
                 debug!(
                     "report_use_of_moved_or_uninitialized place: error about {:?} suppressed",
                     root_place
@@ -188,11 +186,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                         let tables = self.infcx.tcx.typeck_tables_of(id);
                         let node_id = self.infcx.tcx.hir.as_local_node_id(id).unwrap();
                         let hir_id = self.infcx.tcx.hir.node_to_hir_id(node_id);
-                        if tables.closure_kind_origins().get(hir_id).is_some() {
-                            false
-                        } else {
-                            true
-                        }
+
+                        tables.closure_kind_origins().get(hir_id).is_none()
                     }
                     _ => true,
                 };
@@ -582,7 +577,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
     fn report_local_value_does_not_live_long_enough(
         &mut self,
         context: Context,
-        name: &String,
+        name: &str,
         scope_tree: &Lrc<ScopeTree>,
         borrow: &BorrowData<'tcx>,
         drop_span: Span,
@@ -1195,10 +1190,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             Place::Static(ref static_) => self.describe_field_from_ty(&static_.ty, field),
             Place::Projection(ref proj) => match proj.elem {
                 ProjectionElem::Deref => self.describe_field(&proj.base, field),
-                ProjectionElem::Downcast(def, variant_index) => format!(
-                    "{}",
-                    def.variants[variant_index].fields[field.index()].ident
-                ),
+                ProjectionElem::Downcast(def, variant_index) =>
+                    def.variants[variant_index].fields[field.index()].ident.to_string(),
                 ProjectionElem::Field(_, field_type) => {
                     self.describe_field_from_ty(&field_type, field)
                 }
@@ -1366,191 +1359,184 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             "annotate_argument_and_return_for_borrow: location={:?}",
             location
         );
-        match &self.mir[location.block]
-            .statements
-            .get(location.statement_index)
+        if let Some(&Statement { kind: StatementKind::Assign(ref reservation, _), ..})
+             = &self.mir[location.block].statements.get(location.statement_index)
         {
-            Some(&Statement {
-                kind: StatementKind::Assign(ref reservation, _),
-                ..
-            }) => {
+            debug!(
+                "annotate_argument_and_return_for_borrow: reservation={:?}",
+                reservation
+            );
+            // Check that the initial assignment of the reserve location is into a temporary.
+            let mut target = *match reservation {
+                Place::Local(local) if self.mir.local_kind(*local) == LocalKind::Temp => local,
+                _ => return None,
+            };
+
+            // Next, look through the rest of the block, checking if we are assigning the
+            // `target` (that is, the place that contains our borrow) to anything.
+            let mut annotated_closure = None;
+            for stmt in &self.mir[location.block].statements[location.statement_index + 1..] {
                 debug!(
-                    "annotate_argument_and_return_for_borrow: reservation={:?}",
-                    reservation
+                    "annotate_argument_and_return_for_borrow: target={:?} stmt={:?}",
+                    target, stmt
                 );
-                // Check that the initial assignment of the reserve location is into a temporary.
-                let mut target = *match reservation {
-                    Place::Local(local) if self.mir.local_kind(*local) == LocalKind::Temp => local,
-                    _ => return None,
-                };
-
-                // Next, look through the rest of the block, checking if we are assigning the
-                // `target` (that is, the place that contains our borrow) to anything.
-                let mut annotated_closure = None;
-                for stmt in &self.mir[location.block].statements[location.statement_index + 1..] {
+                if let StatementKind::Assign(Place::Local(assigned_to), box rvalue) = &stmt.kind
+                {
                     debug!(
-                        "annotate_argument_and_return_for_borrow: target={:?} stmt={:?}",
-                        target, stmt
+                        "annotate_argument_and_return_for_borrow: assigned_to={:?} \
+                         rvalue={:?}",
+                        assigned_to, rvalue
                     );
-                    if let StatementKind::Assign(Place::Local(assigned_to), box rvalue) = &stmt.kind
+                    // Check if our `target` was captured by a closure.
+                    if let Rvalue::Aggregate(
+                        box AggregateKind::Closure(def_id, substs),
+                        operands,
+                    ) = rvalue
                     {
-                        debug!(
-                            "annotate_argument_and_return_for_borrow: assigned_to={:?} \
-                             rvalue={:?}",
-                            assigned_to, rvalue
-                        );
-                        // Check if our `target` was captured by a closure.
-                        if let Rvalue::Aggregate(
-                            box AggregateKind::Closure(def_id, substs),
-                            operands,
-                        ) = rvalue
-                        {
-                            for operand in operands {
-                                let assigned_from = match operand {
-                                    Operand::Copy(assigned_from) | Operand::Move(assigned_from) => {
-                                        assigned_from
-                                    }
-                                    _ => continue,
-                                };
-                                debug!(
-                                    "annotate_argument_and_return_for_borrow: assigned_from={:?}",
+                        for operand in operands {
+                            let assigned_from = match operand {
+                                Operand::Copy(assigned_from) | Operand::Move(assigned_from) => {
                                     assigned_from
-                                );
-
-                                // Find the local from the operand.
-                                let assigned_from_local = match assigned_from.local() {
-                                    Some(local) => local,
-                                    None => continue,
-                                };
-
-                                if assigned_from_local != target {
-                                    continue;
                                 }
+                                _ => continue,
+                            };
+                            debug!(
+                                "annotate_argument_and_return_for_borrow: assigned_from={:?}",
+                                assigned_from
+                            );
 
-                                // If a closure captured our `target` and then assigned
-                                // into a place then we should annotate the closure in
-                                // case it ends up being assigned into the return place.
-                                annotated_closure = self.annotate_fn_sig(
-                                    *def_id,
-                                    self.infcx.closure_sig(*def_id, *substs),
-                                );
-                                debug!(
-                                    "annotate_argument_and_return_for_borrow: \
-                                     annotated_closure={:?} assigned_from_local={:?} \
-                                     assigned_to={:?}",
-                                    annotated_closure, assigned_from_local, assigned_to
-                                );
-
-                                if *assigned_to == mir::RETURN_PLACE {
-                                    // If it was assigned directly into the return place, then
-                                    // return now.
-                                    return annotated_closure;
-                                } else {
-                                    // Otherwise, update the target.
-                                    target = *assigned_to;
-                                }
+                            // Find the local from the operand.
+                            let assigned_from_local = match assigned_from.local() {
+                                Some(local) => local,
+                                None => continue,
+                            };
+
+                            if assigned_from_local != target {
+                                continue;
                             }
 
-                            // If none of our closure's operands matched, then skip to the next
-                            // statement.
-                            continue;
+                            // If a closure captured our `target` and then assigned
+                            // into a place then we should annotate the closure in
+                            // case it ends up being assigned into the return place.
+                            annotated_closure = self.annotate_fn_sig(
+                                *def_id,
+                                self.infcx.closure_sig(*def_id, *substs),
+                            );
+                            debug!(
+                                "annotate_argument_and_return_for_borrow: \
+                                 annotated_closure={:?} assigned_from_local={:?} \
+                                 assigned_to={:?}",
+                                annotated_closure, assigned_from_local, assigned_to
+                            );
+
+                            if *assigned_to == mir::RETURN_PLACE {
+                                // If it was assigned directly into the return place, then
+                                // return now.
+                                return annotated_closure;
+                            } else {
+                                // Otherwise, update the target.
+                                target = *assigned_to;
+                            }
                         }
 
-                        // Otherwise, look at other types of assignment.
-                        let assigned_from = match rvalue {
-                            Rvalue::Ref(_, _, assigned_from) => assigned_from,
-                            Rvalue::Use(operand) => match operand {
-                                Operand::Copy(assigned_from) | Operand::Move(assigned_from) => {
-                                    assigned_from
-                                }
-                                _ => continue,
-                            },
-                            _ => continue,
-                        };
-                        debug!(
-                            "annotate_argument_and_return_for_borrow: \
-                             assigned_from={:?}",
-                            assigned_from,
-                        );
+                        // If none of our closure's operands matched, then skip to the next
+                        // statement.
+                        continue;
+                    }
 
-                        // Find the local from the rvalue.
-                        let assigned_from_local = match assigned_from.local() {
-                            Some(local) => local,
-                            None => continue,
-                        };
-                        debug!(
-                            "annotate_argument_and_return_for_borrow: \
-                             assigned_from_local={:?}",
-                            assigned_from_local,
-                        );
+                    // Otherwise, look at other types of assignment.
+                    let assigned_from = match rvalue {
+                        Rvalue::Ref(_, _, assigned_from) => assigned_from,
+                        Rvalue::Use(operand) => match operand {
+                            Operand::Copy(assigned_from) | Operand::Move(assigned_from) => {
+                                assigned_from
+                            }
+                            _ => continue,
+                        },
+                        _ => continue,
+                    };
+                    debug!(
+                        "annotate_argument_and_return_for_borrow: \
+                         assigned_from={:?}",
+                        assigned_from,
+                    );
 
-                        // Check if our local matches the target - if so, we've assigned our
-                        // borrow to a new place.
-                        if assigned_from_local != target {
-                            continue;
-                        }
+                    // Find the local from the rvalue.
+                    let assigned_from_local = match assigned_from.local() {
+                        Some(local) => local,
+                        None => continue,
+                    };
+                    debug!(
+                        "annotate_argument_and_return_for_borrow: \
+                         assigned_from_local={:?}",
+                        assigned_from_local,
+                    );
 
-                        // If we assigned our `target` into a new place, then we should
-                        // check if it was the return place.
-                        debug!(
-                            "annotate_argument_and_return_for_borrow: \
-                             assigned_from_local={:?} assigned_to={:?}",
-                            assigned_from_local, assigned_to
-                        );
-                        if *assigned_to == mir::RETURN_PLACE {
-                            // If it was then return the annotated closure if there was one,
-                            // else, annotate this function.
-                            return annotated_closure.or_else(fallback);
-                        }
+                    // Check if our local matches the target - if so, we've assigned our
+                    // borrow to a new place.
+                    if assigned_from_local != target {
+                        continue;
+                    }
 
-                        // If we didn't assign into the return place, then we just update
-                        // the target.
-                        target = *assigned_to;
+                    // If we assigned our `target` into a new place, then we should
+                    // check if it was the return place.
+                    debug!(
+                        "annotate_argument_and_return_for_borrow: \
+                         assigned_from_local={:?} assigned_to={:?}",
+                        assigned_from_local, assigned_to
+                    );
+                    if *assigned_to == mir::RETURN_PLACE {
+                        // If it was then return the annotated closure if there was one,
+                        // else, annotate this function.
+                        return annotated_closure.or_else(fallback);
                     }
+
+                    // If we didn't assign into the return place, then we just update
+                    // the target.
+                    target = *assigned_to;
                 }
+            }
 
-                // Check the terminator if we didn't find anything in the statements.
-                let terminator = &self.mir[location.block].terminator();
+            // Check the terminator if we didn't find anything in the statements.
+            let terminator = &self.mir[location.block].terminator();
+            debug!(
+                "annotate_argument_and_return_for_borrow: target={:?} terminator={:?}",
+                target, terminator
+            );
+            if let TerminatorKind::Call {
+                destination: Some((Place::Local(assigned_to), _)),
+                args,
+                ..
+            } = &terminator.kind
+            {
                 debug!(
-                    "annotate_argument_and_return_for_borrow: target={:?} terminator={:?}",
-                    target, terminator
+                    "annotate_argument_and_return_for_borrow: assigned_to={:?} args={:?}",
+                    assigned_to, args
                 );
-                if let TerminatorKind::Call {
-                    destination: Some((Place::Local(assigned_to), _)),
-                    args,
-                    ..
-                } = &terminator.kind
-                {
+                for operand in args {
+                    let assigned_from = match operand {
+                        Operand::Copy(assigned_from) | Operand::Move(assigned_from) => {
+                            assigned_from
+                        }
+                        _ => continue,
+                    };
                     debug!(
-                        "annotate_argument_and_return_for_borrow: assigned_to={:?} args={:?}",
-                        assigned_to, args
+                        "annotate_argument_and_return_for_borrow: assigned_from={:?}",
+                        assigned_from,
                     );
-                    for operand in args {
-                        let assigned_from = match operand {
-                            Operand::Copy(assigned_from) | Operand::Move(assigned_from) => {
-                                assigned_from
-                            }
-                            _ => continue,
-                        };
+
+                    if let Some(assigned_from_local) = assigned_from.local() {
                         debug!(
-                            "annotate_argument_and_return_for_borrow: assigned_from={:?}",
-                            assigned_from,
+                            "annotate_argument_and_return_for_borrow: assigned_from_local={:?}",
+                            assigned_from_local,
                         );
 
-                        if let Some(assigned_from_local) = assigned_from.local() {
-                            debug!(
-                                "annotate_argument_and_return_for_borrow: assigned_from_local={:?}",
-                                assigned_from_local,
-                            );
-
-                            if *assigned_to == mir::RETURN_PLACE && assigned_from_local == target {
-                                return annotated_closure.or_else(fallback);
-                            }
+                        if *assigned_to == mir::RETURN_PLACE && assigned_from_local == target {
+                            return annotated_closure.or_else(fallback);
                         }
                     }
                 }
             }
-            _ => {}
         }
 
         // If we haven't found an assignment into the return place, then we need not add
@@ -1605,13 +1591,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                             // Need to use the `rustc::ty` types to compare against the
                             // `return_region`. Then use the `rustc::hir` type to get only
                             // the lifetime span.
-                            match &fn_decl.inputs[index].node {
-                                hir::TyKind::Rptr(lifetime, _) => {
-                                    // With access to the lifetime, we can get
-                                    // the span of it.
-                                    arguments.push((*argument, lifetime.span));
-                                }
-                                _ => bug!("ty type is a ref but hir type is not"),
+                            if let hir::TyKind::Rptr(lifetime, _) = &fn_decl.inputs[index].node {
+                                // With access to the lifetime, we can get
+                                // the span of it.
+                                arguments.push((*argument, lifetime.span));
+                            } else {
+                                bug!("ty type is a ref but hir type is not");
                             }
                         }
                     }
@@ -1794,8 +1779,8 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
                 ty::RegionKind::RePlaceholder(ty::Placeholder { name: br, .. }),
                 _,
                 _,
-            ) => with_highlight_region_for_bound_region(*br, counter, || format!("{}", ty)),
-            _ => format!("{}", ty),
+            ) => with_highlight_region_for_bound_region(*br, counter, || ty.to_string()),
+            _ => ty.to_string(),
         }
     }
 
@@ -1806,9 +1791,9 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
             ty::TyKind::Ref(region, _, _) => match region {
                 ty::RegionKind::ReLateBound(_, br)
                 | ty::RegionKind::RePlaceholder(ty::Placeholder { name: br, .. }) => {
-                    with_highlight_region_for_bound_region(*br, counter, || format!("{}", region))
+                    with_highlight_region_for_bound_region(*br, counter, || region.to_string())
                 }
-                _ => format!("{}", region),
+                _ => region.to_string(),
             },
             _ => bug!("ty for annotation of borrow region is not a reference"),
         }
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 98663270882..a7b356c1461 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -284,7 +284,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
     let temporary_used_locals: FxHashSet<Local> = mbcx
         .used_mut
         .iter()
-        .filter(|&local| !mbcx.mir.local_decls[*local].is_user_variable.is_some())
+        .filter(|&local| mbcx.mir.local_decls[*local].is_user_variable.is_none())
         .cloned()
         .collect();
     mbcx.gather_used_muts(temporary_used_locals);
@@ -342,7 +342,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
         diag.buffer(&mut mbcx.errors_buffer);
     }
 
-    if mbcx.errors_buffer.len() > 0 {
+    if !mbcx.errors_buffer.is_empty() {
         mbcx.errors_buffer.sort_by_key(|diag| diag.span.primary_span());
 
         if tcx.migrate_borrowck() {
@@ -1009,13 +1009,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                         return Control::Continue;
                     }
 
+                    error_reported = true;
                     match kind {
                         ReadKind::Copy  => {
-                            error_reported = true;
                             this.report_use_while_mutably_borrowed(context, place_span, borrow)
                         }
                         ReadKind::Borrow(bk) => {
-                            error_reported = true;
                             this.report_conflicting_borrow(context, place_span, bk, &borrow)
                         }
                     }
@@ -1045,13 +1044,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                         Read(..) | Write(..) => {}
                     }
 
+                    error_reported = true;
                     match kind {
                         WriteKind::MutableBorrow(bk) => {
-                            error_reported = true;
                             this.report_conflicting_borrow(context, place_span, bk, &borrow)
                         }
                         WriteKind::StorageDeadOrDrop => {
-                            error_reported = true;
                             this.report_borrowed_value_does_not_live_long_enough(
                                 context,
                                 borrow,
@@ -1059,11 +1057,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                                 Some(kind))
                         }
                         WriteKind::Mutate => {
-                            error_reported = true;
                             this.report_illegal_mutation_of_borrowed(context, place_span, borrow)
                         }
                         WriteKind::Move => {
-                            error_reported = true;
                             this.report_move_out_while_borrowed(context, place_span, &borrow)
                         }
                     }
@@ -1593,7 +1589,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             Place::Local(_) => panic!("should have move path for every Local"),
             Place::Projection(_) => panic!("PrefixSet::All meant don't stop for Projection"),
             Place::Promoted(_) |
-            Place::Static(_) => return Err(NoMovePathFound::ReachedStatic),
+            Place::Static(_) => Err(NoMovePathFound::ReachedStatic),
         }
     }
 
@@ -1885,7 +1881,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         }
 
         // at this point, we have set up the error reporting state.
-        if previously_initialized {
+        return if previously_initialized {
             self.report_mutability_error(
                 place,
                 span,
@@ -1893,10 +1889,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                 error_access,
                 location,
             );
-            return true;
+            true
         } else {
-            return false;
-        }
+            false
+        };
     }
 
     fn is_local_ever_initialized(&self,
@@ -1911,7 +1907,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                 return Some(index);
             }
         }
-        return None;
+        None
     }
 
     /// Adds the place into the used mutable variables set
@@ -2171,7 +2167,7 @@ impl ContextKind {
     fn new(self, loc: Location) -> Context {
         Context {
             kind: self,
-            loc: loc,
+            loc,
         }
     }
 }
diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs
index ea62694f8be..a556199b875 100644
--- a/src/librustc_mir/borrow_check/move_errors.rs
+++ b/src/librustc_mir/borrow_check/move_errors.rs
@@ -331,7 +331,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                             _ => {
                                 let source = self.borrowed_content_source(place);
                                 self.infcx.tcx.cannot_move_out_of(
-                                    span, &format!("{}", source), origin
+                                    span, &source.to_string(), origin
                                 )
                             },
                         }
@@ -469,9 +469,9 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
             let binding_span = bind_to.source_info.span;
 
             if j == 0 {
-                err.span_label(binding_span, format!("data moved here"));
+                err.span_label(binding_span, "data moved here");
             } else {
-                err.span_label(binding_span, format!("...and here"));
+                err.span_label(binding_span, "...and here");
             }
 
             if binds_to.len() == 1 {
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 5ab1605d7f0..30f4fc9d5ea 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -408,7 +408,6 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                             .map(|replacement| (pattern_span, replacement))
                     }
 
-                    //
                     ClearCrossCrate::Set(mir::BindingForm::RefForGuard) => unreachable!(),
 
                     ClearCrossCrate::Clear => bug!("saw cleared local state"),
@@ -505,7 +504,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                                 );
 
                                 let extra = if found {
-                                    String::from("")
+                                    String::new()
                                 } else {
                                     format!(", but it is not implemented for `{}`",
                                             substs.type_at(0))
@@ -573,7 +572,7 @@ fn suggest_ampmut<'cx, 'gcx, 'tcx>(
     opt_ty_info: Option<Span>,
 ) -> (Span, String) {
     let locations = mir.find_assignments(local);
-    if locations.len() > 0 {
+    if !locations.is_empty() {
         let assignment_rhs_span = mir.source_info(locations[0]).span;
         if let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span) {
             if let (true, Some(ws_pos)) = (
@@ -584,7 +583,7 @@ fn suggest_ampmut<'cx, 'gcx, 'tcx>(
                 let ty = &src[ws_pos..];
                 return (assignment_rhs_span, format!("&{} mut {}", lt_name, ty));
             } else if src.starts_with('&') {
-                let borrowed_expr = src[1..].to_string();
+                let borrowed_expr = &src[1..];
                 return (assignment_rhs_span, format!("&mut {}", borrowed_expr));
             }
         }
diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs
index 30b263a923a..495e84528a3 100644
--- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs
+++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs
@@ -141,6 +141,7 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx
         if let Some(all_facts) = self.all_facts {
             if let Place::Local(temp) = place {
                 if let Some(borrow_indices) = self.borrow_set.local_map.get(temp) {
+                    all_facts.killed.reserve(borrow_indices.len());
                     for &borrow_index in borrow_indices {
                         let location_index = self.location_table.mid_index(location);
                         all_facts.killed.push((borrow_index, location_index));
@@ -164,7 +165,9 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx
                 self.location_table.mid_index(location),
             ));
 
-            for successor_block in terminator.successors() {
+            let successor_blocks = terminator.successors();
+            all_facts.cfg_edge.reserve(successor_blocks.size_hint().0);
+            for successor_block in successor_blocks {
                 all_facts.cfg_edge.push((
                     self.location_table.mid_index(location),
                     self.location_table
diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
index 307112f8ba1..a0f832c5449 100644
--- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
@@ -87,9 +87,9 @@ impl<'tcx> BorrowExplanation<'tcx> {
                     // Otherwise, just report the whole type (and use
                     // the intentionally fuzzy phrase "destructor")
                     ty::Closure(..) =>
-                        ("destructor", format!("closure")),
+                        ("destructor", "closure".to_owned()),
                     ty::Generator(..) =>
-                        ("destructor", format!("generator")),
+                        ("destructor", "generator".to_owned()),
 
                     _ => ("destructor", format!("type `{}`", local_decl.ty)),
                 };
@@ -279,9 +279,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                         pending_locations.push(target.start_location());
                     },
                     TerminatorKind::SwitchInt { ref targets, .. } => {
-                        for target in targets {
-                            pending_locations.push(target.start_location());
-                        }
+                        pending_locations.extend(
+                            targets.into_iter().map(|target| target.start_location()));
                     },
                     TerminatorKind::Drop { target, unwind, .. } |
                     TerminatorKind::DropAndReplace { target, unwind, .. } |
@@ -303,9 +302,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     },
                     TerminatorKind::FalseEdges { real_target, ref imaginary_targets, .. } => {
                         pending_locations.push(real_target.start_location());
-                        for target in imaginary_targets {
-                            pending_locations.push(target.start_location());
-                        }
+                        pending_locations.extend(
+                            imaginary_targets.into_iter().map(|target| target.start_location()));
                     },
                     _ => {},
                 }
@@ -441,17 +439,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                             Operand::Move(Place::Local(from)) if *from == target => {
                                 debug!("was_captured_by_trait_object: ty={:?}", ty);
                                 // Check the type for a trait object.
-                                match ty.sty {
+                                return match ty.sty {
                                     // `&dyn Trait`
-                                    ty::TyKind::Ref(_, ty, _) if ty.is_trait() => return true,
+                                    ty::TyKind::Ref(_, ty, _) if ty.is_trait() => true,
                                     // `Box<dyn Trait>`
                                     _ if ty.is_box() && ty.boxed_ty().is_trait() =>
-                                        return true,
+                                        true,
                                     // `dyn Trait`
-                                    _ if ty.is_trait() => return true,
+                                    _ if ty.is_trait() => true,
                                     // Anything else.
-                                    _ => return false,
-                                }
+                                    _ => false,
+                                };
                             },
                             _ => return false,
                         },
@@ -466,32 +464,29 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                 let terminator = block.terminator();
                 debug!("was_captured_by_trait_object: terminator={:?}", terminator);
 
-                match &terminator.kind {
-                    TerminatorKind::Call {
-                        destination: Some((Place::Local(dest), block)),
-                        args,
-                        ..
-                    } => {
-                        debug!(
-                            "was_captured_by_trait_object: target={:?} dest={:?} args={:?}",
-                            target, dest, args
-                        );
-                        // Check if one of the arguments to this function is the target place.
-                        let found_target = args.iter().any(|arg| {
-                            if let Operand::Move(Place::Local(potential)) = arg {
-                                *potential == target
-                            } else {
-                                false
-                            }
-                        });
-
-                        // If it is, follow this to the next block and update the target.
-                        if found_target {
-                            target = *dest;
-                            queue.push(block.start_location());
+                if let TerminatorKind::Call {
+                    destination: Some((Place::Local(dest), block)),
+                    args,
+                    ..
+                } = &terminator.kind {
+                    debug!(
+                        "was_captured_by_trait_object: target={:?} dest={:?} args={:?}",
+                        target, dest, args
+                    );
+                    // Check if one of the arguments to this function is the target place.
+                    let found_target = args.iter().any(|arg| {
+                        if let Operand::Move(Place::Local(potential)) = arg {
+                            *potential == target
+                        } else {
+                            false
                         }
-                    },
-                    _ => {},
+                    });
+
+                    // If it is, follow this to the next block and update the target.
+                    if found_target {
+                        target = *dest;
+                        queue.push(block.start_location());
+                    }
                 }
             }
 
diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs
index a9b5531bae5..002f35880ae 100644
--- a/src/librustc_mir/borrow_check/nll/invalidation.rs
+++ b/src/librustc_mir/borrow_check/nll/invalidation.rs
@@ -35,7 +35,7 @@ pub(super) fn generate_invalidates<'cx, 'gcx, 'tcx>(
     mir: &Mir<'tcx>,
     borrow_set: &BorrowSet<'tcx>,
 ) {
-    if !all_facts.is_some() {
+    if all_facts.is_none() {
         // Nothing to do if we don't have any facts
         return;
     }
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs b/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
index ee900afc44d..268a37c7086 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
@@ -36,12 +36,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 let outlived_by = self.universal_region_relations.regions_outlived_by(region);
                 writeln!(
                     out,
-                    "| {r:rw$} | {c:cw$} | {ob}",
-                    r = format!("{:?}", region),
+                    "| {r:rw$?} | {c:cw$?} | {ob:?}",
+                    r = region,
                     rw = REGION_WIDTH,
-                    c = format!("{:?}", classification),
+                    c = classification,
                     cw = 8, // "External" at most
-                    ob = format!("{:?}", outlived_by)
+                    ob = outlived_by
                 )?;
             }
         }
@@ -51,8 +51,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         for region in self.regions() {
             writeln!(
                 out,
-                "| {r:rw$} | {ui:4?} | {v}",
-                r = format!("{:?}", region),
+                "| {r:rw$?} | {ui:4?} | {v}",
+                r = region,
                 rw = REGION_WIDTH,
                 ui = self.region_universe(region),
                 v = self.region_value_str(region),
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
index 8191dd720e7..5ff50c606d6 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
@@ -550,7 +550,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     let span = infcx.tcx.def_span(*did);
                     if let Ok(snippet) = infcx.tcx.sess.source_map().span_to_snippet(span) {
                         let suggestable_fr_name = if fr_name.was_named() {
-                            format!("{}", fr_name)
+                            fr_name.to_string()
                         } else {
                             "'_".to_string()
                         };
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
index 65ba2f537bf..e07dfda406b 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
@@ -462,9 +462,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         argument_hir_ty: &hir::Ty,
         counter: &mut usize,
     ) -> Option<RegionName> {
-        let search_stack: &mut Vec<(Ty<'tcx>, &hir::Ty)> = &mut Vec::new();
-
-        search_stack.push((argument_ty, argument_hir_ty));
+        let search_stack: &mut Vec<(Ty<'tcx>, &hir::Ty)> =
+            &mut vec![(argument_ty, argument_hir_ty)];
 
         while let Some((ty, hir_ty)) = search_stack.pop() {
             match (&ty.sty, &hir_ty.node) {
@@ -567,10 +566,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             | hir::LifetimeName::Underscore => {
                 let region_name = self.synthesize_region_name(counter);
                 let ampersand_span = lifetime.span;
-                return Some(RegionName {
+                Some(RegionName {
                     name: region_name,
                     source: RegionNameSource::MatchedAdtAndSegment(ampersand_span),
-                });
+                })
             }
 
             hir::LifetimeName::Implicit => {
@@ -585,7 +584,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 // T>`. We don't consider this a match; instead we let
                 // the "fully elaborated" type fallback above handle
                 // it.
-                return None;
+                None
             }
         }
     }
diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs
index f4ddfa5293e..f5e824b7628 100644
--- a/src/librustc_mir/interpret/cast.rs
+++ b/src/librustc_mir/interpret/cast.rs
@@ -327,12 +327,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
             }
             (_, &ty::Dynamic(ref data, _)) => {
                 // Initial cast from sized to dyn trait
-                let trait_ref = data.principal().with_self_ty(
-                    *self.tcx,
-                    src_pointee_ty,
-                );
-                let trait_ref = self.tcx.erase_regions(&trait_ref);
-                let vtable = self.get_vtable(src_pointee_ty, trait_ref)?;
+                let vtable = self.get_vtable(src_pointee_ty, data.principal())?;
                 let ptr = self.read_value(src)?.to_scalar_ptr()?;
                 let val = Value::new_dyn_trait(ptr, vtable);
                 self.write_value(val, dest)
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 85a8376134a..cf5358a9896 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -27,6 +27,7 @@ use rustc::mir::interpret::{
     EvalResult, EvalErrorKind,
     truncate, sign_extend,
 };
+use rustc_data_structures::fx::FxHashMap;
 
 use syntax::source_map::{self, Span};
 
@@ -50,6 +51,9 @@ pub struct EvalContext<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> {
 
     /// The virtual call stack.
     pub(crate) stack: Vec<Frame<'mir, 'tcx, M::PointerTag>>,
+
+    /// A cache for deduplicating vtables
+    pub(super) vtables: FxHashMap<(Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>), AllocId>,
 }
 
 /// A stack frame.
@@ -209,6 +213,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
             param_env,
             memory: Memory::new(tcx, memory_data),
             stack: Vec::new(),
+            vtables: FxHashMap::default(),
         }
     }
 
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index c72a5894b6a..2d6b19ca4a7 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -688,9 +688,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
         rval: OpTy<'tcx, M::PointerTag>,
     ) -> EvalResult<'tcx, (u128, usize)> {
         trace!("read_discriminant_value {:#?}", rval.layout);
-        if rval.layout.abi.is_uninhabited() {
-            return err!(Unreachable);
-        }
 
         match rval.layout.variants {
             layout::Variants::Single { index } => {
diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs
index 227c85772d2..2b0febc1ce7 100644
--- a/src/librustc_mir/interpret/traits.rs
+++ b/src/librustc_mir/interpret/traits.rs
@@ -24,20 +24,32 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
     pub fn get_vtable(
         &mut self,
         ty: Ty<'tcx>,
-        trait_ref: ty::PolyTraitRef<'tcx>,
+        poly_trait_ref: ty::PolyExistentialTraitRef<'tcx>,
     ) -> EvalResult<'tcx, Pointer<M::PointerTag>> {
-        debug!("get_vtable(trait_ref={:?})", trait_ref);
+        debug!("get_vtable(trait_ref={:?})", poly_trait_ref);
 
-        // FIXME: Cache this!
+        let (ty, poly_trait_ref) = self.tcx.erase_regions(&(ty, poly_trait_ref));
 
-        let layout = self.layout_of(trait_ref.self_ty())?;
+        if let Some(&vtable) = self.vtables.get(&(ty, poly_trait_ref)) {
+            return Ok(Pointer::from(vtable).with_default_tag());
+        }
+
+        let trait_ref = poly_trait_ref.with_self_ty(*self.tcx, ty);
+        let trait_ref = self.tcx.erase_regions(&trait_ref);
+
+        let methods = self.tcx.vtable_methods(trait_ref);
+
+        let layout = self.layout_of(ty)?;
         assert!(!layout.is_unsized(), "can't create a vtable for an unsized type");
         let size = layout.size.bytes();
         let align = layout.align.abi();
 
         let ptr_size = self.pointer_size();
         let ptr_align = self.tcx.data_layout.pointer_align;
-        let methods = self.tcx.vtable_methods(trait_ref);
+        // /////////////////////////////////////////////////////////////////////////////////////////
+        // If you touch this code, be sure to also make the corresponding changes to
+        // `get_vtable` in rust_codegen_llvm/meth.rs
+        // /////////////////////////////////////////////////////////////////////////////////////////
         let vtable = self.memory.allocate(
             ptr_size * (3 + methods.len() as u64),
             ptr_align,
@@ -64,6 +76,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
         }
 
         self.memory.mark_immutable(vtable.alloc_id)?;
+        assert!(self.vtables.insert((ty, poly_trait_ref), vtable.alloc_id).is_none());
 
         Ok(vtable)
     }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 86fe584dc3a..ac0616e50b0 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1980,9 +1980,15 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
         }
 
         if !module.no_implicit_prelude {
-            // `record_used` means that we don't try to load crates during speculative resolution
-            if record_used && ns == TypeNS && self.extern_prelude.contains(&ident.name) {
-                let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span);
+            if ns == TypeNS && self.extern_prelude.contains(&ident.name) {
+                let crate_id = if record_used {
+                    self.crate_loader.process_path_extern(ident.name, ident.span)
+                } else if let Some(crate_id) =
+                        self.crate_loader.maybe_process_path_extern(ident.name, ident.span) {
+                    crate_id
+                } else {
+                    return None;
+                };
                 let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
                 self.populate_module_if_necessary(&crate_root);
 
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 7643aade83b..445fc2e833a 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -553,6 +553,9 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt:
             f.write_str(name)
         }
         clean::ResolvedPath{ did, ref typarams, ref path, is_generic } => {
+            if typarams.is_some() {
+                f.write_str("dyn ")?;
+            }
             // Paths like T::Output and Self::Output should be rendered with all segments
             resolved_path(f, did, path, is_generic, use_absolute)?;
             tybounds(f, typarams)
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 582f31ce7c7..6868c7707ad 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -83,6 +83,7 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
             <div class=\"search-container\">\
                 <input class=\"search-input\" name=\"search\" \
                        autocomplete=\"off\" \
+                       spellcheck=\"false\" \
                        placeholder=\"Click or press ‘S’ to search, ‘?’ for more options…\" \
                        type=\"search\">\
                 <a id=\"settings-menu\" href=\"{root_path}settings.html\">\
diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index 4ef8349fa9c..e10e330402f 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -26,8 +26,26 @@ function onEach(arr, func) {
     return false;
 }
 
+function usableLocalStorage() {
+    // Check if the browser supports localStorage at all:
+    if (typeof(Storage) === "undefined") {
+        return false;
+    }
+    // Check if we can access it; this access will fail if the browser
+    // preferences deny access to localStorage, e.g., to prevent storage of
+    // "cookies" (or cookie-likes, as is the case here).
+    try {
+        window.localStorage;
+    } catch(err) {
+        // Storage is supported, but browser preferences deny access to it.
+        return false;
+    }
+
+    return true;
+}
+
 function updateLocalStorage(name, value) {
-    if (typeof(Storage) !== "undefined") {
+    if (usableLocalStorage()) {
         localStorage[name] = value;
     } else {
         // No Web Storage support so we do nothing
@@ -35,7 +53,7 @@ function updateLocalStorage(name, value) {
 }
 
 function getCurrentValue(name) {
-    if (typeof(Storage) !== "undefined" && localStorage[name] !== undefined) {
+    if (usableLocalStorage() && localStorage[name] !== undefined) {
         return localStorage[name];
     }
     return null;
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 796b2bd3eed..c1f0a6fecef 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -650,15 +650,17 @@ pub fn panicking() -> bool {
     panicking::panicking()
 }
 
-/// Puts the current thread to sleep for the specified amount of time.
+/// Puts the current thread to sleep for at least the specified amount of time.
 ///
 /// The thread may sleep longer than the duration specified due to scheduling
-/// specifics or platform-dependent functionality.
+/// specifics or platform-dependent functionality. It will never sleep less.
 ///
 /// # Platform-specific behavior
 ///
-/// On Unix platforms this function will not return early due to a
-/// signal being received or a spurious wakeup.
+/// On Unix platforms, the underlying syscall may be interrupted by a
+/// spurious wakeup or signal handler. To ensure the sleep occurs for at least
+/// the specified duration, this function may invoke that system call multiple
+/// times.
 ///
 /// # Examples
 ///
@@ -674,17 +676,19 @@ pub fn sleep_ms(ms: u32) {
     sleep(Duration::from_millis(ms as u64))
 }
 
-/// Puts the current thread to sleep for the specified amount of time.
+/// Puts the current thread to sleep for at least the specified amount of time.
 ///
 /// The thread may sleep longer than the duration specified due to scheduling
-/// specifics or platform-dependent functionality.
+/// specifics or platform-dependent functionality. It will never sleep less.
 ///
 /// # Platform-specific behavior
 ///
-/// On Unix platforms this function will not return early due to a
-/// signal being received or a spurious wakeup. Platforms which do not support
-/// nanosecond precision for sleeping will have `dur` rounded up to the nearest
-/// granularity of time they can sleep for.
+/// On Unix platforms, the underlying syscall may be interrupted by a
+/// spurious wakeup or signal handler. To ensure the sleep occurs for at least
+/// the specified duration, this function may invoke that system call multiple
+/// times.
+/// Platforms which do not support nanosecond precision for sleeping will
+/// have `dur` rounded up to the nearest granularity of time they can sleep for.
 ///
 /// # Examples
 ///
diff --git a/src/test/debuginfo/lexical-scope-with-macro.rs b/src/test/debuginfo/lexical-scope-with-macro.rs
index 4e88f65ad1d..d11a42bb0ed 100644
--- a/src/test/debuginfo/lexical-scope-with-macro.rs
+++ b/src/test/debuginfo/lexical-scope-with-macro.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // min-lldb-version: 310
-// ignore-macos FIXME #48807
+// ignore-lldb FIXME #48807
 
 // compile-flags:-g -Zdebug-macros
 
diff --git a/src/test/run-pass/extern/extern-prelude-no-speculative.rs b/src/test/run-pass/extern/extern-prelude-no-speculative.rs
index 6ca1815a191..372f34454de 100644
--- a/src/test/run-pass/extern/extern-prelude-no-speculative.rs
+++ b/src/test/run-pass/extern/extern-prelude-no-speculative.rs
@@ -10,7 +10,7 @@
 
 // run-pass
 #![allow(unused_variables)]
-// compile-flags: --extern LooksLikeExternCrate=/path/to/nowhere
+// compile-flags: --extern LooksLikeExternCrate
 
 mod m {
     pub struct LooksLikeExternCrate;
diff --git a/src/test/rustdoc/assoc-consts.rs b/src/test/rustdoc/assoc-consts.rs
index 71e7db5f4a5..cbb2a00214a 100644
--- a/src/test/rustdoc/assoc-consts.rs
+++ b/src/test/rustdoc/assoc-consts.rs
@@ -52,7 +52,7 @@ pub fn f(_: &(ToString + 'static)) {}
 
 impl Bar {
     // @has assoc_consts/struct.Bar.html '//*[@id="associatedconstant.F"]' \
-    //      "const F: fn(_: &(ToString + 'static))"
+    //      "const F: fn(_: &(dyn ToString + 'static))"
     pub const F: fn(_: &(ToString + 'static)) = f;
 }
 
diff --git a/src/test/rustdoc/inline_cross/issue-32881.rs b/src/test/rustdoc/inline_cross/issue-32881.rs
index 948061bdcbe..c55a69bcb7b 100644
--- a/src/test/rustdoc/inline_cross/issue-32881.rs
+++ b/src/test/rustdoc/inline_cross/issue-32881.rs
@@ -15,8 +15,8 @@
 extern crate rustdoc_trait_object_impl;
 
 // @has issue_32881/trait.Bar.html
-// @has - '//code' "impl<'a> Bar"
-// @has - '//code' "impl<'a> Debug for Bar"
+// @has - '//code' "impl<'a> dyn Bar"
+// @has - '//code' "impl<'a> Debug for dyn Bar"
 
 pub use rustdoc_trait_object_impl::Bar;
 
diff --git a/src/test/rustdoc/test-parens.rs b/src/test/rustdoc/test-parens.rs
index 792dc9c218d..0c9452fa1e1 100644
--- a/src/test/rustdoc/test-parens.rs
+++ b/src/test/rustdoc/test-parens.rs
@@ -11,5 +11,5 @@
 #![crate_name = "foo"]
 
 // @has foo/fn.foo.html
-// @has - '//*[@class="rust fn"]' "_: &(ToString + 'static)"
+// @has - '//*[@class="rust fn"]' "_: &(dyn ToString + 'static)"
 pub fn foo(_: &(ToString + 'static)) {}
diff --git a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs
new file mode 100644
index 00000000000..0749900986d
--- /dev/null
+++ b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.rs
@@ -0,0 +1,22 @@
+#![feature(nll)]
+
+#![allow(dead_code)]
+
+#[derive(Debug)]
+struct Value;
+impl Value {
+    fn as_array(&self) -> Option<&Vec<Value>> {
+        None
+    }
+}
+
+fn foo(val: Value) {
+    let _reviewers_original: Vec<Value> = match val.as_array() {
+        Some(array) => {
+            *array
+        }
+        None => vec![]
+    };
+}
+
+fn main() { }
diff --git a/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr
new file mode 100644
index 00000000000..6a12016b2a5
--- /dev/null
+++ b/src/test/ui/borrowck/issue-54597-reject-move-out-of-borrow-via-pat.stderr
@@ -0,0 +1,12 @@
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/issue-54597-reject-move-out-of-borrow-via-pat.rs:16:13
+   |
+LL |             *array
+   |             ^^^^^^
+   |             |
+   |             cannot move out of borrowed content
+   |             help: consider removing the `*`: `array`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.
diff --git a/src/test/ui/impl-trait/auxiliary/extra-item.rs b/src/test/ui/impl-trait/auxiliary/extra-item.rs
new file mode 100644
index 00000000000..8eaeafa5207
--- /dev/null
+++ b/src/test/ui/impl-trait/auxiliary/extra-item.rs
@@ -0,0 +1 @@
+pub trait MyTrait {}
diff --git a/src/test/ui/impl-trait/extra-item.rs b/src/test/ui/impl-trait/extra-item.rs
new file mode 100644
index 00000000000..d82237ccecc
--- /dev/null
+++ b/src/test/ui/impl-trait/extra-item.rs
@@ -0,0 +1,10 @@
+// aux-build:extra-item.rs
+// compile-flags:--extern extra_item
+
+struct S;
+
+impl extra_item::MyTrait for S {
+    fn extra() {} //~ ERROR method `extra` is not a member of trait `extra_item::MyTrait`
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/extra-item.stderr b/src/test/ui/impl-trait/extra-item.stderr
new file mode 100644
index 00000000000..de3c7ba5d31
--- /dev/null
+++ b/src/test/ui/impl-trait/extra-item.stderr
@@ -0,0 +1,9 @@
+error[E0407]: method `extra` is not a member of trait `extra_item::MyTrait`
+  --> $DIR/extra-item.rs:7:5
+   |
+LL |     fn extra() {} //~ ERROR method `extra` is not a member of trait `extra_item::MyTrait`
+   |     ^^^^^^^^^^^^^ not a member of trait `extra_item::MyTrait`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0407`.
diff --git a/src/test/ui/issues/issue-34229.rs b/src/test/ui/issues/issue-34229.rs
new file mode 100644
index 00000000000..bcdfcc767fb
--- /dev/null
+++ b/src/test/ui/issues/issue-34229.rs
@@ -0,0 +1,4 @@
+#[derive(PartialEq)] struct Comparable;
+#[derive(PartialEq, PartialOrd)] struct Nope(Comparable);
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-34229.stderr b/src/test/ui/issues/issue-34229.stderr
new file mode 100644
index 00000000000..c57f80cd409
--- /dev/null
+++ b/src/test/ui/issues/issue-34229.stderr
@@ -0,0 +1,12 @@
+error[E0277]: can't compare `Comparable` with `Comparable`
+  --> $DIR/issue-34229.rs:2:46
+   |
+LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable);
+   |                                              ^^^^^^^^^^ no implementation for `Comparable < Comparable` and `Comparable > Comparable`
+   |
+   = help: the trait `std::cmp::PartialOrd` is not implemented for `Comparable`
+   = note: required by `std::cmp::PartialOrd::partial_cmp`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 7006fb9427e..fab2ea7ba6c 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -25,6 +25,7 @@ pub enum Mode {
     RunPass,
     RunPassValgrind,
     Pretty,
+    DebugInfoBoth,
     DebugInfoGdb,
     DebugInfoLldb,
     Codegen,
@@ -60,6 +61,7 @@ impl FromStr for Mode {
             "run-pass" => Ok(RunPass),
             "run-pass-valgrind" => Ok(RunPassValgrind),
             "pretty" => Ok(Pretty),
+            "debuginfo-both" => Ok(DebugInfoBoth),
             "debuginfo-lldb" => Ok(DebugInfoLldb),
             "debuginfo-gdb" => Ok(DebugInfoGdb),
             "codegen" => Ok(Codegen),
@@ -83,6 +85,7 @@ impl fmt::Display for Mode {
             RunPass => "run-pass",
             RunPassValgrind => "run-pass-valgrind",
             Pretty => "pretty",
+            DebugInfoBoth => "debuginfo-both",
             DebugInfoGdb => "debuginfo-gdb",
             DebugInfoLldb => "debuginfo-lldb",
             Codegen => "codegen",
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 688f2babe6e..06eeef61a19 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -19,10 +19,62 @@ use util;
 
 use extract_gdb_version;
 
+/// Whether to ignore the test.
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub enum Ignore {
+    /// Run it.
+    Run,
+    /// Ignore it totally.
+    Ignore,
+    /// Ignore only the gdb test, but run the lldb test.
+    IgnoreGdb,
+    /// Ignore only the lldb test, but run the gdb test.
+    IgnoreLldb,
+}
+
+impl Ignore {
+    pub fn can_run_gdb(&self) -> bool {
+        *self == Ignore::Run || *self == Ignore::IgnoreLldb
+    }
+
+    pub fn can_run_lldb(&self) -> bool {
+        *self == Ignore::Run || *self == Ignore::IgnoreGdb
+    }
+
+    pub fn no_gdb(&self) -> Ignore {
+        match *self {
+            Ignore::Run => Ignore::IgnoreGdb,
+            Ignore::IgnoreGdb => Ignore::IgnoreGdb,
+            _ => Ignore::Ignore,
+        }
+    }
+
+    pub fn no_lldb(&self) -> Ignore {
+        match *self {
+            Ignore::Run => Ignore::IgnoreLldb,
+            Ignore::IgnoreLldb => Ignore::IgnoreLldb,
+            _ => Ignore::Ignore,
+        }
+    }
+}
+
+/// The result of parse_cfg_name_directive.
+#[derive(Clone, Copy, PartialEq, Debug)]
+enum ParsedNameDirective {
+    /// No match.
+    NoMatch,
+    /// Match.
+    Match,
+    /// Mode was DebugInfoBoth and this matched gdb.
+    MatchGdb,
+    /// Mode was DebugInfoBoth and this matched lldb.
+    MatchLldb,
+}
+
 /// Properties which must be known very early, before actually running
 /// the test.
 pub struct EarlyProps {
-    pub ignore: bool,
+    pub ignore: Ignore,
     pub should_fail: bool,
     pub aux: Vec<String>,
     pub revisions: Vec<String>,
@@ -31,20 +83,55 @@ pub struct EarlyProps {
 impl EarlyProps {
     pub fn from_file(config: &Config, testfile: &Path) -> Self {
         let mut props = EarlyProps {
-            ignore: false,
+            ignore: Ignore::Run,
             should_fail: false,
             aux: Vec::new(),
             revisions: vec![],
         };
 
+        if config.mode == common::DebugInfoBoth {
+            if config.lldb_python_dir.is_none() {
+                props.ignore = props.ignore.no_lldb();
+            }
+            if config.gdb_version.is_none() {
+                props.ignore = props.ignore.no_gdb();
+            }
+        }
+
         iter_header(testfile, None, &mut |ln| {
             // we should check if any only-<platform> exists and if it exists
             // and does not matches the current platform, skip the test
-            props.ignore = props.ignore || config.parse_cfg_name_directive(ln, "ignore")
-                || (config.has_cfg_prefix(ln, "only")
-                    && !config.parse_cfg_name_directive(ln, "only"))
-                || ignore_gdb(config, ln) || ignore_lldb(config, ln)
-                || ignore_llvm(config, ln);
+            if props.ignore != Ignore::Ignore {
+                props.ignore = match config.parse_cfg_name_directive(ln, "ignore") {
+                    ParsedNameDirective::Match => Ignore::Ignore,
+                    ParsedNameDirective::NoMatch => props.ignore,
+                    ParsedNameDirective::MatchGdb => props.ignore.no_gdb(),
+                    ParsedNameDirective::MatchLldb => props.ignore.no_lldb(),
+                };
+
+                if config.has_cfg_prefix(ln, "only") {
+                    props.ignore = match config.parse_cfg_name_directive(ln, "only") {
+                        ParsedNameDirective::Match => props.ignore,
+                        ParsedNameDirective::NoMatch => Ignore::Ignore,
+                        ParsedNameDirective::MatchLldb => props.ignore.no_gdb(),
+                        ParsedNameDirective::MatchGdb => props.ignore.no_lldb(),
+                    };
+                }
+
+                if ignore_llvm(config, ln) {
+                    props.ignore = Ignore::Ignore;
+                }
+            }
+
+            if (config.mode == common::DebugInfoGdb || config.mode == common::DebugInfoBoth) &&
+                props.ignore.can_run_gdb() && ignore_gdb(config, ln) {
+                props.ignore = props.ignore.no_gdb();
+            }
+
+            if (config.mode == common::DebugInfoLldb || config.mode == common::DebugInfoBoth) &&
+                props.ignore.can_run_lldb() && ignore_lldb(config, ln) {
+                props.ignore = props.ignore.no_lldb();
+            }
 
             if let Some(s) = config.parse_aux_build(ln) {
                 props.aux.push(s);
@@ -60,10 +147,6 @@ impl EarlyProps {
         return props;
 
         fn ignore_gdb(config: &Config, line: &str) -> bool {
-            if config.mode != common::DebugInfoGdb {
-                return false;
-            }
-
             if let Some(actual_version) = config.gdb_version {
                 if line.starts_with("min-gdb-version") {
                     let (start_ver, end_ver) = extract_gdb_version_range(line);
@@ -120,10 +203,6 @@ impl EarlyProps {
         }
 
         fn ignore_lldb(config: &Config, line: &str) -> bool {
-            if config.mode != common::DebugInfoLldb {
-                return false;
-            }
-
             if let Some(ref actual_version) = config.lldb_version {
                 if line.starts_with("min-lldb-version") {
                     let min_version = line.trim_right()
@@ -604,7 +683,7 @@ impl Config {
     }
 
     fn parse_custom_normalization(&self, mut line: &str, prefix: &str) -> Option<(String, String)> {
-        if self.parse_cfg_name_directive(line, prefix) {
+        if self.parse_cfg_name_directive(line, prefix) == ParsedNameDirective::Match {
             let from = match parse_normalization_string(&mut line) {
                 Some(s) => s,
                 None => return None,
@@ -620,35 +699,59 @@ impl Config {
     }
 
     /// Parses a name-value directive which contains config-specific information, e.g. `ignore-x86`
-    /// or `normalize-stderr-32bit`. Returns `true` if the line matches it.
-    fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> bool {
+    /// or `normalize-stderr-32bit`.
+    fn parse_cfg_name_directive(&self, line: &str, prefix: &str) -> ParsedNameDirective {
         if line.starts_with(prefix) && line.as_bytes().get(prefix.len()) == Some(&b'-') {
             let name = line[prefix.len() + 1..]
                 .split(&[':', ' '][..])
                 .next()
                 .unwrap();
 
-            name == "test" ||
+            if name == "test" ||
                 util::matches_os(&self.target, name) ||             // target
                 name == util::get_arch(&self.target) ||             // architecture
                 name == util::get_pointer_width(&self.target) ||    // pointer width
                 name == self.stage_id.split('-').next().unwrap() || // stage
                 Some(name) == util::get_env(&self.target) ||        // env
-                match self.mode {
-                    common::DebugInfoGdb => name == "gdb",
-                    common::DebugInfoLldb => name == "lldb",
-                    common::Pretty => name == "pretty",
-                    _ => false,
-                } ||
                 (self.target != self.host && name == "cross-compile") ||
                 match self.compare_mode {
                     Some(CompareMode::Nll) => name == "compare-mode-nll",
                     Some(CompareMode::Polonius) => name == "compare-mode-polonius",
                     None => false,
                 } ||
-                (cfg!(debug_assertions) && name == "debug")
+                (cfg!(debug_assertions) && name == "debug") {
+                ParsedNameDirective::Match
+            } else {
+                match self.mode {
+                    common::DebugInfoBoth => {
+                        if name == "gdb" {
+                            ParsedNameDirective::MatchGdb
+                        } else if name == "lldb" {
+                            ParsedNameDirective::MatchLldb
+                        } else {
+                            ParsedNameDirective::NoMatch
+                        }
+                    },
+                    common::DebugInfoGdb => if name == "gdb" {
+                        ParsedNameDirective::Match
+                    } else {
+                        ParsedNameDirective::NoMatch
+                    },
+                    common::DebugInfoLldb => if name == "lldb" {
+                        ParsedNameDirective::Match
+                    } else {
+                        ParsedNameDirective::NoMatch
+                    },
+                    common::Pretty => if name == "pretty" {
+                        ParsedNameDirective::Match
+                    } else {
+                        ParsedNameDirective::NoMatch
+                    },
+                    _ => ParsedNameDirective::NoMatch,
+                }
+            }
         } else {
-            false
+            ParsedNameDirective::NoMatch
         }
     }
 
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index f46e031d768..c931d3c0e30 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -32,7 +32,7 @@ extern crate rustfix;
 use common::CompareMode;
 use common::{expected_output_path, output_base_dir, output_relative_path, UI_EXTENSIONS};
 use common::{Config, TestPaths};
-use common::{DebugInfoGdb, DebugInfoLldb, Mode, Pretty};
+use common::{DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Mode, Pretty};
 use filetime::FileTime;
 use getopts::Options;
 use std::env;
@@ -44,7 +44,7 @@ use std::process::Command;
 use test::ColorConfig;
 use util::logv;
 
-use self::header::EarlyProps;
+use self::header::{EarlyProps, Ignore};
 
 pub mod common;
 pub mod errors;
@@ -425,7 +425,7 @@ pub fn opt_str2(maybestr: Option<String>) -> String {
 
 pub fn run_tests(config: &Config) {
     if config.target.contains("android") {
-        if let DebugInfoGdb = config.mode {
+        if config.mode == DebugInfoGdb || config.mode == DebugInfoBoth {
             println!(
                 "{} debug-info test uses tcp 5039 port.\
                  please reserve it",
@@ -443,7 +443,9 @@ pub fn run_tests(config: &Config) {
     }
 
     match config.mode {
-        DebugInfoLldb => {
+        // Note that we don't need to emit the gdb warning when
+        // DebugInfoBoth, so it is ok to list that here.
+        DebugInfoBoth | DebugInfoLldb => {
             if let Some(lldb_version) = config.lldb_version.as_ref() {
                 if is_blacklisted_lldb_version(&lldb_version[..]) {
                     println!(
@@ -647,15 +649,18 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> Vec<test::TestDescAn
         .into_iter()
         .map(|revision| {
             // Debugging emscripten code doesn't make sense today
-            let ignore = early_props.ignore
+            let ignore = early_props.ignore == Ignore::Ignore
                 || !up_to_date(
                     config,
                     testpaths,
                     &early_props,
                     revision.map(|s| s.as_str()),
                 )
-                || (config.mode == DebugInfoGdb || config.mode == DebugInfoLldb)
-                    && config.target.contains("emscripten");
+                || ((config.mode == DebugInfoBoth ||
+                     config.mode == DebugInfoGdb || config.mode == DebugInfoLldb)
+                    && config.target.contains("emscripten"))
+                || (config.mode == DebugInfoGdb && !early_props.ignore.can_run_gdb())
+                || (config.mode == DebugInfoLldb && !early_props.ignore.can_run_lldb());
             test::TestDescAndFn {
                 desc: test::TestDesc {
                     name: make_test_name(config, testpaths, revision),
@@ -663,7 +668,7 @@ pub fn make_test(config: &Config, testpaths: &TestPaths) -> Vec<test::TestDescAn
                     should_panic,
                     allow_fail: false,
                 },
-                testfn: make_test_closure(config, testpaths, revision),
+                testfn: make_test_closure(config, early_props.ignore, testpaths, revision),
             }
         })
         .collect()
@@ -774,10 +779,21 @@ fn make_test_name(
 
 fn make_test_closure(
     config: &Config,
+    ignore: Ignore,
     testpaths: &TestPaths,
     revision: Option<&String>,
 ) -> test::TestFn {
-    let config = config.clone();
+    let mut config = config.clone();
+    if config.mode == DebugInfoBoth {
+        // If both gdb and lldb were ignored, then the test as a whole
+        // would be ignored.
+        if !ignore.can_run_gdb() {
+            config.mode = DebugInfoLldb;
+        } else if !ignore.can_run_lldb() {
+            config.mode = DebugInfoGdb;
+        }
+    }
+
     let testpaths = testpaths.clone();
     let revision = revision.cloned();
     test::DynTestFn(Box::new(move || {
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index c69956030c0..8c3b1bb4df3 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -11,7 +11,7 @@
 use common::CompareMode;
 use common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT};
 use common::{output_base_dir, output_base_name, output_testname_unique};
-use common::{Codegen, CodegenUnits, DebugInfoGdb, DebugInfoLldb, Rustdoc};
+use common::{Codegen, CodegenUnits, DebugInfoBoth, DebugInfoGdb, DebugInfoLldb, Rustdoc};
 use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
 use common::{Config, TestPaths};
 use common::{Incremental, MirOpt, RunMake, Ui};
@@ -225,19 +225,20 @@ pub fn run(config: Config, testpaths: &TestPaths, revision: Option<&str>) {
 pub fn compute_stamp_hash(config: &Config) -> String {
     let mut hash = DefaultHasher::new();
     config.stage_id.hash(&mut hash);
-    match config.mode {
-        DebugInfoGdb => match config.gdb {
+
+    if config.mode == DebugInfoGdb || config.mode == DebugInfoBoth {
+        match config.gdb {
             None => env::var_os("PATH").hash(&mut hash),
             Some(ref s) if s.is_empty() => env::var_os("PATH").hash(&mut hash),
             Some(ref s) => s.hash(&mut hash),
-        },
-        DebugInfoLldb => {
-            env::var_os("PATH").hash(&mut hash);
-            env::var_os("PYTHONPATH").hash(&mut hash);
-        },
+        };
+    }
+
+    if config.mode == DebugInfoLldb || config.mode == DebugInfoBoth {
+        env::var_os("PATH").hash(&mut hash);
+        env::var_os("PYTHONPATH").hash(&mut hash);
+    }
 
-        _ => {},
-    };
     format!("{:x}", hash.finish())
 }
 
@@ -268,6 +269,10 @@ impl<'test> TestCx<'test> {
             RunFail => self.run_rfail_test(),
             RunPassValgrind => self.run_valgrind_test(),
             Pretty => self.run_pretty_test(),
+            DebugInfoBoth => {
+                self.run_debuginfo_gdb_test();
+                self.run_debuginfo_lldb_test();
+            },
             DebugInfoGdb => self.run_debuginfo_gdb_test(),
             DebugInfoLldb => self.run_debuginfo_lldb_test(),
             Codegen => self.run_codegen_test(),
@@ -640,6 +645,7 @@ impl<'test> TestCx<'test> {
         let config = Config {
             target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
             host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
+            mode: DebugInfoGdb,
             ..self.config.clone()
         };
 
@@ -910,6 +916,7 @@ impl<'test> TestCx<'test> {
         let config = Config {
             target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
             host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
+            mode: DebugInfoLldb,
             ..self.config.clone()
         };
 
@@ -1774,7 +1781,7 @@ impl<'test> TestCx<'test> {
 
                 rustc.arg(dir_opt);
             }
-            RunFail | RunPassValgrind | Pretty | DebugInfoGdb | DebugInfoLldb
+            RunFail | RunPassValgrind | Pretty | DebugInfoBoth | DebugInfoGdb | DebugInfoLldb
             | Codegen | Rustdoc | RunMake | CodegenUnits => {
                 // do not use JSON output
             }