about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/Cargo.lock21
-rw-r--r--src/bootstrap/dist.rs6
-rw-r--r--src/bootstrap/lib.rs3
-rw-r--r--src/liballoc/fmt.rs2
-rw-r--r--src/liballoc/rc.rs4
-rw-r--r--src/liballoc/sync.rs4
-rw-r--r--src/librustc/traits/coherence.rs10
-rw-r--r--src/librustc/traits/select.rs27
-rw-r--r--src/librustc/ty/error.rs3
-rw-r--r--src/librustc/ty/fast_reject.rs2
-rw-r--r--src/librustc/ty/item_path.rs2
-rw-r--r--src/librustc/ty/sty.rs16
-rw-r--r--src/librustc/ty/wf.rs2
-rw-r--r--src/librustc/util/ppaux.rs20
-rw-r--r--src/librustc_codegen_llvm/abi.rs5
-rw-r--r--src/librustc_codegen_llvm/context.rs2
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs7
-rw-r--r--src/librustc_codegen_llvm/debuginfo/type_names.rs14
-rw-r--r--src/librustc_codegen_llvm/meth.rs24
-rw-r--r--src/librustc_driver/driver.rs65
-rw-r--r--src/librustc_driver/lib.rs174
-rw-r--r--src/librustc_driver/pretty.rs56
-rw-r--r--src/librustc_driver/profile/mod.rs43
-rw-r--r--src/librustc_driver/profile/trace.rs116
-rw-r--r--src/librustc_lint/unused.rs9
-rw-r--r--src/librustc_mir/interpret/cast.rs2
-rw-r--r--src/librustc_mir/monomorphize/collector.rs30
-rw-r--r--src/librustc_mir/monomorphize/item.rs13
-rw-r--r--src/librustc_mir/transform/inline.rs23
-rw-r--r--src/librustc_privacy/lib.rs7
-rw-r--r--src/librustc_target/spec/mod.rs9
-rw-r--r--src/librustc_target/spec/wasm32_unknown_unknown.rs6
-rw-r--r--src/librustc_typeck/check/cast.rs4
-rw-r--r--src/librustc_typeck/check/closure.rs4
-rw-r--r--src/librustc_typeck/check/method/confirm.rs2
-rw-r--r--src/librustc_typeck/check/method/probe.rs7
-rw-r--r--src/librustc_typeck/check/method/suggest.rs3
-rw-r--r--src/librustc_typeck/coherence/inherent_impls.rs4
-rw-r--r--src/librustc_typeck/coherence/mod.rs5
-rw-r--r--src/librustc_typeck/outlives/implicit_infer.rs43
-rw-r--r--src/librustc_typeck/variance/constraints.rs10
-rw-r--r--src/librustdoc/clean/mod.rs73
-rw-r--r--src/libstd/Cargo.toml9
-rw-r--r--src/libstd/sys/wasm/mutex_atomics.rs23
-rw-r--r--src/libstd/sys/wasm/thread.rs46
-rw-r--r--src/libstd/sys/wasm/thread_local_atomics.rs53
-rw-r--r--src/libstd/thread/local.rs14
-rw-r--r--src/libstd/thread/mod.rs2
-rw-r--r--src/libsyntax/feature_gate.rs10
-rw-r--r--src/libsyntax/parse/parser.rs8
-rw-r--r--src/stage0.txt2
-rw-r--r--src/test/mir-opt/inline-trait-method.rs31
-rw-r--r--src/test/run-pass/resolve-pseudo-shadowing.rs2
-rw-r--r--src/test/ui/closure-expected-type/README.md1
-rw-r--r--src/test/ui/closure-expected-type/issue-24421.rs20
-rw-r--r--src/test/ui/feature-gate-underscore_const_names.rs24
-rw-r--r--src/test/ui/feature-gate-underscore_const_names.stderr16
-rw-r--r--src/test/ui/fn_must_use.rs8
-rw-r--r--src/test/ui/fn_must_use.stderr20
-rw-r--r--src/test/ui/issues/issue-52240.nll.stderr9
-rw-r--r--src/test/ui/issues/issue-52240.rs16
-rw-r--r--src/test/ui/issues/issue-52240.stderr9
-rw-r--r--src/test/ui/issues/issue-54966.rs6
-rw-r--r--src/test/ui/issues/issue-54966.stderr9
-rw-r--r--src/test/ui/underscore_const_names.rs43
m---------src/tools/cargo0
m---------src/tools/clippy24
m---------src/tools/miri24
m---------src/tools/rls0
69 files changed, 787 insertions, 524 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock
index abe736a4fe6..52314b0ac89 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -204,7 +204,7 @@ dependencies = [
  "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fwdansi 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "git2 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -737,7 +737,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "flate2"
-version = "1.0.2"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -959,7 +959,7 @@ version = "0.0.0"
 dependencies = [
  "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1649,7 +1649,7 @@ dependencies = [
 
 [[package]]
 name = "racer"
-version = "2.1.6"
+version = "2.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1797,7 +1797,7 @@ dependencies = [
  "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "racer 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "racer 2.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1814,6 +1814,7 @@ dependencies = [
  "serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1889,7 +1890,7 @@ dependencies = [
  "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fmt_macros 0.0.0",
  "graphviz 0.0.0",
  "jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2133,7 +2134,7 @@ dependencies = [
 name = "rustc_codegen_utils"
 version = "0.0.0"
 dependencies = [
- "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_data_structures 0.0.0",
@@ -2276,7 +2277,7 @@ dependencies = [
 name = "rustc_metadata"
 version = "0.0.0"
 dependencies = [
- "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc_macro 0.0.0",
  "rustc 0.0.0",
@@ -3222,7 +3223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426"
 "checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f"
 "checksum fixedbitset 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33"
-"checksum flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "37847f133aae7acf82bb9577ccd8bda241df836787642654286e79679826a54b"
+"checksum flate2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4af030962d89d62aa52cd9492083b1cd9b2d1a77764878102a6c0f86b4d5444d"
 "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
 "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
 "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
@@ -3319,7 +3320,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
 "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
 "checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
-"checksum racer 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "99e820b7f7701c834c3f6f8226f388c19c0ea948a3ef79ddc96aa7398b5ba87a"
+"checksum racer 2.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0beefbfaed799c3554021a48856113ad53862311395f6d75376192884ba5fbe6"
 "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
 "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
 "checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index c25f94357f2..cf79d4f777a 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -1263,14 +1263,16 @@ impl Step for Clippy {
         builder.install(&cargoclippy, &image.join("bin"), 0o755);
         let doc = image.join("share/doc/clippy");
         builder.install(&src.join("README.md"), &doc, 0o644);
-        builder.install(&src.join("LICENSE"), &doc, 0o644);
+        builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
+        builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
 
         // Prepare the overlay
         let overlay = tmp.join("clippy-overlay");
         drop(fs::remove_dir_all(&overlay));
         t!(fs::create_dir_all(&overlay));
         builder.install(&src.join("README.md"), &overlay, 0o644);
-        builder.install(&src.join("LICENSE"), &doc, 0o644);
+        builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
+        builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
         builder.create(&overlay.join("version"), &version);
 
         // Generate the installer tarball
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 247727762d1..c09de02ab51 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -1288,6 +1288,9 @@ impl Build {
         t!(fs::create_dir_all(dstdir));
         drop(fs::remove_file(&dst));
         {
+            if !src.exists() {
+                panic!("Error: File \"{}\" not found!", src.display());
+            }
             let mut s = t!(fs::File::open(&src));
             let mut d = t!(fs::File::create(&dst));
             io::copy(&mut s, &mut d).expect("failed to copy");
diff --git a/src/liballoc/fmt.rs b/src/liballoc/fmt.rs
index b49ec0ae252..a2e68a223f1 100644
--- a/src/liballoc/fmt.rs
+++ b/src/liballoc/fmt.rs
@@ -152,7 +152,7 @@
 //! Additionally, the return value of this function is [`fmt::Result`] which is a
 //! type alias of [`Result`]`<(), `[`std::fmt::Error`]`>`. Formatting implementations
 //! should ensure that they propagate errors from the [`Formatter`][`Formatter`] (e.g., when
-//! calling [`write!`]) however, they should never return errors spuriously. That
+//! calling [`write!`]). However, they should never return errors spuriously. That
 //! is, a formatting implementation must and may only return an error if the
 //! passed-in [`Formatter`] returns an error. This is because, contrary to what
 //! the function signature might suggest, string formatting is an infallible
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 915b8e7787e..40bb2faa362 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -867,7 +867,7 @@ impl<T: ?Sized> Clone for Rc<T> {
     ///
     /// let five = Rc::new(5);
     ///
-    /// Rc::clone(&five);
+    /// let _ = Rc::clone(&five);
     /// ```
     #[inline]
     fn clone(&self) -> Rc<T> {
@@ -1304,7 +1304,7 @@ impl<T: ?Sized> Clone for Weak<T> {
     ///
     /// let weak_five = Rc::downgrade(&Rc::new(5));
     ///
-    /// Weak::clone(&weak_five);
+    /// let _ = Weak::clone(&weak_five);
     /// ```
     #[inline]
     fn clone(&self) -> Weak<T> {
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 9e245fbd7bb..35935861fb1 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -713,7 +713,7 @@ impl<T: ?Sized> Clone for Arc<T> {
     ///
     /// let five = Arc::new(5);
     ///
-    /// Arc::clone(&five);
+    /// let _ = Arc::clone(&five);
     /// ```
     #[inline]
     fn clone(&self) -> Arc<T> {
@@ -1135,7 +1135,7 @@ impl<T: ?Sized> Clone for Weak<T> {
     ///
     /// let weak_five = Arc::downgrade(&Arc::new(5));
     ///
-    /// Weak::clone(&weak_five);
+    /// let _ = Weak::clone(&weak_five);
     /// ```
     #[inline]
     fn clone(&self) -> Weak<T> {
diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs
index 7add8ef05ee..817e9ffcbb5 100644
--- a/src/librustc/traits/coherence.rs
+++ b/src/librustc/traits/coherence.rs
@@ -418,9 +418,7 @@ fn fundamental_ty(tcx: TyCtxt<'_, '_, '_>, ty: Ty<'_>) -> bool {
     match ty.sty {
         ty::Ref(..) => true,
         ty::Adt(def, _) => def.is_fundamental(),
-        ty::Dynamic(ref data, ..) => {
-            data.principal().map_or(false, |p| tcx.has_attr(p.def_id(), "fundamental"))
-        }
+        ty::Dynamic(ref data, ..) => tcx.has_attr(data.principal().def_id(), "fundamental"),
         _ => false
     }
 }
@@ -467,11 +465,7 @@ fn ty_is_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> bool {
         ty::Adt(def, _) => def_id_is_local(def.did, in_crate),
         ty::Foreign(did) => def_id_is_local(did, in_crate),
 
-        ty::Dynamic(ref tt, ..) => {
-            tt.principal().map_or(false, |p|
-                def_id_is_local(p.def_id(), in_crate)
-            )
-        }
+        ty::Dynamic(ref tt, ..) => def_id_is_local(tt.principal().def_id(), in_crate),
 
         ty::Error => true,
 
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 82d881e10b1..8e8024e51da 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -2088,10 +2088,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                         return;
                     }
 
-                    match data.principal() {
-                        Some(p) => p.with_self_ty(this.tcx(), self_ty),
-                        None => return,
-                    }
+                    data.principal().with_self_ty(this.tcx(), self_ty)
                 }
                 ty::Infer(ty::TyVar(_)) => {
                     debug!("assemble_candidates_from_object_ty: ambiguous");
@@ -2183,15 +2180,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                 //
                 // We always upcast when we can because of reason
                 // #2 (region bounds).
-                match (data_a.principal(), data_b.principal()) {
-                    (Some(a), Some(b)) => {
-                        a.def_id() == b.def_id()
-                            && data_b.auto_traits()
-                            // All of a's auto traits need to be in b's auto traits.
-                            .all(|b| data_a.auto_traits().any(|a| a == b))
-                    }
-                    _ => false,
-                }
+                data_a.principal().def_id() == data_b.principal().def_id()
+                    && data_b.auto_traits()
+                    // All of a's auto traits need to be in b's auto traits.
+                    .all(|b| data_a.auto_traits().any(|a| a == b))
             }
 
             // T -> Trait.
@@ -2981,7 +2973,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
             .shallow_resolve(*obligation.self_ty().skip_binder());
         let poly_trait_ref = match self_ty.sty {
             ty::Dynamic(ref data, ..) => {
-                data.principal().unwrap().with_self_ty(self.tcx(), self_ty)
+                data.principal().with_self_ty(self.tcx(), self_ty)
             }
             _ => span_bug!(obligation.cause.span, "object candidate with non-object"),
         };
@@ -3244,10 +3236,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
             (&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => {
                 // See assemble_candidates_for_unsizing for more info.
                 let existential_predicates = data_a.map_bound(|data_a| {
-                    let principal = data_a.principal();
-                    let iter = principal
-                        .into_iter()
-                        .map(ty::ExistentialPredicate::Trait)
+                    let iter = iter::once(ty::ExistentialPredicate::Trait(data_a.principal()))
                         .chain(
                             data_a
                                 .projection_bounds()
@@ -3285,7 +3274,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
             // T -> Trait.
             (_, &ty::Dynamic(ref data, r)) => {
                 let mut object_dids = data.auto_traits()
-                    .chain(data.principal().map(|p| p.def_id()));
+                    .chain(iter::once(data.principal().def_id()));
                 if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) {
                     return Err(TraitNotObjectSafe(did));
                 }
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index 3123f0fbe31..d886d5ed204 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -208,8 +208,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
             ty::FnDef(..) => "fn item".into(),
             ty::FnPtr(_) => "fn pointer".into(),
             ty::Dynamic(ref inner, ..) => {
-                inner.principal().map_or_else(|| "trait".into(),
-                    |p| format!("trait {}", tcx.item_path_str(p.def_id())).into())
+                format!("trait {}", tcx.item_path_str(inner.principal().def_id())).into()
             }
             ty::Closure(..) => "closure".into(),
             ty::Generator(..) => "generator".into(),
diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs
index 0f68e7aba4d..e6aaf8b1bb2 100644
--- a/src/librustc/ty/fast_reject.rs
+++ b/src/librustc/ty/fast_reject.rs
@@ -78,7 +78,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
         ty::Array(..) | ty::Slice(_) => Some(ArraySimplifiedType),
         ty::RawPtr(_) => Some(PtrSimplifiedType),
         ty::Dynamic(ref trait_info, ..) => {
-            trait_info.principal().map(|p| TraitSimplifiedType(p.def_id()))
+            Some(TraitSimplifiedType(trait_info.principal().def_id()))
         }
         ty::Ref(_, ty, _) => {
             // since we introduce auto-refs during method lookup, we
diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs
index ab081324036..c4a25971da3 100644
--- a/src/librustc/ty/item_path.rs
+++ b/src/librustc/ty/item_path.rs
@@ -436,7 +436,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
     match ty.sty {
         ty::Adt(adt_def, _) => Some(adt_def.did),
 
-        ty::Dynamic(data, ..) => data.principal().map(|p| p.def_id()),
+        ty::Dynamic(data, ..) => Some(data.principal().def_id()),
 
         ty::Array(subty, _) |
         ty::Slice(subty) => characteristic_def_id_of_type(subty),
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 145c122e75d..cc6e6b2861e 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -559,10 +559,10 @@ impl<'a, 'gcx, 'tcx> Binder<ExistentialPredicate<'tcx>> {
 impl<'tcx> serialize::UseSpecializedDecodable for &'tcx List<ExistentialPredicate<'tcx>> {}
 
 impl<'tcx> List<ExistentialPredicate<'tcx>> {
-    pub fn principal(&self) -> Option<ExistentialTraitRef<'tcx>> {
-        match self.get(0) {
-            Some(&ExistentialPredicate::Trait(tr)) => Some(tr),
-            _ => None,
+    pub fn principal(&self) -> ExistentialTraitRef<'tcx> {
+        match self[0] {
+            ExistentialPredicate::Trait(tr) => tr,
+            other => bug!("first predicate is {:?}", other),
         }
     }
 
@@ -589,8 +589,8 @@ impl<'tcx> List<ExistentialPredicate<'tcx>> {
 }
 
 impl<'tcx> Binder<&'tcx List<ExistentialPredicate<'tcx>>> {
-    pub fn principal(&self) -> Option<PolyExistentialTraitRef<'tcx>> {
-        self.skip_binder().principal().map(Binder::bind)
+    pub fn principal(&self) -> PolyExistentialTraitRef<'tcx> {
+        Binder::bind(self.skip_binder().principal())
     }
 
     #[inline]
@@ -1825,9 +1825,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
             }
             Dynamic(ref obj, region) => {
                 let mut v = vec![region];
-                if let Some(p) = obj.principal() {
-                    v.extend(p.skip_binder().substs.regions());
-                }
+                v.extend(obj.principal().skip_binder().substs.regions());
                 v
             }
             Adt(_, substs) | Opaque(_, substs) => {
diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs
index 7af838845cd..27747970f76 100644
--- a/src/librustc/ty/wf.rs
+++ b/src/librustc/ty/wf.rs
@@ -387,7 +387,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
 
                     let cause = self.cause(traits::MiscObligation);
                     let component_traits =
-                        data.auto_traits().chain(data.principal().map(|p| p.def_id()));
+                        data.auto_traits().chain(once(data.principal().def_id()));
                     self.out.extend(
                         component_traits.map(|did| traits::Obligation::new(
                             cause.clone(),
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 33534ab27f1..f3b5503b8d0 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -621,16 +621,16 @@ define_print! {
                 // Use a type that can't appear in defaults of type parameters.
                 let dummy_self = tcx.mk_infer(ty::FreshTy(0));
 
-                if let Some(p) = self.principal() {
-                    let principal = tcx.lift(&p).expect("could not lift TraitRef for printing")
-                        .with_self_ty(tcx, dummy_self);
-                    let projections = self.projection_bounds().map(|p| {
-                        tcx.lift(&p)
-                            .expect("could not lift projection for printing")
-                            .with_self_ty(tcx, dummy_self)
-                    }).collect::<Vec<_>>();
-                    cx.parameterized(f, principal.substs, principal.def_id, &projections)?;
-                }
+                let principal = tcx
+                    .lift(&self.principal())
+                    .expect("could not lift TraitRef for printing")
+                    .with_self_ty(tcx, dummy_self);
+                let projections = self.projection_bounds().map(|p| {
+                    tcx.lift(&p)
+                        .expect("could not lift projection for printing")
+                        .with_self_ty(tcx, dummy_self)
+                }).collect::<Vec<_>>();
+                cx.parameterized(f, principal.substs, principal.def_id, &projections)?;
 
                 // Builtin bounds.
                 for did in self.auto_traits() {
diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs
index c8e8d0dc84e..7b93d3e795e 100644
--- a/src/librustc_codegen_llvm/abi.rs
+++ b/src/librustc_codegen_llvm/abi.rs
@@ -536,7 +536,10 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
                     // Note that the platform intrinsic ABI is exempt here as
                     // that's how we connect up to LLVM and it's unstable
                     // anyway, we control all calls to it in libstd.
-                    layout::Abi::Vector { .. } if abi != Abi::PlatformIntrinsic => {
+                    layout::Abi::Vector { .. }
+                        if abi != Abi::PlatformIntrinsic &&
+                            cx.sess().target.target.options.simd_types_indirect =>
+                    {
                         arg.make_indirect();
                         return
                     }
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index 578018c7adc..e6197423738 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -59,7 +59,7 @@ pub struct CodegenCx<'a, 'tcx: 'a> {
     /// Cache instances of monomorphic and polymorphic items
     pub instances: RefCell<FxHashMap<Instance<'tcx>, &'a Value>>,
     /// Cache generated vtables
-    pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>),
+    pub vtables: RefCell<FxHashMap<(Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>),
                                    &'a Value>>,
     /// Cache of constant strings,
     pub const_cstr_cache: RefCell<FxHashMap<LocalInternedString, &'a Value>>,
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index 706568b5446..6eff086a2ba 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -435,12 +435,7 @@ fn trait_pointer_metadata(
     // But it does not describe the trait's methods.
 
     let containing_scope = match trait_type.sty {
-        ty::Dynamic(ref data, ..) => if let Some(principal) = data.principal() {
-            let def_id = principal.def_id();
-            Some(get_namespace_for_item(cx, def_id))
-        } else {
-            NO_SCOPE_METADATA
-        },
+        ty::Dynamic(ref data, ..) => Some(get_namespace_for_item(cx, data.principal().def_id())),
         _ => {
             bug!("debuginfo: Unexpected trait-object type in \
                   trait_pointer_metadata(): {:?}",
diff --git a/src/librustc_codegen_llvm/debuginfo/type_names.rs b/src/librustc_codegen_llvm/debuginfo/type_names.rs
index 2f110fd552a..06b9318a5e8 100644
--- a/src/librustc_codegen_llvm/debuginfo/type_names.rs
+++ b/src/librustc_codegen_llvm/debuginfo/type_names.rs
@@ -116,14 +116,12 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
             }
         },
         ty::Dynamic(ref trait_data, ..) => {
-            if let Some(principal) = trait_data.principal() {
-                let principal = cx.tcx.normalize_erasing_late_bound_regions(
-                    ty::ParamEnv::reveal_all(),
-                    &principal,
-                );
-                push_item_name(cx, principal.def_id, false, output);
-                push_type_params(cx, principal.substs, output);
-            }
+            let principal = cx.tcx.normalize_erasing_late_bound_regions(
+                ty::ParamEnv::reveal_all(),
+                &trait_data.principal(),
+            );
+            push_item_name(cx, principal.def_id, false, output);
+            push_type_params(cx, principal.substs, output);
         },
         ty::FnDef(..) | ty::FnPtr(_) => {
             let sig = t.fn_sig(cx.tcx);
diff --git a/src/librustc_codegen_llvm/meth.rs b/src/librustc_codegen_llvm/meth.rs
index 8a1159bc477..db06b87f44e 100644
--- a/src/librustc_codegen_llvm/meth.rs
+++ b/src/librustc_codegen_llvm/meth.rs
@@ -72,7 +72,7 @@ impl<'a, 'tcx> VirtualIndex {
 pub fn get_vtable(
     cx: &CodegenCx<'ll, 'tcx>,
     ty: Ty<'tcx>,
-    trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
+    trait_ref: ty::PolyExistentialTraitRef<'tcx>,
 ) -> &'ll Value {
     let tcx = cx.tcx;
 
@@ -86,23 +86,19 @@ pub fn get_vtable(
     // Not in the cache. Build it.
     let nullptr = C_null(Type::i8p(cx));
 
+    let methods = tcx.vtable_methods(trait_ref.with_self_ty(tcx, ty));
+    let methods = methods.iter().cloned().map(|opt_mth| {
+        opt_mth.map_or(nullptr, |(def_id, substs)| {
+            callee::resolve_and_get_fn(cx, def_id, substs)
+        })
+    });
+
     let (size, align) = cx.size_and_align_of(ty);
-    let mut components: Vec<_> = [
+    let components: Vec<_> = [
         callee::get_fn(cx, monomorphize::resolve_drop_in_place(cx.tcx, ty)),
         C_usize(cx, size.bytes()),
         C_usize(cx, align.abi())
-    ].iter().cloned().collect();
-
-    if let Some(trait_ref) = trait_ref {
-        let trait_ref = trait_ref.with_self_ty(tcx, ty);
-        let methods = tcx.vtable_methods(trait_ref);
-        let methods = methods.iter().cloned().map(|opt_mth| {
-            opt_mth.map_or(nullptr, |(def_id, substs)| {
-                callee::resolve_and_get_fn(cx, def_id, substs)
-            })
-        });
-        components.extend(methods);
-    }
+    ].iter().cloned().chain(methods).collect();
 
     let vtable_const = C_struct(cx, &components, false);
     let align = cx.data_layout().pointer_align;
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 7fb66ea97f2..b4f95b915eb 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -44,7 +44,7 @@ use serialize::json;
 
 use std::any::Any;
 use std::env;
-use std::ffi::{OsStr, OsString};
+use std::ffi::OsString;
 use std::fs;
 use std::io::{self, Write};
 use std::iter;
@@ -1021,6 +1021,7 @@ where
             .cloned()
             .collect();
         missing_fragment_specifiers.sort();
+
         for span in missing_fragment_specifiers {
             let lint = lint::builtin::MISSING_FRAGMENT_SPECIFIER;
             let msg = "missing fragment specifier";
@@ -1472,7 +1473,7 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &[Pa
             .collect();
         let mut file = fs::File::create(&deps_filename)?;
         for path in out_filenames {
-            write!(file, "{}: {}\n\n", path.display(), files.join(" "))?;
+            writeln!(file, "{}: {}\n", path.display(), files.join(" "))?;
         }
 
         // Emit a fake target for each input file to the compilation. This
@@ -1484,15 +1485,12 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &[Pa
         Ok(())
     })();
 
-    match result {
-        Ok(()) => {}
-        Err(e) => {
-            sess.fatal(&format!(
-                "error writing dependencies to `{}`: {}",
-                deps_filename.display(),
-                e
-            ));
-        }
+    if let Err(e) = result {
+        sess.fatal(&format!(
+            "error writing dependencies to `{}`: {}",
+            deps_filename.display(),
+            e
+        ));
     }
 }
 
@@ -1520,6 +1518,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
                             Symbol::intern("proc-macro"),
                             Symbol::intern("bin")
                         ];
+
                         if let ast::MetaItemKind::NameValue(spanned) = a.meta().unwrap().node {
                             let span = spanned.span;
                             let lev_candidate = find_best_match_for_name(
@@ -1551,7 +1550,7 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
                         }
                         None
                     }
-                    _ => {
+                    None => {
                         session
                             .struct_span_err(a.span, "`crate_type` requires a value")
                             .note("for example: `#![crate_type=\"lib\"]`")
@@ -1581,25 +1580,26 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
             base.push(::rustc_codegen_utils::link::default_output_for_target(
                 session,
             ));
+        } else {
+            base.sort();
+            base.dedup();
         }
-        base.sort();
-        base.dedup();
     }
 
-    base.into_iter()
-        .filter(|crate_type| {
-            let res = !::rustc_codegen_utils::link::invalid_output_for_target(session, *crate_type);
+    base.retain(|crate_type| {
+        let res = !::rustc_codegen_utils::link::invalid_output_for_target(session, *crate_type);
 
-            if !res {
-                session.warn(&format!(
-                    "dropping unsupported crate type `{}` for target `{}`",
-                    *crate_type, session.opts.target_triple
-                ));
-            }
+        if !res {
+            session.warn(&format!(
+                "dropping unsupported crate type `{}` for target `{}`",
+                *crate_type, session.opts.target_triple
+            ));
+        }
 
-            res
-        })
-        .collect()
+        res
+    });
+
+    base
 }
 
 pub fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguator {
@@ -1650,17 +1650,14 @@ pub fn build_output_filenames(
             // "-" as input file will cause the parser to read from stdin so we
             // have to make up a name
             // We want to toss everything after the final '.'
-            let dirpath = match *odir {
-                Some(ref d) => d.clone(),
-                None => PathBuf::new(),
-            };
+            let dirpath = (*odir).as_ref().cloned().unwrap_or_default();
 
             // If a crate name is present, we use it as the link name
             let stem = sess.opts
                 .crate_name
                 .clone()
                 .or_else(|| attr::find_crate_name(attrs).map(|n| n.to_string()))
-                .unwrap_or(input.filestem());
+                .unwrap_or_else(|| input.filestem());
 
             OutputFilenames {
                 out_directory: dirpath,
@@ -1693,13 +1690,11 @@ pub fn build_output_filenames(
                 sess.warn("ignoring -C extra-filename flag due to -o flag");
             }
 
-            let cur_dir = Path::new("");
-
             OutputFilenames {
-                out_directory: out_file.parent().unwrap_or(cur_dir).to_path_buf(),
+                out_directory: out_file.parent().unwrap_or_else(|| Path::new("")).to_path_buf(),
                 out_filestem: out_file
                     .file_stem()
-                    .unwrap_or(OsStr::new(""))
+                    .unwrap_or_default()
                     .to_str()
                     .unwrap()
                     .to_string(),
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 0514bd20c98..276b7290c2e 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -89,6 +89,7 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend;
 use serialize::json::ToJson;
 
 use std::any::Any;
+use std::borrow::Cow;
 use std::cmp::max;
 use std::default::Default;
 use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
@@ -136,9 +137,7 @@ pub mod target_features {
                              codegen_backend: &dyn CodegenBackend) {
         let tf = Symbol::intern("target_feature");
 
-        for feat in codegen_backend.target_features(sess) {
-            cfg.insert((tf, Some(feat)));
-        }
+        cfg.extend(codegen_backend.target_features(sess).into_iter().map(|feat| (tf, Some(feat))));
 
         if sess.crt_static_feature() {
             cfg.insert((tf, Some(Symbol::intern("crt-static"))));
@@ -152,21 +151,14 @@ pub const EXIT_SUCCESS: isize = 0;
 /// Exit status code used for compilation failures and  invalid flags.
 pub const EXIT_FAILURE: isize = 1;
 
-const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\
-                                      md#bug-reports";
-
-const ICE_REPORT_COMPILER_FLAGS: &'static [&'static str] = &[
-    "Z",
-    "C",
-    "crate-type",
-];
-const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &'static [&'static str] = &[
-    "metadata",
-    "extra-filename",
-];
-const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &'static [&'static str] = &[
-    "incremental",
-];
+const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\
+                              md#bug-reports";
+
+const ICE_REPORT_COMPILER_FLAGS: &[&str] = &["Z", "C", "crate-type"];
+
+const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &[&str] = &["metadata", "extra-filename"];
+
+const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &[&str] = &["incremental"];
 
 pub fn abort_on_err<T>(result: Result<T, CompileIncomplete>, sess: &Session) -> T {
     match result {
@@ -195,14 +187,16 @@ pub fn run<F>(run_compiler: F) -> isize
                     }
                     None => {
                         let emitter =
-                            errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto,
-                                                                None,
-                                                                true,
-                                                                false);
+                            errors::emitter::EmitterWriter::stderr(
+                                errors::ColorConfig::Auto,
+                                None,
+                                true,
+                                false
+                            );
                         let handler = errors::Handler::with_emitter(true, false, Box::new(emitter));
                         handler.emit(&MultiSpan::new(),
-                                    "aborting due to previous error(s)",
-                                    errors::Level::Fatal);
+                                     "aborting due to previous error(s)",
+                                     errors::Level::Fatal);
                         panic::resume_unwind(Box::new(errors::FatalErrorMarker));
                     }
                 }
@@ -224,15 +218,10 @@ fn load_backend_from_dylib(path: &Path) -> fn() -> Box<dyn CodegenBackend> {
     // available for future dynamic libraries opened. This is currently used by
     // loading LLVM and then making its symbols available for other dynamic
     // libraries.
-    let lib = match DynamicLibrary::open_global_now(path) {
-        Ok(lib) => lib,
-        Err(err) => {
-            let err = format!("couldn't load codegen backend {:?}: {:?}",
-                              path,
-                              err);
-            early_error(ErrorOutputType::default(), &err);
-        }
-    };
+    let lib = DynamicLibrary::open_global_now(path).unwrap_or_else(|err| {
+        let err = format!("couldn't load codegen backend {:?}: {:?}", path, err);
+        early_error(ErrorOutputType::default(), &err);
+    });
     unsafe {
         match lib.symbol("__rustc_codegen_backend") {
             Ok(f) => {
@@ -328,37 +317,30 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
     let sysroot = sysroot_candidates.iter()
         .map(|sysroot| {
             let libdir = filesearch::relative_target_lib_path(&sysroot, &target);
-            sysroot.join(libdir)
-                .with_file_name(option_env!("CFG_CODEGEN_BACKENDS_DIR")
-                                .unwrap_or("codegen-backends"))
+            sysroot.join(libdir).with_file_name(
+                option_env!("CFG_CODEGEN_BACKENDS_DIR").unwrap_or("codegen-backends"))
         })
         .filter(|f| {
             info!("codegen backend candidate: {}", f.display());
             f.exists()
         })
         .next();
-    let sysroot = match sysroot {
-        Some(path) => path,
-        None => {
-            let candidates = sysroot_candidates.iter()
-                .map(|p| p.display().to_string())
-                .collect::<Vec<_>>()
-                .join("\n* ");
-            let err = format!("failed to find a `codegen-backends` folder \
-                               in the sysroot candidates:\n* {}", candidates);
-            early_error(ErrorOutputType::default(), &err);
-        }
-    };
+    let sysroot = sysroot.unwrap_or_else(|| {
+        let candidates = sysroot_candidates.iter()
+            .map(|p| p.display().to_string())
+            .collect::<Vec<_>>()
+            .join("\n* ");
+        let err = format!("failed to find a `codegen-backends` folder \
+                           in the sysroot candidates:\n* {}", candidates);
+        early_error(ErrorOutputType::default(), &err);
+    });
     info!("probing {} for a codegen backend", sysroot.display());
 
-    let d = match sysroot.read_dir() {
-        Ok(d) => d,
-        Err(e) => {
-            let err = format!("failed to load default codegen backend, couldn't \
-                               read `{}`: {}", sysroot.display(), e);
-            early_error(ErrorOutputType::default(), &err);
-        }
-    };
+    let d = sysroot.read_dir().unwrap_or_else(|e| {
+        let err = format!("failed to load default codegen backend, couldn't \
+                           read `{}`: {}", sysroot.display(), e);
+        early_error(ErrorOutputType::default(), &err);
+    });
 
     let mut file: Option<PathBuf> = None;
 
@@ -378,8 +360,8 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
         }
         if let Some(ref prev) = file {
             let err = format!("duplicate codegen backends found\n\
-                first:  {}\n\
-                second: {}\n\
+                               first:  {}\n\
+                               second: {}\n\
             ", prev.display(), path.display());
             early_error(ErrorOutputType::default(), &err);
         }
@@ -391,7 +373,7 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
         None => {
             let err = format!("failed to load default codegen backend for `{}`, \
                                no appropriate codegen dylib found in `{}`",
-                               backend_name, sysroot.display());
+                              backend_name, sysroot.display());
             early_error(ErrorOutputType::default(), &err);
         }
     }
@@ -578,7 +560,7 @@ pub fn set_sigpipe_handler() {
     unsafe {
         // Set the SIGPIPE signal handler, so that an EPIPE
         // will cause rustc to terminate, as expected.
-        assert!(libc::signal(libc::SIGPIPE, libc::SIG_DFL) != libc::SIG_ERR);
+        assert_ne!(libc::signal(libc::SIGPIPE, libc::SIG_DFL), libc::SIG_ERR);
     }
 }
 
@@ -996,7 +978,7 @@ impl RustcDefaultCalls {
                          input: &Input)
                          -> Compilation {
         let r = matches.opt_strs("Z");
-        if r.contains(&("ls".to_string())) {
+        if r.iter().any(|s| *s == "ls") {
             match input {
                 &Input::File(ref ifile) => {
                     let path = &(*ifile);
@@ -1015,7 +997,7 @@ impl RustcDefaultCalls {
             return Compilation::Stop;
         }
 
-        return Compilation::Continue;
+        Compilation::Continue
     }
 
 
@@ -1028,7 +1010,7 @@ impl RustcDefaultCalls {
         use rustc::session::config::PrintRequest::*;
         // PrintRequest::NativeStaticLibs is special - printed during linking
         // (empty iterator returns true)
-        if sess.opts.prints.iter().all(|&p| p==PrintRequest::NativeStaticLibs) {
+        if sess.opts.prints.iter().all(|&p| p == PrintRequest::NativeStaticLibs) {
             return Compilation::Continue;
         }
 
@@ -1055,10 +1037,8 @@ impl RustcDefaultCalls {
                 Sysroot => println!("{}", sess.sysroot().display()),
                 TargetSpec => println!("{}", sess.target.target.to_json().pretty()),
                 FileNames | CrateName => {
-                    let input = match input {
-                        Some(input) => input,
-                        None => early_error(ErrorOutputType::default(), "no input file provided"),
-                    };
+                    let input = input.unwrap_or_else(||
+                        early_error(ErrorOutputType::default(), "no input file provided"));
                     let attrs = attrs.as_ref().unwrap();
                     let t_outputs = driver::build_output_filenames(input, odir, ofile, attrs, sess);
                     let id = rustc_codegen_utils::link::find_crate_name(Some(sess), attrs, input);
@@ -1074,18 +1054,14 @@ impl RustcDefaultCalls {
                             &id,
                             &t_outputs
                         );
-                        println!("{}",
-                                 fname.file_name()
-                                      .unwrap()
-                                      .to_string_lossy());
+                        println!("{}", fname.file_name().unwrap().to_string_lossy());
                     }
                 }
                 Cfg => {
                     let allow_unstable_cfg = UnstableFeatures::from_environment()
                         .is_nightly_build();
 
-                    let mut cfgs = Vec::new();
-                    for &(name, ref value) in sess.parse_sess.config.iter() {
+                    let mut cfgs = sess.parse_sess.config.iter().filter_map(|&(name, ref value)| {
                         let gated_cfg = GatedCfg::gate(&ast::MetaItem {
                             ident: ast::Path::from_ident(ast::Ident::with_empty_ctxt(name)),
                             node: ast::MetaItemKind::Word,
@@ -1104,16 +1080,16 @@ impl RustcDefaultCalls {
                         let value = value.as_ref().map(|s| s.as_ref());
                         if name != "target_feature" || value != Some("crt-static") {
                             if !allow_unstable_cfg && gated_cfg.is_some() {
-                                continue;
+                                return None
                             }
                         }
 
-                        cfgs.push(if let Some(value) = value {
-                            format!("{}=\"{}\"", name, value)
+                        if let Some(value) = value {
+                            Some(format!("{}=\"{}\"", name, value))
                         } else {
-                            name.to_string()
-                        });
-                    }
+                            Some(name.to_string())
+                        }
+                    }).collect::<Vec<String>>();
 
                     cfgs.sort();
                     for cfg in cfgs {
@@ -1150,9 +1126,8 @@ fn commit_date_str() -> Option<&'static str> {
 pub fn version(binary: &str, matches: &getopts::Matches) {
     let verbose = matches.opt_present("verbose");
 
-    println!("{} {}",
-             binary,
-             option_env!("CFG_VERSION").unwrap_or("unknown version"));
+    println!("{} {}", binary, option_env!("CFG_VERSION").unwrap_or("unknown version"));
+
     if verbose {
         fn unw(x: Option<&str>) -> &str {
             x.unwrap_or("unknown")
@@ -1176,7 +1151,7 @@ fn usage(verbose: bool, include_unstable_options: bool) {
     for option in groups.iter().filter(|x| include_unstable_options || x.is_stable()) {
         (option.apply)(&mut options);
     }
-    let message = "Usage: rustc [OPTIONS] INPUT".to_string();
+    let message = "Usage: rustc [OPTIONS] INPUT";
     let nightly_help = if nightly_options::is_nightly_build() {
         "\n    -Z help             Print internal options for debugging rustc"
     } else {
@@ -1191,7 +1166,7 @@ fn usage(verbose: bool, include_unstable_options: bool) {
     -C help             Print codegen options
     -W help             \
               Print 'lint' options and default settings{}{}\n",
-             options.usage(&message),
+             options.usage(message),
              nightly_help,
              verbose_help);
 }
@@ -1273,8 +1248,6 @@ Available lint options:
 
     print_lints(builtin);
 
-
-
     let max_name_len = max("warnings".len(),
                            plugin_groups.iter()
                                         .chain(&builtin_groups)
@@ -1407,10 +1380,8 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
     for option in config::rustc_optgroups() {
         (option.apply)(&mut options);
     }
-    let matches = match options.parse(args) {
-        Ok(m) => m,
-        Err(f) => early_error(ErrorOutputType::default(), &f.to_string()),
-    };
+    let matches = options.parse(args).unwrap_or_else(|f|
+        early_error(ErrorOutputType::default(), &f.to_string()));
 
     // For all options we just parsed, we check a few aspects:
     //
@@ -1452,6 +1423,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
     }
 
     let cg_flags = matches.opt_strs("C");
+
     if cg_flags.iter().any(|x| *x == "help") {
         describe_codegen_flags();
         return None;
@@ -1462,7 +1434,7 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
                    "the --no-stack-check flag is deprecated and does nothing");
     }
 
-    if cg_flags.contains(&"passes=list".to_string()) {
+    if cg_flags.iter().any(|x| *x == "passes=list") {
         get_codegen_sysroot("llvm")().print_passes();
         return None;
     }
@@ -1500,7 +1472,7 @@ pub fn in_named_rustc_thread<F, R>(name: String, f: F) -> Result<R, Box<dyn Any
     // Temporarily have stack size set to 16MB to deal with nom-using crates failing
     const STACK_SIZE: usize = 16 * 1024 * 1024; // 16MB
 
-    #[cfg(all(unix,not(target_os = "haiku")))]
+    #[cfg(all(unix, not(target_os = "haiku")))]
     let spawn_thread = unsafe {
         // Fetch the current resource limits
         let mut rlim = libc::rlimit {
@@ -1554,7 +1526,7 @@ pub fn in_named_rustc_thread<F, R>(name: String, f: F) -> Result<R, Box<dyn Any
         }
     };
 
-    #[cfg(not(any(windows,unix)))]
+    #[cfg(not(any(windows, unix)))]
     let spawn_thread = true;
 
     // The or condition is added from backward compatibility.
@@ -1632,7 +1604,7 @@ fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
         }
     }
 
-    if result.len() > 0 {
+    if !result.is_empty() {
         Some((result, excluded_cargo_defaults))
     } else {
         None
@@ -1680,25 +1652,25 @@ pub fn monitor<F: FnOnce() + Send + 'static>(f: F) -> Result<(), CompilationFail
                              errors::Level::Bug);
             }
 
-            let mut xs = vec![
-                "the compiler unexpectedly panicked. this is a bug.".to_string(),
-                format!("we would appreciate a bug report: {}", BUG_REPORT_URL),
+            let mut xs: Vec<Cow<'static, str>> = vec![
+                "the compiler unexpectedly panicked. this is a bug.".into(),
+                format!("we would appreciate a bug report: {}", BUG_REPORT_URL).into(),
                 format!("rustc {} running on {}",
                         option_env!("CFG_VERSION").unwrap_or("unknown_version"),
-                        config::host_triple()),
+                        config::host_triple()).into(),
             ];
 
             if let Some((flags, excluded_cargo_defaults)) = extra_compiler_flags() {
-                xs.push(format!("compiler flags: {}", flags.join(" ")));
+                xs.push(format!("compiler flags: {}", flags.join(" ")).into());
 
                 if excluded_cargo_defaults {
-                    xs.push("some of the compiler flags provided by cargo are hidden".to_string());
+                    xs.push("some of the compiler flags provided by cargo are hidden".into());
                 }
             }
 
             for note in &xs {
                 handler.emit(&MultiSpan::new(),
-                             &note,
+                             note,
                              errors::Level::Note);
             }
 
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 7e395f1e9a9..b4f6d10b1f8 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -167,10 +167,10 @@ pub fn parse_pretty(sess: &Session,
 impl PpSourceMode {
     /// Constructs a `PrinterSupport` object and passes it to `f`.
     fn call_with_pp_support<'tcx, A, F>(&self,
-                                           sess: &'tcx Session,
-                                           hir_map: Option<&hir_map::Map<'tcx>>,
-                                           f: F)
-                                           -> A
+                                        sess: &'tcx Session,
+                                        hir_map: Option<&hir_map::Map<'tcx>>,
+                                        f: F)
+                                        -> A
         where F: FnOnce(&dyn PrinterSupport) -> A
     {
         match *self {
@@ -198,17 +198,18 @@ impl PpSourceMode {
             _ => panic!("Should use call_with_pp_support_hir"),
         }
     }
-    fn call_with_pp_support_hir<'tcx, A, F>(&self,
-                                               sess: &'tcx Session,
-                                               cstore: &'tcx CStore,
-                                               hir_map: &hir_map::Map<'tcx>,
-                                               analysis: &ty::CrateAnalysis,
-                                               resolutions: &Resolutions,
-                                               arenas: &'tcx AllArenas<'tcx>,
-                                               output_filenames: &OutputFilenames,
-                                               id: &str,
-                                               f: F)
-                                               -> A
+    fn call_with_pp_support_hir<'tcx, A, F>(
+        &self,
+        sess: &'tcx Session,
+        cstore: &'tcx CStore,
+        hir_map: &hir_map::Map<'tcx>,
+        analysis: &ty::CrateAnalysis,
+        resolutions: &Resolutions,
+        arenas: &'tcx AllArenas<'tcx>,
+        output_filenames: &OutputFilenames,
+        id: &str,
+        f: F
+    ) -> A
         where F: FnOnce(&dyn HirPrinterSupport, &hir::Crate) -> A
     {
         match *self {
@@ -855,7 +856,7 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
                     break n.body();
                 }
                 let parent = tcx.hir.get_parent_node(node_id);
-                assert!(node_id != parent);
+                assert_ne!(node_id, parent);
                 node_id = parent;
             }
         }
@@ -952,18 +953,17 @@ pub fn print_after_parsing(sess: &Session,
         // Silently ignores an identified node.
         let out: &mut dyn Write = &mut out;
         s.call_with_pp_support(sess, None, move |annotation| {
-                debug!("pretty printing source code {:?}", s);
-                let sess = annotation.sess();
-                pprust::print_crate(sess.source_map(),
-                                    &sess.parse_sess,
-                                    krate,
-                                    src_name,
-                                    &mut rdr,
-                                    box out,
-                                    annotation.pp_ann(),
-                                    false)
-            })
-            .unwrap()
+            debug!("pretty printing source code {:?}", s);
+            let sess = annotation.sess();
+            pprust::print_crate(sess.source_map(),
+                                &sess.parse_sess,
+                                krate,
+                                src_name,
+                                &mut rdr,
+                                box out,
+                                annotation.pp_ann(),
+                                false)
+        }).unwrap()
     } else {
         unreachable!();
     };
diff --git a/src/librustc_driver/profile/mod.rs b/src/librustc_driver/profile/mod.rs
index 2ec85e1c27f..d334a9476ce 100644
--- a/src/librustc_driver/profile/mod.rs
+++ b/src/librustc_driver/profile/mod.rs
@@ -23,7 +23,7 @@ pub fn begin(sess: &Session) {
     use std::sync::mpsc::{channel};
     let (tx, rx) = channel();
     if profq_set_chan(sess, tx) {
-        thread::spawn(move||profile_queries_thread(rx));
+        thread::spawn(move || profile_queries_thread(rx));
     }
 }
 
@@ -34,11 +34,12 @@ pub fn begin(sess: &Session) {
 pub fn dump(sess: &Session, path: String) {
     use std::sync::mpsc::{channel};
     let (tx, rx) = channel();
-    let params = ProfQDumpParams{
-        path, ack:tx,
+    let params = ProfQDumpParams {
+        path,
+        ack: tx,
         // FIXME: Add another compiler flag to toggle whether this log
         // is written; false for now
-        dump_profq_msg_log:true,
+        dump_profq_msg_log: true,
     };
     profq_msg(sess, ProfileQueriesMsg::Dump(params));
     let _ = rx.recv().unwrap();
@@ -63,20 +64,20 @@ struct StackFrame {
 }
 
 fn total_duration(traces: &[trace::Rec]) -> Duration {
-    let mut sum : Duration = Duration::new(0,0);
+    let mut sum : Duration = Duration::new(0, 0);
     for t in traces.iter() { sum += t.dur_total; }
     return sum
 }
 
 // profiling thread; retains state (in local variables) and dump traces, upon request.
-fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
+fn profile_queries_thread(r: Receiver<ProfileQueriesMsg>) {
     use self::trace::*;
     use std::fs::File;
     use std::time::{Instant};
 
-    let mut profq_msgs : Vec<ProfileQueriesMsg> = vec![];
-    let mut frame : StackFrame = StackFrame{ parse_st:ParseState::Clear, traces:vec![] };
-    let mut stack : Vec<StackFrame> = vec![];
+    let mut profq_msgs: Vec<ProfileQueriesMsg> = vec![];
+    let mut frame: StackFrame = StackFrame { parse_st: ParseState::Clear, traces: vec![] };
+    let mut stack: Vec<StackFrame> = vec![];
     loop {
         let msg = r.recv();
         if let Err(_recv_err) = msg {
@@ -90,7 +91,7 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
         match msg {
             ProfileQueriesMsg::Halt => return,
             ProfileQueriesMsg::Dump(params) => {
-                assert!(stack.len() == 0);
+                assert!(stack.is_empty());
                 assert!(frame.parse_st == ParseState::Clear);
                 {
                     // write log of all messages
@@ -109,17 +110,14 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
                     let counts_path = format!("{}.counts.txt", params.path);
                     let mut counts_file = File::create(&counts_path).unwrap();
 
-                    write!(html_file, "<html>\n").unwrap();
-                    write!(html_file,
-                           "<head>\n<link rel=\"stylesheet\" type=\"text/css\" href=\"{}\">\n",
-                           "profile_queries.css").unwrap();
-                    write!(html_file, "<style>\n").unwrap();
+                    writeln!(html_file,
+                        "<html>\n<head>\n<link rel=\"stylesheet\" type=\"text/css\" href=\"{}\">",
+                        "profile_queries.css").unwrap();
+                    writeln!(html_file, "<style>").unwrap();
                     trace::write_style(&mut html_file);
-                    write!(html_file, "</style>\n").unwrap();
-                    write!(html_file, "</head>\n").unwrap();
-                    write!(html_file, "<body>\n").unwrap();
+                    writeln!(html_file, "</style>\n</head>\n<body>").unwrap();
                     trace::write_traces(&mut html_file, &mut counts_file, &frame.traces);
-                    write!(html_file, "</body>\n</html>\n").unwrap();
+                    writeln!(html_file, "</body>\n</html>").unwrap();
 
                     let ack_path = format!("{}.ack", params.path);
                     let ack_file = File::create(&ack_path).unwrap();
@@ -141,10 +139,10 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
 
                     // Parse State: Clear
                     (ParseState::Clear,
-                     ProfileQueriesMsg::QueryBegin(span,querymsg)) => {
+                     ProfileQueriesMsg::QueryBegin(span, querymsg)) => {
                         let start = Instant::now();
                         frame.parse_st = ParseState::HaveQuery
-                            (Query{span:span, msg:querymsg}, start)
+                            (Query { span, msg: querymsg }, start)
                     },
                     (ParseState::Clear,
                      ProfileQueriesMsg::CacheHit) => {
@@ -287,8 +285,6 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
                         frame = StackFrame{parse_st:ParseState::Clear, traces:vec![]};
                     },
 
-                    //
-                    //
                     // Parse errors:
 
                     (ParseState::HaveQuery(q,_),
@@ -310,7 +306,6 @@ fn profile_queries_thread(r:Receiver<ProfileQueriesMsg>) {
                         unreachable!()
                     },
                 }
-
             }
         }
     }
diff --git a/src/librustc_driver/profile/trace.rs b/src/librustc_driver/profile/trace.rs
index e329b037d22..9589ae2a8db 100644
--- a/src/librustc_driver/profile/trace.rs
+++ b/src/librustc_driver/profile/trace.rs
@@ -43,18 +43,18 @@ pub struct QueryMetric {
     pub dur_total: Duration,
 }
 
+fn cons(s: &str) -> String {
+    let first = s.split(|d| d == '(' || d == '{').next();
+    assert!(first.is_some() && first != Some(""));
+    first.unwrap().to_owned()
+}
+
 pub fn cons_of_query_msg(q: &trace::Query) -> String {
-    let s = format!("{:?}", q.msg);
-    let cons: Vec<&str> = s.split(|d| d == '(' || d == '{').collect();
-    assert!(cons.len() > 0 && cons[0] != "");
-    cons[0].to_string()
+    cons(&format!("{:?}", q.msg))
 }
 
 pub fn cons_of_key(k: &DepNode) -> String {
-    let s = format!("{:?}", k);
-    let cons: Vec<&str> = s.split(|d| d == '(' || d == '{').collect();
-    assert!(cons.len() > 0 && cons[0] != "");
-    cons[0].to_string()
+    cons(&format!("{:?}", k))
 }
 
 // First return value is text; second return value is a CSS class
@@ -84,35 +84,33 @@ pub fn html_of_effect(eff: &Effect) -> (String, String) {
 // First return value is text; second return value is a CSS class
 fn html_of_duration(_start: &Instant, dur: &Duration) -> (String, String) {
     use rustc::util::common::duration_to_secs_str;
-    (duration_to_secs_str(dur.clone()),
-     String::new()
-    )
+    (duration_to_secs_str(dur.clone()), String::new())
 }
 
-fn html_of_fraction(frac: f64) -> (String, String) {
+fn html_of_fraction(frac: f64) -> (String, &'static str) {
     let css = {
-        if       frac > 0.50  { "frac-50".to_string() }
-        else if  frac > 0.40  { "frac-40".to_string() }
-        else if  frac > 0.30  { "frac-30".to_string() }
-        else if  frac > 0.20  { "frac-20".to_string() }
-        else if  frac > 0.10  { "frac-10".to_string() }
-        else if  frac > 0.05  { "frac-05".to_string() }
-        else if  frac > 0.02  { "frac-02".to_string() }
-        else if  frac > 0.01  { "frac-01".to_string() }
-        else if  frac > 0.001 { "frac-001".to_string() }
-        else                  { "frac-0".to_string() }
+        if       frac > 0.50  { "frac-50" }
+        else if  frac > 0.40  { "frac-40" }
+        else if  frac > 0.30  { "frac-30" }
+        else if  frac > 0.20  { "frac-20" }
+        else if  frac > 0.10  { "frac-10" }
+        else if  frac > 0.05  { "frac-05" }
+        else if  frac > 0.02  { "frac-02" }
+        else if  frac > 0.01  { "frac-01" }
+        else if  frac > 0.001 { "frac-001" }
+        else                  { "frac-0" }
     };
     let percent = frac * 100.0;
-    if percent > 0.1 { (format!("{:.1}%", percent), css) }
-    else { ("< 0.1%".to_string(), css) }
+
+    if percent > 0.1 {
+        (format!("{:.1}%", percent), css)
+    } else {
+        ("< 0.1%".to_string(), css)
+    }
 }
 
 fn total_duration(traces: &[Rec]) -> Duration {
-    let mut sum : Duration = Duration::new(0,0);
-    for t in traces.iter() {
-        sum += t.dur_total;
-    }
-    return sum
+    Duration::new(0, 0) + traces.iter().map(|t| t.dur_total).sum()
 }
 
 fn duration_div(nom: Duration, den: Duration) -> f64 {
@@ -130,64 +128,65 @@ fn write_traces_rec(file: &mut File, traces: &[Rec], total: Duration, depth: usi
         let fraction = duration_div(t.dur_total, total);
         let percent = fraction * 100.0;
         let (frc_text, frc_css_classes) = html_of_fraction(fraction);
-        write!(file, "<div class=\"trace depth-{} extent-{}{} {} {} {}\">\n",
-               depth,
-               t.extent.len(),
-               /* Heuristic for 'important' CSS class: */
-               if t.extent.len() > 5 || percent >= 1.0 {
-                   " important" }
-               else { "" },
-               eff_css_classes,
-               dur_css_classes,
-               frc_css_classes,
+        writeln!(file, "<div class=\"trace depth-{} extent-{}{} {} {} {}\">",
+                 depth,
+                 t.extent.len(),
+                 /* Heuristic for 'important' CSS class: */
+                 if t.extent.len() > 5 || percent >= 1.0 { " important" } else { "" },
+                 eff_css_classes,
+                 dur_css_classes,
+                 frc_css_classes,
         ).unwrap();
-        write!(file, "<div class=\"eff\">{}</div>\n", eff_text).unwrap();
-        write!(file, "<div class=\"dur\">{}</div>\n", dur_text).unwrap();
-        write!(file, "<div class=\"frc\">{}</div>\n", frc_text).unwrap();
+        writeln!(file, "<div class=\"eff\">{}</div>", eff_text).unwrap();
+        writeln!(file, "<div class=\"dur\">{}</div>", dur_text).unwrap();
+        writeln!(file, "<div class=\"frc\">{}</div>", frc_text).unwrap();
         write_traces_rec(file, &t.extent, total, depth + 1);
-        write!(file, "</div>\n").unwrap();
+        writeln!(file, "</div>").unwrap();
     }
 }
 
 fn compute_counts_rec(counts: &mut FxHashMap<String,QueryMetric>, traces: &[Rec]) {
+    counts.reserve(traces.len());
     for t in traces.iter() {
         match t.effect {
             Effect::TimeBegin(ref msg) => {
                 let qm = match counts.get(msg) {
-                    Some(_qm) => { panic!("TimeBegin with non-unique, repeat message") }
-                    None => QueryMetric{
+                    Some(_qm) => panic!("TimeBegin with non-unique, repeat message"),
+                    None => QueryMetric {
                         count: 1,
                         dur_self: t.dur_self,
                         dur_total: t.dur_total,
-                    }};
+                    }
+                };
                 counts.insert(msg.clone(), qm);
             },
             Effect::TaskBegin(ref key) => {
                 let cons = cons_of_key(key);
                 let qm = match counts.get(&cons) {
                     Some(qm) =>
-                        QueryMetric{
+                        QueryMetric {
                             count: qm.count + 1,
                             dur_self: qm.dur_self + t.dur_self,
                             dur_total: qm.dur_total + t.dur_total,
                         },
-                    None => QueryMetric{
+                    None => QueryMetric {
                         count: 1,
                         dur_self: t.dur_self,
                         dur_total: t.dur_total,
-                    }};
+                    }
+                };
                 counts.insert(cons, qm);
             },
             Effect::QueryBegin(ref qmsg, ref _cc) => {
                 let qcons = cons_of_query_msg(qmsg);
                 let qm = match counts.get(&qcons) {
                     Some(qm) =>
-                        QueryMetric{
+                        QueryMetric {
                             count: qm.count + 1,
                             dur_total: qm.dur_total + t.dur_total,
                             dur_self: qm.dur_self + t.dur_self
                         },
-                    None => QueryMetric{
+                    None => QueryMetric {
                         count: 1,
                         dur_total: t.dur_total,
                         dur_self: t.dur_self,
@@ -200,19 +199,20 @@ fn compute_counts_rec(counts: &mut FxHashMap<String,QueryMetric>, traces: &[Rec]
     }
 }
 
-pub fn write_counts(count_file: &mut File, counts: &mut FxHashMap<String,QueryMetric>) {
+pub fn write_counts(count_file: &mut File, counts: &mut FxHashMap<String, QueryMetric>) {
     use rustc::util::common::duration_to_secs_str;
     use std::cmp::Reverse;
 
     let mut data = counts.iter().map(|(ref cons, ref qm)|
         (cons.clone(), qm.count.clone(), qm.dur_total.clone(), qm.dur_self.clone())
     ).collect::<Vec<_>>();
+
     data.sort_by_key(|k| Reverse(k.3));
     for (cons, count, dur_total, dur_self) in data {
-        write!(count_file, "{}, {}, {}, {}\n",
-               cons, count,
-               duration_to_secs_str(dur_total),
-               duration_to_secs_str(dur_self)
+        writeln!(count_file, "{}, {}, {}, {}",
+                 cons, count,
+                 duration_to_secs_str(dur_total),
+                 duration_to_secs_str(dur_self)
         ).unwrap();
     }
 }
@@ -223,12 +223,12 @@ pub fn write_traces(html_file: &mut File, counts_file: &mut File, traces: &[Rec]
     compute_counts_rec(&mut counts, traces);
     write_counts(counts_file, &mut counts);
 
-    let total : Duration = total_duration(traces);
+    let total: Duration = total_duration(traces);
     write_traces_rec(html_file, traces, total, 0)
 }
 
 pub fn write_style(html_file: &mut File) {
-    write!(html_file,"{}", "
+    write!(html_file, "{}", "
 body {
     font-family: sans-serif;
     background: black;
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index ec3c310c63c..7d178d20967 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -80,10 +80,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
                 match callee.node {
                     hir::ExprKind::Path(ref qpath) => {
                         let def = cx.tables.qpath_def(qpath, callee.hir_id);
-                        if let Def::Fn(_) = def {
-                            Some(def)
-                        } else {  // `Def::Local` if it was a closure, for which we
-                            None  // do not currently support must-use linting
+                        match def {
+                            Def::Fn(_) | Def::Method(_) => Some(def),
+                            // `Def::Local` if it was a closure, for which we
+                            // do not currently support must-use linting
+                            _ => None
                         }
                     },
                     _ => None
diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs
index b5137e914dc..f4ddfa5293e 100644
--- a/src/librustc_mir/interpret/cast.rs
+++ b/src/librustc_mir/interpret/cast.rs
@@ -327,7 +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().unwrap().with_self_ty(
+                let trait_ref = data.principal().with_self_ty(
                     *self.tcx,
                     src_pointee_ty,
                 );
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 29f16762944..dd83d3157ba 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -907,22 +907,20 @@ fn create_mono_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             !impl_ty.needs_subst() && !impl_ty.has_escaping_regions());
 
     if let ty::Dynamic(ref trait_ty, ..) = trait_ty.sty {
-        if let Some(principal) = trait_ty.principal() {
-            let poly_trait_ref = principal.with_self_ty(tcx, impl_ty);
-            assert!(!poly_trait_ref.has_escaping_regions());
-
-            // Walk all methods of the trait, including those of its supertraits
-            let methods = tcx.vtable_methods(poly_trait_ref);
-            let methods = methods.iter().cloned().filter_map(|method| method)
-                .map(|(def_id, substs)| ty::Instance::resolve(
-                        tcx,
-                        ty::ParamEnv::reveal_all(),
-                        def_id,
-                        substs).unwrap())
-                .filter(|&instance| should_monomorphize_locally(tcx, &instance))
-                .map(|instance| create_fn_mono_item(instance));
-            output.extend(methods);
-        }
+        let poly_trait_ref = trait_ty.principal().with_self_ty(tcx, impl_ty);
+        assert!(!poly_trait_ref.has_escaping_regions());
+
+        // Walk all methods of the trait, including those of its supertraits
+        let methods = tcx.vtable_methods(poly_trait_ref);
+        let methods = methods.iter().cloned().filter_map(|method| method)
+            .map(|(def_id, substs)| ty::Instance::resolve(
+                    tcx,
+                    ty::ParamEnv::reveal_all(),
+                    def_id,
+                    substs).unwrap())
+            .filter(|&instance| should_monomorphize_locally(tcx, &instance))
+            .map(|instance| create_fn_mono_item(instance));
+        output.extend(methods);
         // Also add the destructor
         visit_drop_use(tcx, impl_ty, false, output);
     }
diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs
index f0ea93bfffd..4c4d56c8938 100644
--- a/src/librustc_mir/monomorphize/item.rs
+++ b/src/librustc_mir/monomorphize/item.rs
@@ -320,12 +320,13 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
                 output.push(']');
             },
             ty::Dynamic(ref trait_data, ..) => {
-                if let Some(principal) = trait_data.principal() {
-                    self.push_def_path(principal.def_id(), output);
-                    self.push_type_params(principal.skip_binder().substs,
-                        trait_data.projection_bounds(),
-                        output);
-                }
+                let principal = trait_data.principal();
+                self.push_def_path(principal.def_id(), output);
+                self.push_type_params(
+                    principal.skip_binder().substs,
+                    trait_data.projection_bounds(),
+                    output,
+                );
             },
             ty::Foreign(did) => self.push_def_path(did, output),
             ty::FnDef(..) |
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 040ee35632c..5963f1a481c 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -19,7 +19,7 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 
 use rustc::mir::*;
 use rustc::mir::visit::*;
-use rustc::ty::{self, Instance, Ty, TyCtxt};
+use rustc::ty::{self, Instance, InstanceDef, Ty, TyCtxt};
 use rustc::ty::subst::{Subst,Substs};
 
 use std::collections::VecDeque;
@@ -100,12 +100,21 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
                                                                       param_env,
                                                                       callee_def_id,
                                                                       substs) {
-                                callsites.push_back(CallSite {
-                                    callee: instance.def_id(),
-                                    substs: instance.substs,
-                                    bb,
-                                    location: terminator.source_info
-                                });
+                                let is_virtual =
+                                    if let InstanceDef::Virtual(..) = instance.def {
+                                        true
+                                    } else {
+                                        false
+                                    };
+
+                                if !is_virtual {
+                                    callsites.push_back(CallSite {
+                                        callee: instance.def_id(),
+                                        substs: instance.substs,
+                                        bb,
+                                        location: terminator.source_info
+                                    });
+                                }
                             }
                         }
                     }
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 60679d6d430..989851bb1b9 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -93,8 +93,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
         let ty_def_id = match self.tcx.type_of(item_def_id).sty {
             ty::Adt(adt, _) => adt.did,
             ty::Foreign(did) => did,
-            ty::Dynamic(ref obj, ..) if obj.principal().is_some() =>
-                obj.principal().unwrap().def_id(),
+            ty::Dynamic(ref obj, ..) => obj.principal().def_id(),
             ty::Projection(ref proj) => proj.trait_ref(self.tcx).def_id,
             _ => return Some(AccessLevel::Public)
         };
@@ -484,7 +483,7 @@ impl<'b, 'a, 'tcx> TypeVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b
         let ty_def_id = match ty.sty {
             ty::Adt(adt, _) => Some(adt.did),
             ty::Foreign(did) => Some(did),
-            ty::Dynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()),
+            ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()),
             ty::Projection(ref proj) => Some(proj.item_def_id),
             ty::FnDef(def_id, ..) |
             ty::Closure(def_id, ..) |
@@ -1456,7 +1455,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
         let ty_def_id = match ty.sty {
             ty::Adt(adt, _) => Some(adt.did),
             ty::Foreign(did) => Some(did),
-            ty::Dynamic(ref obj, ..) => obj.principal().map(|p| p.def_id()),
+            ty::Dynamic(ref obj, ..) => Some(obj.principal().def_id()),
             ty::Projection(ref proj) => {
                 if self.required_visibility == ty::Visibility::Invisible {
                     // Conservatively approximate the whole type alias as public without
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 9c0f945326d..9ee4582fabf 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -680,6 +680,12 @@ pub struct TargetOptions {
     /// typically because the platform needs to unwind for things like stack
     /// unwinders.
     pub requires_uwtable: bool,
+
+    /// Whether or not SIMD types are passed by reference in the Rust ABI,
+    /// typically required if a target can be compiled with a mixed set of
+    /// target features. This is `true` by default, and `false` for targets like
+    /// wasm32 where the whole program either has simd or not.
+    pub simd_types_indirect: bool,
 }
 
 impl Default for TargetOptions {
@@ -760,6 +766,7 @@ impl Default for TargetOptions {
             embed_bitcode: false,
             emit_debug_gdb_scripts: true,
             requires_uwtable: false,
+            simd_types_indirect: true,
         }
     }
 }
@@ -1041,6 +1048,7 @@ impl Target {
         key!(embed_bitcode, bool);
         key!(emit_debug_gdb_scripts, bool);
         key!(requires_uwtable, bool);
+        key!(simd_types_indirect, bool);
 
         if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
             for name in array.iter().filter_map(|abi| abi.as_string()) {
@@ -1250,6 +1258,7 @@ impl ToJson for Target {
         target_option_val!(embed_bitcode);
         target_option_val!(emit_debug_gdb_scripts);
         target_option_val!(requires_uwtable);
+        target_option_val!(simd_types_indirect);
 
         if default.abi_blacklist != self.options.abi_blacklist {
             d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()
diff --git a/src/librustc_target/spec/wasm32_unknown_unknown.rs b/src/librustc_target/spec/wasm32_unknown_unknown.rs
index c0455ceb839..46353068bd0 100644
--- a/src/librustc_target/spec/wasm32_unknown_unknown.rs
+++ b/src/librustc_target/spec/wasm32_unknown_unknown.rs
@@ -54,6 +54,12 @@ pub fn target() -> Result<Target, String> {
         linker: Some("rust-lld".to_owned()),
         lld_flavor: LldFlavor::Wasm,
 
+        // No need for indirection here, simd types can always be passed by
+        // value as the whole module either has simd or not, which is different
+        // from x86 (for example) where programs can have functions that don't
+        // enable simd features.
+        simd_types_indirect: false,
+
         .. Default::default()
     };
     Ok(Target {
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 285fed9544d..e0ee26cba08 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -73,7 +73,7 @@ enum PointerKind<'tcx> {
     /// No metadata attached, ie pointer to sized type or foreign type
     Thin,
     /// A trait object
-    Vtable(Option<DefId>),
+    Vtable(DefId),
     /// Slice
     Length,
     /// The unsize info of this projection
@@ -105,7 +105,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         Ok(match t.sty {
             ty::Slice(_) | ty::Str => Some(PointerKind::Length),
             ty::Dynamic(ref tty, ..) =>
-                Some(PointerKind::Vtable(tty.principal().map(|p| p.def_id()))),
+                Some(PointerKind::Vtable(tty.principal().def_id())),
             ty::Adt(def, substs) if def.is_struct() => {
                 match def.non_enum_variant().fields.last() {
                     None => Some(PointerKind::Thin),
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 202789d1d8a..940fa4d3916 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -198,9 +198,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         self.deduce_sig_from_projection(None, &pb)
                     })
                     .next();
-                let kind = object_type
-                    .principal()
-                    .and_then(|p| self.tcx.lang_items().fn_trait_kind(p.def_id()));
+                let kind = self.tcx.lang_items().fn_trait_kind(object_type.principal().def_id());
                 (sig, kind)
             }
             ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid),
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 4e5488b432d..75f5bf74c6a 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -290,7 +290,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
             .include_raw_pointers()
             .filter_map(|(ty, _)|
                 match ty.sty {
-                    ty::Dynamic(ref data, ..) => data.principal().map(|p| closure(self, ty, p)),
+                    ty::Dynamic(ref data, ..) => Some(closure(self, ty, data.principal())),
                     _ => None,
                 }
             )
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index ec4483204f0..ae02cd64c38 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -452,10 +452,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
 
         match self_ty.sty {
             ty::Dynamic(ref data, ..) => {
-                if let Some(p) = data.principal() {
-                    self.assemble_inherent_candidates_from_object(self_ty, p);
-                    self.assemble_inherent_impl_candidates_for_type(p.def_id());
-                }
+                let p = data.principal();
+                self.assemble_inherent_candidates_from_object(self_ty, p);
+                self.assemble_inherent_impl_candidates_for_type(p.def_id());
             }
             ty::Adt(def, _) => {
                 self.assemble_inherent_impl_candidates_for_type(def.did);
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 28b9dcb9bfd..2006796a100 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -663,8 +663,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 ty::Adt(def, _) => def.did.is_local(),
                 ty::Foreign(did) => did.is_local(),
 
-                ty::Dynamic(ref tr, ..) => tr.principal()
-                    .map_or(false, |p| p.def_id().is_local()),
+                ty::Dynamic(ref tr, ..) => tr.principal().def_id().is_local(),
 
                 ty::Param(_) => true,
 
diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs
index 1955a709dbf..ec979dea4fd 100644
--- a/src/librustc_typeck/coherence/inherent_impls.rs
+++ b/src/librustc_typeck/coherence/inherent_impls.rs
@@ -108,8 +108,8 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
             ty::Foreign(did) => {
                 self.check_def_id(item, did);
             }
-            ty::Dynamic(ref data, ..) if data.principal().is_some() => {
-                self.check_def_id(item, data.principal().unwrap().def_id());
+            ty::Dynamic(ref data, ..) => {
+                self.check_def_id(item, data.principal().def_id());
             }
             ty::Char => {
                 self.check_primitive_impl(def_id,
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index 616ca97a7a7..9b17654d469 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -181,13 +181,12 @@ fn check_impl_overlap<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, node_id: ast::NodeI
         // This is something like impl Trait1 for Trait2. Illegal
         // if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
 
-        if data.principal().map_or(true, |p| !tcx.is_object_safe(p.def_id())) {
+        if !tcx.is_object_safe(data.principal().def_id()) {
             // This is an error, but it will be reported by wfcheck.  Ignore it here.
             // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
         } else {
             let mut supertrait_def_ids =
-                traits::supertrait_def_ids(tcx,
-                                           data.principal().unwrap().def_id());
+                traits::supertrait_def_ids(tcx, data.principal().def_id());
             if supertrait_def_ids.any(|d| d == trait_def_id) {
                 let sp = tcx.sess.source_map().def_span(tcx.span_of_impl(impl_def_id).unwrap());
                 struct_span_err!(tcx.sess,
diff --git a/src/librustc_typeck/outlives/implicit_infer.rs b/src/librustc_typeck/outlives/implicit_infer.rs
index 254146c0ef3..132da8f5cea 100644
--- a/src/librustc_typeck/outlives/implicit_infer.rs
+++ b/src/librustc_typeck/outlives/implicit_infer.rs
@@ -203,28 +203,27 @@ fn insert_required_predicates_to_be_wf<'tcx>(
                 debug!("Dynamic");
                 debug!("field_ty = {}", &field_ty);
                 debug!("ty in field = {}", &ty);
-                if let Some(ex_trait_ref) = obj.principal() {
-                    // Here, we are passing the type `usize` as a
-                    // placeholder value with the function
-                    // `with_self_ty`, since there is no concrete type
-                    // `Self` for a `dyn Trait` at this
-                    // stage. Therefore when checking explicit
-                    // predicates in `check_explicit_predicates` we
-                    // need to ignore checking the explicit_map for
-                    // Self type.
-                    let substs = ex_trait_ref
-                        .with_self_ty(tcx, tcx.types.usize)
-                        .skip_binder()
-                        .substs;
-                    check_explicit_predicates(
-                        tcx,
-                        &ex_trait_ref.skip_binder().def_id,
-                        substs,
-                        required_predicates,
-                        explicit_map,
-                        IgnoreSelfTy(true),
-                    );
-                }
+                let ex_trait_ref = obj.principal();
+                // Here, we are passing the type `usize` as a
+                // placeholder value with the function
+                // `with_self_ty`, since there is no concrete type
+                // `Self` for a `dyn Trait` at this
+                // stage. Therefore when checking explicit
+                // predicates in `check_explicit_predicates` we
+                // need to ignore checking the explicit_map for
+                // Self type.
+                let substs = ex_trait_ref
+                    .with_self_ty(tcx, tcx.types.usize)
+                    .skip_binder()
+                    .substs;
+                check_explicit_predicates(
+                    tcx,
+                    &ex_trait_ref.skip_binder().def_id,
+                    substs,
+                    required_predicates,
+                    explicit_map,
+                    IgnoreSelfTy(true),
+                );
             }
 
             ty::Projection(obj) => {
diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs
index 32a591777db..3e523c0c7f5 100644
--- a/src/librustc_typeck/variance/constraints.rs
+++ b/src/librustc_typeck/variance/constraints.rs
@@ -311,11 +311,11 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                 let contra = self.contravariant(variance);
                 self.add_constraints_from_region(current, r, contra);
 
-                if let Some(p) = data.principal() {
-                    let poly_trait_ref = p.with_self_ty(self.tcx(), self.tcx().types.err);
-                    self.add_constraints_from_trait_ref(
-                        current, *poly_trait_ref.skip_binder(), variance);
-                }
+                let poly_trait_ref = data
+                    .principal()
+                    .with_self_ty(self.tcx(), self.tcx().types.err);
+                self.add_constraints_from_trait_ref(
+                    current, *poly_trait_ref.skip_binder(), variance);
 
                 for projection in data.projection_bounds() {
                     self.add_constraints_from_ty(
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index ddabef96c7c..2ba1f103971 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2632,47 +2632,44 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                 }
             }
             ty::Dynamic(ref obj, ref reg) => {
-                if let Some(principal) = obj.principal() {
-                    let did = principal.def_id();
+                let principal = obj.principal();
+                let did = principal.def_id();
+                inline::record_extern_fqn(cx, did, TypeKind::Trait);
+
+                let mut typarams = vec![];
+                reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b)));
+                for did in obj.auto_traits() {
+                    let empty = cx.tcx.intern_substs(&[]);
+                    let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
+                        Some(did), false, vec![], empty);
                     inline::record_extern_fqn(cx, did, TypeKind::Trait);
+                    let bound = GenericBound::TraitBound(PolyTrait {
+                        trait_: ResolvedPath {
+                            path,
+                            typarams: None,
+                            did,
+                            is_generic: false,
+                        },
+                        generic_params: Vec::new(),
+                    }, hir::TraitBoundModifier::None);
+                    typarams.push(bound);
+                }
 
-                    let mut typarams = vec![];
-                    reg.clean(cx).map(|b| typarams.push(GenericBound::Outlives(b)));
-                    for did in obj.auto_traits() {
-                        let empty = cx.tcx.intern_substs(&[]);
-                        let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
-                            Some(did), false, vec![], empty);
-                        inline::record_extern_fqn(cx, did, TypeKind::Trait);
-                        let bound = GenericBound::TraitBound(PolyTrait {
-                            trait_: ResolvedPath {
-                                path,
-                                typarams: None,
-                                did,
-                                is_generic: false,
-                            },
-                            generic_params: Vec::new(),
-                        }, hir::TraitBoundModifier::None);
-                        typarams.push(bound);
-                    }
-
-                    let mut bindings = vec![];
-                    for pb in obj.projection_bounds() {
-                        bindings.push(TypeBinding {
-                            name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx),
-                            ty: pb.skip_binder().ty.clean(cx)
-                        });
-                    }
+                let mut bindings = vec![];
+                for pb in obj.projection_bounds() {
+                    bindings.push(TypeBinding {
+                        name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx),
+                        ty: pb.skip_binder().ty.clean(cx)
+                    });
+                }
 
-                    let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did),
-                        false, bindings, principal.skip_binder().substs);
-                    ResolvedPath {
-                        path,
-                        typarams: Some(typarams),
-                        did,
-                        is_generic: false,
-                    }
-                } else {
-                    Never
+                let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did),
+                    false, bindings, principal.skip_binder().substs);
+                ResolvedPath {
+                    path,
+                    typarams: Some(typarams),
+                    did,
+                    is_generic: false,
                 }
             }
             ty::Tuple(ref t) => Tuple(t.clean(cx)),
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index bcdd1b4b088..cd1e3438fc3 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -48,4 +48,13 @@ jemalloc = ["alloc_jemalloc"]
 force_alloc_system = []
 panic-unwind = ["panic_unwind"]
 profiler = ["profiler_builtins"]
+
+# An off-by-default feature which enables a linux-syscall-like ABI for libstd to
+# interoperate with the host environment. Currently not well documented and
+# requires rebuilding the standard library to use it.
 wasm_syscall = []
+
+# An off-by-default features to enable libstd to assume that wasm-bindgen is in
+# the environment for hooking up some thread-related information like the
+# current thread id and accessing/getting the current thread's TCB
+wasm-bindgen-threads = []
diff --git a/src/libstd/sys/wasm/mutex_atomics.rs b/src/libstd/sys/wasm/mutex_atomics.rs
index ced6c17ef96..762e807096f 100644
--- a/src/libstd/sys/wasm/mutex_atomics.rs
+++ b/src/libstd/sys/wasm/mutex_atomics.rs
@@ -11,7 +11,8 @@
 use arch::wasm32::atomic;
 use cell::UnsafeCell;
 use mem;
-use sync::atomic::{AtomicUsize, AtomicU64, Ordering::SeqCst};
+use sync::atomic::{AtomicUsize, AtomicU32, Ordering::SeqCst};
+use sys::thread;
 
 pub struct Mutex {
     locked: AtomicUsize,
@@ -70,7 +71,7 @@ impl Mutex {
 }
 
 pub struct ReentrantMutex {
-    owner: AtomicU64,
+    owner: AtomicU32,
     recursions: UnsafeCell<u32>,
 }
 
@@ -91,7 +92,7 @@ unsafe impl Sync for ReentrantMutex {}
 impl ReentrantMutex {
     pub unsafe fn uninitialized() -> ReentrantMutex {
         ReentrantMutex {
-            owner: AtomicU64::new(0),
+            owner: AtomicU32::new(0),
             recursions: UnsafeCell::new(0),
         }
     }
@@ -101,20 +102,20 @@ impl ReentrantMutex {
     }
 
     pub unsafe fn lock(&self) {
-        let me = thread_id();
+        let me = thread::my_id();
         while let Err(owner) = self._try_lock(me) {
-            let val = atomic::wait_i64(self.ptr(), owner as i64, -1);
+            let val = atomic::wait_i32(self.ptr(), owner as i32, -1);
             debug_assert!(val == 0 || val == 1);
         }
     }
 
     #[inline]
     pub unsafe fn try_lock(&self) -> bool {
-        self._try_lock(thread_id()).is_ok()
+        self._try_lock(thread::my_id()).is_ok()
     }
 
     #[inline]
-    unsafe fn _try_lock(&self, id: u64) -> Result<(), u64> {
+    unsafe fn _try_lock(&self, id: u32) -> Result<(), u32> {
         let id = id.checked_add(1).unwrap(); // make sure `id` isn't 0
         match self.owner.compare_exchange(0, id, SeqCst, SeqCst) {
             // we transitioned from unlocked to locked
@@ -153,11 +154,7 @@ impl ReentrantMutex {
     }
 
     #[inline]
-    fn ptr(&self) -> *mut i64 {
-        &self.owner as *const AtomicU64 as *mut i64
+    fn ptr(&self) -> *mut i32 {
+        &self.owner as *const AtomicU32 as *mut i32
     }
 }
-
-fn thread_id() -> u64 {
-    panic!("thread ids not implemented on wasm with atomics yet")
-}
diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs
index bef6c1f3490..4ad89c42b92 100644
--- a/src/libstd/sys/wasm/thread.rs
+++ b/src/libstd/sys/wasm/thread.rs
@@ -69,3 +69,49 @@ pub mod guard {
     pub unsafe fn init() -> Option<Guard> { None }
     pub unsafe fn deinit() {}
 }
+
+cfg_if! {
+    if #[cfg(all(target_feature = "atomics", feature = "wasm-bindgen-threads"))] {
+        #[link(wasm_import_module = "__wbindgen_thread_xform__")]
+        extern {
+            fn __wbindgen_current_id() -> u32;
+            fn __wbindgen_tcb_get() -> u32;
+            fn __wbindgen_tcb_set(ptr: u32);
+        }
+        pub fn my_id() -> u32 {
+            unsafe { __wbindgen_current_id() }
+        }
+
+        // These are currently only ever used in `thread_local_atomics.rs`, if
+        // you'd like to use them be sure to update that and make sure everyone
+        // agrees what's what.
+        pub fn tcb_get() -> *mut u8 {
+            use mem;
+            assert_eq!(mem::size_of::<*mut u8>(), mem::size_of::<u32>());
+            unsafe { __wbindgen_tcb_get() as *mut u8 }
+        }
+
+        pub fn tcb_set(ptr: *mut u8) {
+            unsafe { __wbindgen_tcb_set(ptr as u32); }
+        }
+
+        // FIXME: still need something for hooking exiting a thread to free
+        // data...
+
+    } else if #[cfg(target_feature = "atomics")] {
+        pub fn my_id() -> u32 {
+            panic!("thread ids not implemented on wasm with atomics yet")
+        }
+
+        pub fn tcb_get() -> *mut u8 {
+            panic!("thread local data not implemented on wasm with atomics yet")
+        }
+
+        pub fn tcb_set(ptr: *mut u8) {
+            panic!("thread local data not implemented on wasm with atomics yet")
+        }
+    } else {
+        // stubbed out because no functions actually access these intrinsics
+        // unless atomics are enabled
+    }
+}
diff --git a/src/libstd/sys/wasm/thread_local_atomics.rs b/src/libstd/sys/wasm/thread_local_atomics.rs
index 1394013b4a3..acfe60719f2 100644
--- a/src/libstd/sys/wasm/thread_local_atomics.rs
+++ b/src/libstd/sys/wasm/thread_local_atomics.rs
@@ -8,22 +8,61 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use sys::thread;
+use sync::atomic::{AtomicUsize, Ordering::SeqCst};
+
+const MAX_KEYS: usize = 128;
+static NEXT_KEY: AtomicUsize = AtomicUsize::new(0);
+
+struct ThreadControlBlock {
+    keys: [*mut u8; MAX_KEYS],
+}
+
+impl ThreadControlBlock {
+    fn new() -> ThreadControlBlock {
+        ThreadControlBlock {
+            keys: [0 as *mut u8; MAX_KEYS],
+        }
+    }
+
+    fn get() -> *mut ThreadControlBlock {
+        let ptr = thread::tcb_get();
+        if !ptr.is_null() {
+            return ptr as *mut ThreadControlBlock
+        }
+        let tcb = Box::into_raw(Box::new(ThreadControlBlock::new()));
+        thread::tcb_set(tcb as *mut u8);
+        tcb
+    }
+}
+
 pub type Key = usize;
 
-pub unsafe fn create(_dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
-    panic!("TLS on wasm with atomics not implemented yet");
+pub unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
+    drop(dtor); // FIXME: need to figure out how to hook thread exit to run this
+    let key = NEXT_KEY.fetch_add(1, SeqCst);
+    if key >= MAX_KEYS {
+        NEXT_KEY.store(MAX_KEYS, SeqCst);
+        panic!("cannot allocate space for more TLS keys");
+    }
+    // offset by 1 so we never hand out 0. This is currently required by
+    // `sys_common/thread_local.rs` where it can't cope with keys of value 0
+    // because it messes up the atomic management.
+    return key + 1
 }
 
-pub unsafe fn set(_key: Key, _value: *mut u8) {
-    panic!("TLS on wasm with atomics not implemented yet");
+pub unsafe fn set(key: Key, value: *mut u8) {
+    (*ThreadControlBlock::get()).keys[key - 1] = value;
 }
 
-pub unsafe fn get(_key: Key) -> *mut u8 {
-    panic!("TLS on wasm with atomics not implemented yet");
+pub unsafe fn get(key: Key) -> *mut u8 {
+    (*ThreadControlBlock::get()).keys[key - 1]
 }
 
 pub unsafe fn destroy(_key: Key) {
-    panic!("TLS on wasm with atomics not implemented yet");
+    // FIXME: should implement this somehow, this isn't typically called but it
+    // can be called if two threads race to initialize a TLS slot and one ends
+    // up not being needed.
 }
 
 #[inline]
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index a170abb2628..59f100fad1b 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -172,16 +172,22 @@ macro_rules! __thread_local_inner {
                 &'static $crate::cell::UnsafeCell<
                     $crate::option::Option<$t>>>
             {
-                #[cfg(target_arch = "wasm32")]
+                #[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))]
                 static __KEY: $crate::thread::__StaticLocalKeyInner<$t> =
                     $crate::thread::__StaticLocalKeyInner::new();
 
                 #[thread_local]
-                #[cfg(all(target_thread_local, not(target_arch = "wasm32")))]
+                #[cfg(all(
+                    target_thread_local,
+                    not(all(target_arch = "wasm32", not(target_feature = "atomics"))),
+                ))]
                 static __KEY: $crate::thread::__FastLocalKeyInner<$t> =
                     $crate::thread::__FastLocalKeyInner::new();
 
-                #[cfg(all(not(target_thread_local), not(target_arch = "wasm32")))]
+                #[cfg(all(
+                    not(target_thread_local),
+                    not(all(target_arch = "wasm32", not(target_feature = "atomics"))),
+                ))]
                 static __KEY: $crate::thread::__OsLocalKeyInner<$t> =
                     $crate::thread::__OsLocalKeyInner::new();
 
@@ -302,7 +308,7 @@ impl<T: 'static> LocalKey<T> {
 /// On some platforms like wasm32 there's no threads, so no need to generate
 /// thread locals and we can instead just use plain statics!
 #[doc(hidden)]
-#[cfg(target_arch = "wasm32")]
+#[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))]
 pub mod statik {
     use cell::UnsafeCell;
     use fmt;
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index c8d54a63946..796b2bd3eed 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -203,7 +203,7 @@ pub use self::local::{LocalKey, AccessError};
 // where available, but both are needed.
 
 #[unstable(feature = "libstd_thread_internals", issue = "0")]
-#[cfg(target_arch = "wasm32")]
+#[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))]
 #[doc(hidden)] pub use self::local::statik::Key as __StaticLocalKeyInner;
 #[unstable(feature = "libstd_thread_internals", issue = "0")]
 #[cfg(target_thread_local)]
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index b86b92fb29e..84122688c83 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -499,6 +499,9 @@ declare_features! (
 
     // #[cfg_attr(predicate, multiple, attributes, here)]
     (active, cfg_attr_multi, "1.31.0", Some(54881), None),
+
+    // Allows `const _: TYPE = VALUE`
+    (active, underscore_const_names, "1.31.0", Some(54912), None),
 );
 
 declare_features! (
@@ -1583,6 +1586,13 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 }
             }
 
+            ast::ItemKind::Const(_,_) => {
+                if i.ident.name == "_" {
+                    gate_feature_post!(&self, underscore_const_names, i.span,
+                                        "naming constants with `_` is unstable");
+                }
+            }
+
             ast::ItemKind::ForeignMod(ref foreign_module) => {
                 self.check_abi(foreign_module.abi, i.span);
             }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index b5896f37c00..c7089a295fc 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -6346,7 +6346,13 @@ impl<'a> Parser<'a> {
     }
 
     fn parse_item_const(&mut self, m: Option<Mutability>) -> PResult<'a, ItemInfo> {
-        let id = self.parse_ident()?;
+        let id = match self.token {
+                token::Ident(ident, false) if ident.name == keywords::Underscore.name() => {
+                    self.bump(); // `_`
+                    ident.gensym()
+                    },
+                _ => self.parse_ident()?,
+            };
         self.expect(&token::Colon)?;
         let ty = self.parse_ty()?;
         self.expect(&token::Eq)?;
diff --git a/src/stage0.txt b/src/stage0.txt
index f0967d1ba8a..6e931a84bac 100644
--- a/src/stage0.txt
+++ b/src/stage0.txt
@@ -12,7 +12,7 @@
 # source tarball for a stable release you'll likely see `1.x.0` for rustc and
 # `0.x.0` for Cargo where they were released on `date`.
 
-date: 2018-09-23
+date: 2018-10-13
 rustc: beta
 cargo: beta
 
diff --git a/src/test/mir-opt/inline-trait-method.rs b/src/test/mir-opt/inline-trait-method.rs
new file mode 100644
index 00000000000..0f79f43ee2d
--- /dev/null
+++ b/src/test/mir-opt/inline-trait-method.rs
@@ -0,0 +1,31 @@
+// compile-flags: -Z span_free_formats
+
+fn main() {
+    println!("{}", test(&()));
+}
+
+fn test(x: &dyn X) -> u32 {
+    x.y()
+}
+
+trait X {
+    fn y(&self) -> u32 {
+        1
+    }
+}
+
+impl X for () {
+    fn y(&self) -> u32 {
+        2
+    }
+}
+
+// END RUST SOURCE
+// START rustc.test.Inline.after.mir
+// ...
+// bb0: {
+// ...
+//     _0 = const X::y(move _2) -> bb1;
+// }
+// ...
+// END rustc.test.Inline.after.mir
diff --git a/src/test/run-pass/resolve-pseudo-shadowing.rs b/src/test/run-pass/resolve-pseudo-shadowing.rs
index 071279ae7d8..bf6e686bb7b 100644
--- a/src/test/run-pass/resolve-pseudo-shadowing.rs
+++ b/src/test/run-pass/resolve-pseudo-shadowing.rs
@@ -12,7 +12,7 @@
 
 fn check<Clone>(_c: Clone) {
     fn check2() {
-        <() as std::clone::Clone>::clone(&());
+        let _ = <() as std::clone::Clone>::clone(&());
     }
     check2();
 }
diff --git a/src/test/ui/closure-expected-type/README.md b/src/test/ui/closure-expected-type/README.md
deleted file mode 100644
index 9995b00a9a7..00000000000
--- a/src/test/ui/closure-expected-type/README.md
+++ /dev/null
@@ -1 +0,0 @@
-See `src/test/run-pass/closure-expected-type`.
diff --git a/src/test/ui/closure-expected-type/issue-24421.rs b/src/test/ui/closure-expected-type/issue-24421.rs
new file mode 100644
index 00000000000..b3c50a74a32
--- /dev/null
+++ b/src/test/ui/closure-expected-type/issue-24421.rs
@@ -0,0 +1,20 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-pass
+
+fn test<F: Fn(&u64, &u64)>(f: F) {}
+
+fn main() {
+    test(|x,      y     | {});
+    test(|x:&u64, y:&u64| {});
+    test(|x:&u64, y     | {});
+    test(|x,      y:&u64| {});
+}
diff --git a/src/test/ui/feature-gate-underscore_const_names.rs b/src/test/ui/feature-gate-underscore_const_names.rs
new file mode 100644
index 00000000000..b283e286514
--- /dev/null
+++ b/src/test/ui/feature-gate-underscore_const_names.rs
@@ -0,0 +1,24 @@
+// Copyright 2012-2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+#![feature(const_let)]
+
+trait Trt {}
+struct Str {}
+
+impl Trt for Str {}
+
+const _ : () = {
+    use std::marker::PhantomData;
+    struct ImplementsTrait<T: Trt>(PhantomData<T>);
+    let _ = ImplementsTrait::<Str>(PhantomData);
+    ()
+};
+
+fn main() {}
diff --git a/src/test/ui/feature-gate-underscore_const_names.stderr b/src/test/ui/feature-gate-underscore_const_names.stderr
new file mode 100644
index 00000000000..ab90ef8f11f
--- /dev/null
+++ b/src/test/ui/feature-gate-underscore_const_names.stderr
@@ -0,0 +1,16 @@
+error[E0658]: naming constants with `_` is unstable (see issue #54912)
+  --> $DIR/feature-gate-underscore_const_names.rs:17:1
+   |
+LL | / const _ : () = {
+LL | |     use std::marker::PhantomData;
+LL | |     struct ImplementsTrait<T: Trt>(PhantomData<T>);
+LL | |     let _ = ImplementsTrait::<Str>(PhantomData);
+LL | |     ()
+LL | | };
+   | |__^
+   |
+   = help: add #![feature(underscore_const_names)] to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/fn_must_use.rs b/src/test/ui/fn_must_use.rs
index def23046db2..e3e20bc89b4 100644
--- a/src/test/ui/fn_must_use.rs
+++ b/src/test/ui/fn_must_use.rs
@@ -22,6 +22,11 @@ impl MyStruct {
     fn need_to_use_this_method_value(&self) -> usize {
         self.n
     }
+
+    #[must_use]
+    fn need_to_use_this_associated_function_value() -> isize {
+        -1
+    }
 }
 
 trait EvenNature {
@@ -66,6 +71,9 @@ fn main() {
     m.is_even(); // trait method!
     //~^ WARN unused return value
 
+    MyStruct::need_to_use_this_associated_function_value();
+    //~^ WARN unused return value
+
     m.replace(3); // won't warn (annotation needs to be in trait definition)
 
     // comparison methods are `must_use`
diff --git a/src/test/ui/fn_must_use.stderr b/src/test/ui/fn_must_use.stderr
index b5bad22f3dc..1bce8abbbf0 100644
--- a/src/test/ui/fn_must_use.stderr
+++ b/src/test/ui/fn_must_use.stderr
@@ -1,5 +1,5 @@
 warning: unused return value of `need_to_use_this_value` which must be used
-  --> $DIR/fn_must_use.rs:60:5
+  --> $DIR/fn_must_use.rs:65:5
    |
 LL |     need_to_use_this_value(); //~ WARN unused return value
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -12,39 +12,45 @@ LL | #![warn(unused_must_use)]
    = note: it's important
 
 warning: unused return value of `MyStruct::need_to_use_this_method_value` which must be used
-  --> $DIR/fn_must_use.rs:65:5
+  --> $DIR/fn_must_use.rs:70:5
    |
 LL |     m.need_to_use_this_method_value(); //~ WARN unused return value
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: unused return value of `EvenNature::is_even` which must be used
-  --> $DIR/fn_must_use.rs:66:5
+  --> $DIR/fn_must_use.rs:71:5
    |
 LL |     m.is_even(); // trait method!
    |     ^^^^^^^^^^^^
    |
    = note: no side effects
 
+warning: unused return value of `MyStruct::need_to_use_this_associated_function_value` which must be used
+  --> $DIR/fn_must_use.rs:74:5
+   |
+LL |     MyStruct::need_to_use_this_associated_function_value();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 warning: unused return value of `std::cmp::PartialEq::eq` which must be used
-  --> $DIR/fn_must_use.rs:72:5
+  --> $DIR/fn_must_use.rs:80:5
    |
 LL |     2.eq(&3); //~ WARN unused return value
    |     ^^^^^^^^^
 
 warning: unused return value of `std::cmp::PartialEq::eq` which must be used
-  --> $DIR/fn_must_use.rs:73:5
+  --> $DIR/fn_must_use.rs:81:5
    |
 LL |     m.eq(&n); //~ WARN unused return value
    |     ^^^^^^^^^
 
 warning: unused comparison which must be used
-  --> $DIR/fn_must_use.rs:76:5
+  --> $DIR/fn_must_use.rs:84:5
    |
 LL |     2 == 3; //~ WARN unused comparison
    |     ^^^^^^
 
 warning: unused comparison which must be used
-  --> $DIR/fn_must_use.rs:77:5
+  --> $DIR/fn_must_use.rs:85:5
    |
 LL |     m == n; //~ WARN unused comparison
    |     ^^^^^^
diff --git a/src/test/ui/issues/issue-52240.nll.stderr b/src/test/ui/issues/issue-52240.nll.stderr
new file mode 100644
index 00000000000..69b663b17d3
--- /dev/null
+++ b/src/test/ui/issues/issue-52240.nll.stderr
@@ -0,0 +1,9 @@
+error[E0596]: cannot borrow data in a `&` reference as mutable
+  --> $DIR/issue-52240.rs:9:27
+   |
+LL |     if let (Some(Foo::Bar(ref mut val)), _) = (&arr.get(0), 0) {
+   |                           ^^^^^^^^^^^ cannot borrow as mutable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/issues/issue-52240.rs b/src/test/ui/issues/issue-52240.rs
new file mode 100644
index 00000000000..9ac7e9905da
--- /dev/null
+++ b/src/test/ui/issues/issue-52240.rs
@@ -0,0 +1,16 @@
+// issue-52240: Can turn immutable into mut with `ref mut`
+
+enum Foo {
+    Bar(i32),
+}
+
+fn main() {
+    let arr = vec!(Foo::Bar(0));
+    if let (Some(Foo::Bar(ref mut val)), _) = (&arr.get(0), 0) {
+        //~^ ERROR cannot borrow field of immutable binding as mutable
+        *val = 9001;
+    }
+    match arr[0] {
+        Foo::Bar(ref s) => println!("{}", s)
+    }
+}
diff --git a/src/test/ui/issues/issue-52240.stderr b/src/test/ui/issues/issue-52240.stderr
new file mode 100644
index 00000000000..c2c2524816d
--- /dev/null
+++ b/src/test/ui/issues/issue-52240.stderr
@@ -0,0 +1,9 @@
+error[E0596]: cannot borrow field of immutable binding as mutable
+  --> $DIR/issue-52240.rs:9:27
+   |
+LL |     if let (Some(Foo::Bar(ref mut val)), _) = (&arr.get(0), 0) {
+   |                           ^^^^^^^^^^^ cannot mutably borrow field of immutable binding
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/issues/issue-54966.rs b/src/test/ui/issues/issue-54966.rs
new file mode 100644
index 00000000000..0ed3c4b3ca9
--- /dev/null
+++ b/src/test/ui/issues/issue-54966.rs
@@ -0,0 +1,6 @@
+// issue-54966: ICE returning an unknown type with impl FnMut
+
+fn generate_duration() -> Oper<impl FnMut()> {}
+//~^ ERROR cannot find type `Oper` in this scope
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-54966.stderr b/src/test/ui/issues/issue-54966.stderr
new file mode 100644
index 00000000000..aa9a61cb592
--- /dev/null
+++ b/src/test/ui/issues/issue-54966.stderr
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `Oper` in this scope
+  --> $DIR/issue-54966.rs:3:27
+   |
+LL | fn generate_duration() -> Oper<impl FnMut()> {}
+   |                           ^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/src/test/ui/underscore_const_names.rs b/src/test/ui/underscore_const_names.rs
new file mode 100644
index 00000000000..8d31fd0b1e9
--- /dev/null
+++ b/src/test/ui/underscore_const_names.rs
@@ -0,0 +1,43 @@
+// Copyright 2012-2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-pass
+
+#![feature(const_let)]
+#![feature(underscore_const_names)]
+
+trait Trt {}
+struct Str {}
+impl Trt for Str {}
+
+macro_rules! check_impl {
+    ($struct:ident,$trait:ident) => {
+        const _ : () = {
+            use std::marker::PhantomData;
+            struct ImplementsTrait<T: $trait>(PhantomData<T>);
+            let _ = ImplementsTrait::<$struct>(PhantomData);
+            ()
+        };
+    }
+}
+
+#[deny(unused)]
+const _ : () = ();
+
+const _ : i32 = 42;
+const _ : Str = Str{};
+
+check_impl!(Str, Trt);
+check_impl!(Str, Trt);
+
+fn main() {
+  check_impl!(Str, Trt);
+  check_impl!(Str, Trt);
+}
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject ad6e5c0037d88602a1c95051e42b392ed5ffcbe
+Subproject 5dbac98885199bbd7c0f189d7405b5523434d1e
diff --git a/src/tools/clippy b/src/tools/clippy
-Subproject 32b1d1fc157f71ed2f10b60fe28abe087a74361
+Subproject 9d3373137b74a403281b293b19ab9346773af07
diff --git a/src/tools/miri b/src/tools/miri
-Subproject 26f9d617c347185433b77c481a5c50c55d9b72c
+Subproject 8b14b03368429e6ee2a8ac0e0c876505606ab1f
diff --git a/src/tools/rls b/src/tools/rls
-Subproject 15d4d4a5b0cf3c0155195f3322cc7a61148e556
+Subproject 440a9855b73b6bf9b5345cf3a79565566f6ef34