From 515446cf1ec86fc4a0e853b079b35f377601c9fa Mon Sep 17 00:00:00 2001
From: Kornel <kornel@geekhood.net>
Date: Thu, 27 Feb 2020 16:28:27 +0000
Subject: [PATCH 01/16] Make error message clearer about creating new module

#69492
---
 src/librustc_parse/parser/diagnostics.rs              | 11 ++++-------
 src/librustc_parse/parser/module.rs                   |  4 +---
 src/test/ui/error-codes/E0583.stderr                  |  2 +-
 .../invalid-module-declaration.stderr                 |  2 +-
 .../missing_non_modrs_mod.stderr                      |  2 +-
 .../missing_non_modrs_mod_inline.stderr               |  2 +-
 src/test/ui/parser/mod_file_not_exist.rs              |  2 +-
 src/test/ui/parser/mod_file_not_exist.stderr          |  2 +-
 src/test/ui/parser/mod_file_not_exist_windows.stderr  |  2 +-
 9 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs
index c27b429563aca..07b6417f1a5c9 100644
--- a/src/librustc_parse/parser/diagnostics.rs
+++ b/src/librustc_parse/parser/diagnostics.rs
@@ -18,6 +18,7 @@ use rustc_span::{MultiSpan, Span, SpanSnippetError, DUMMY_SP};
 
 use log::{debug, trace};
 use std::mem;
+use std::path::PathBuf;
 
 const TURBOFISH: &'static str = "use `::<...>` instead of `<...>` to specify type arguments";
 
@@ -42,9 +43,7 @@ pub(super) fn dummy_arg(ident: Ident) -> Param {
 pub enum Error {
     FileNotFoundForModule {
         mod_name: String,
-        default_path: String,
-        secondary_path: String,
-        dir_path: String,
+        default_path: PathBuf,
     },
     DuplicatePaths {
         mod_name: String,
@@ -60,8 +59,6 @@ impl Error {
             Error::FileNotFoundForModule {
                 ref mod_name,
                 ref default_path,
-                ref secondary_path,
-                ref dir_path,
             } => {
                 let mut err = struct_span_err!(
                     handler,
@@ -71,8 +68,8 @@ impl Error {
                     mod_name,
                 );
                 err.help(&format!(
-                    "name the file either {} or {} inside the directory \"{}\"",
-                    default_path, secondary_path, dir_path,
+                    "to create the module `{}`, create file \"{}\"",
+                    mod_name, default_path.display(),
                 ));
                 err
             }
diff --git a/src/librustc_parse/parser/module.rs b/src/librustc_parse/parser/module.rs
index 4e9a9a5021b5c..27322b7246922 100644
--- a/src/librustc_parse/parser/module.rs
+++ b/src/librustc_parse/parser/module.rs
@@ -236,9 +236,7 @@ impl<'a> Parser<'a> {
             }),
             (false, false) => Err(Error::FileNotFoundForModule {
                 mod_name: mod_name.clone(),
-                default_path: default_path_str,
-                secondary_path: secondary_path_str,
-                dir_path: dir_path.display().to_string(),
+                default_path,
             }),
             (true, true) => Err(Error::DuplicatePaths {
                 mod_name: mod_name.clone(),
diff --git a/src/test/ui/error-codes/E0583.stderr b/src/test/ui/error-codes/E0583.stderr
index ef7a48bc8a48f..5d47b633e78db 100644
--- a/src/test/ui/error-codes/E0583.stderr
+++ b/src/test/ui/error-codes/E0583.stderr
@@ -4,7 +4,7 @@ error[E0583]: file not found for module `module_that_doesnt_exist`
 LL | mod module_that_doesnt_exist;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: name the file either module_that_doesnt_exist.rs or module_that_doesnt_exist/mod.rs inside the directory "$DIR"
+   = help: to create the module `module_that_doesnt_exist`, create file "$DIR/module_that_doesnt_exist.rs"
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr b/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr
index c95df5b4534c1..5d2cdaef1a761 100644
--- a/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr
+++ b/src/test/ui/invalid-module-declaration/invalid-module-declaration.stderr
@@ -4,7 +4,7 @@ error[E0583]: file not found for module `baz`
 LL | pub mod baz;
    |         ^^^
    |
-   = help: name the file either bar/baz.rs or bar/baz/mod.rs inside the directory "$DIR/auxiliary/foo"
+   = help: to create the module `baz`, create file "$DIR/auxiliary/foo/bar/baz.rs"
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr b/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr
index 98b74e5f5cbca..e8d997e6de091 100644
--- a/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr
+++ b/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod.stderr
@@ -4,7 +4,7 @@ error[E0583]: file not found for module `missing`
 LL | mod missing;
    |     ^^^^^^^
    |
-   = help: name the file either foo/missing.rs or foo/missing/mod.rs inside the directory "$DIR"
+   = help: to create the module `missing`, create file "$DIR/foo/missing.rs"
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod_inline.stderr b/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod_inline.stderr
index 457e8fcccbfb3..b2b0f8b466a04 100644
--- a/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod_inline.stderr
+++ b/src/test/ui/missing_non_modrs_mod/missing_non_modrs_mod_inline.stderr
@@ -4,7 +4,7 @@ error[E0583]: file not found for module `missing`
 LL |     mod missing;
    |         ^^^^^^^
    |
-   = help: name the file either missing.rs or missing/mod.rs inside the directory "$DIR/foo_inline/inline"
+   = help: to create the module `missing`, create file "$DIR/foo_inline/inline/missing.rs"
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/mod_file_not_exist.rs b/src/test/ui/parser/mod_file_not_exist.rs
index e662c707a38b9..71fbc7aea45eb 100644
--- a/src/test/ui/parser/mod_file_not_exist.rs
+++ b/src/test/ui/parser/mod_file_not_exist.rs
@@ -1,7 +1,7 @@
 // ignore-windows
 
 mod not_a_real_file; //~ ERROR file not found for module `not_a_real_file`
-//~^ HELP name the file either not_a_real_file.rs or not_a_real_file/mod.rs inside the directory
+//~^ HELP to create the module `not_a_real_file`, create file "
 
 fn main() {
     assert_eq!(mod_file_aux::bar(), 10);
diff --git a/src/test/ui/parser/mod_file_not_exist.stderr b/src/test/ui/parser/mod_file_not_exist.stderr
index dadf4b29dcf39..db3ea04ac7655 100644
--- a/src/test/ui/parser/mod_file_not_exist.stderr
+++ b/src/test/ui/parser/mod_file_not_exist.stderr
@@ -4,7 +4,7 @@ error[E0583]: file not found for module `not_a_real_file`
 LL | mod not_a_real_file;
    |     ^^^^^^^^^^^^^^^
    |
-   = help: name the file either not_a_real_file.rs or not_a_real_file/mod.rs inside the directory "$DIR"
+   = help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs"
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/mod_file_not_exist_windows.stderr b/src/test/ui/parser/mod_file_not_exist_windows.stderr
index 60ae00abab1ed..a58db80f73d7d 100644
--- a/src/test/ui/parser/mod_file_not_exist_windows.stderr
+++ b/src/test/ui/parser/mod_file_not_exist_windows.stderr
@@ -4,7 +4,7 @@ error[E0583]: file not found for module `not_a_real_file`
 LL | mod not_a_real_file;
    |     ^^^^^^^^^^^^^^^
    |
-   = help: name the file either not_a_real_file.rs or not_a_real_file/mod.rs inside the directory "$DIR"
+   = help: to create the module `not_a_real_file`, create file "$DIR/not_a_real_file.rs"
 
 error: aborting due to previous error
 

From 96b32613a0b81c9335238b0ca1568afb87880c19 Mon Sep 17 00:00:00 2001
From: Kornel <kornel@geekhood.net>
Date: Sun, 1 Mar 2020 13:48:19 +0000
Subject: [PATCH 02/16] Apply rustfmt :(

---
 src/librustc_parse/parser/diagnostics.rs | 19 +++++--------------
 src/librustc_parse/parser/module.rs      |  7 +++----
 2 files changed, 8 insertions(+), 18 deletions(-)

diff --git a/src/librustc_parse/parser/diagnostics.rs b/src/librustc_parse/parser/diagnostics.rs
index 07b6417f1a5c9..62fc464551bcb 100644
--- a/src/librustc_parse/parser/diagnostics.rs
+++ b/src/librustc_parse/parser/diagnostics.rs
@@ -41,25 +41,15 @@ pub(super) fn dummy_arg(ident: Ident) -> Param {
 }
 
 pub enum Error {
-    FileNotFoundForModule {
-        mod_name: String,
-        default_path: PathBuf,
-    },
-    DuplicatePaths {
-        mod_name: String,
-        default_path: String,
-        secondary_path: String,
-    },
+    FileNotFoundForModule { mod_name: String, default_path: PathBuf },
+    DuplicatePaths { mod_name: String, default_path: String, secondary_path: String },
     UselessDocComment,
 }
 
 impl Error {
     fn span_err(self, sp: impl Into<MultiSpan>, handler: &Handler) -> DiagnosticBuilder<'_> {
         match self {
-            Error::FileNotFoundForModule {
-                ref mod_name,
-                ref default_path,
-            } => {
+            Error::FileNotFoundForModule { ref mod_name, ref default_path } => {
                 let mut err = struct_span_err!(
                     handler,
                     sp,
@@ -69,7 +59,8 @@ impl Error {
                 );
                 err.help(&format!(
                     "to create the module `{}`, create file \"{}\"",
-                    mod_name, default_path.display(),
+                    mod_name,
+                    default_path.display(),
                 ));
                 err
             }
diff --git a/src/librustc_parse/parser/module.rs b/src/librustc_parse/parser/module.rs
index 27322b7246922..008320396ebbc 100644
--- a/src/librustc_parse/parser/module.rs
+++ b/src/librustc_parse/parser/module.rs
@@ -234,10 +234,9 @@ impl<'a> Parser<'a> {
                 path: secondary_path,
                 directory_ownership: DirectoryOwnership::Owned { relative: None },
             }),
-            (false, false) => Err(Error::FileNotFoundForModule {
-                mod_name: mod_name.clone(),
-                default_path,
-            }),
+            (false, false) => {
+                Err(Error::FileNotFoundForModule { mod_name: mod_name.clone(), default_path })
+            }
             (true, true) => Err(Error::DuplicatePaths {
                 mod_name: mod_name.clone(),
                 default_path: default_path_str,

From 7b6f5ed9562ad13b68224138992a06463de299c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 1 Mar 2020 10:46:07 -0800
Subject: [PATCH 03/16] `delay_span_bug` when codegen cannot select obligation

Fix #69602, introduced in #60126 by letting the compiler continue past
type checking after encountering errors.
---
 src/librustc/query/mod.rs                     |  2 +-
 src/librustc_infer/traits/codegen/mod.rs      | 18 +++++++++------
 src/librustc_mir/monomorphize/mod.rs          |  2 +-
 src/librustc_ty/instance.rs                   |  2 +-
 ...issue-69602-type-err-during-codegen-ice.rs | 22 +++++++++++++++++++
 ...e-69602-type-err-during-codegen-ice.stderr | 19 ++++++++++++++++
 6 files changed, 55 insertions(+), 10 deletions(-)
 create mode 100644 src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs
 create mode 100644 src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr

diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index b3315cc3701da..27d9435ac57dd 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -650,7 +650,7 @@ rustc_queries! {
     Codegen {
         query codegen_fulfill_obligation(
             key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
-        ) -> Vtable<'tcx, ()> {
+        ) -> Option<Vtable<'tcx, ()>> {
             no_force
             cache_on_disk_if { true }
             desc { |tcx|
diff --git a/src/librustc_infer/traits/codegen/mod.rs b/src/librustc_infer/traits/codegen/mod.rs
index bd4129a4de76c..f499565e9192a 100644
--- a/src/librustc_infer/traits/codegen/mod.rs
+++ b/src/librustc_infer/traits/codegen/mod.rs
@@ -19,7 +19,7 @@ use rustc::ty::{self, TyCtxt};
 pub fn codegen_fulfill_obligation<'tcx>(
     ty: TyCtxt<'tcx>,
     (param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>),
-) -> Vtable<'tcx, ()> {
+) -> Option<Vtable<'tcx, ()>> {
     // Remove any references to regions; this helps improve caching.
     let trait_ref = ty.erase_regions(&trait_ref);
 
@@ -47,11 +47,15 @@ pub fn codegen_fulfill_obligation<'tcx>(
                 // leading to an ambiguous result. So report this as an
                 // overflow bug, since I believe this is the only case
                 // where ambiguity can result.
-                bug!(
-                    "Encountered ambiguity selecting `{:?}` during codegen, \
-                      presuming due to overflow",
-                    trait_ref
-                )
+                infcx.tcx.sess.delay_span_bug(
+                    rustc_span::DUMMY_SP,
+                    &format!(
+                        "encountered ambiguity selecting `{:?}` during codegen, presuming due to \
+                         overflow or prior type error",
+                        trait_ref
+                    ),
+                );
+                return None;
             }
             Err(e) => {
                 bug!("Encountered error `{:?}` selecting `{:?}` during codegen", e, trait_ref)
@@ -71,7 +75,7 @@ pub fn codegen_fulfill_obligation<'tcx>(
         let vtable = infcx.drain_fulfillment_cx_or_panic(&mut fulfill_cx, &vtable);
 
         info!("Cache miss: {:?} => {:?}", trait_ref, vtable);
-        vtable
+        Some(vtable)
     })
 }
 
diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs
index 8bc63bfcfcbe3..3dff06967e50e 100644
--- a/src/librustc_mir/monomorphize/mod.rs
+++ b/src/librustc_mir/monomorphize/mod.rs
@@ -18,7 +18,7 @@ pub fn custom_coerce_unsize_info<'tcx>(
     });
 
     match tcx.codegen_fulfill_obligation((ty::ParamEnv::reveal_all(), trait_ref)) {
-        traits::VtableImpl(traits::VtableImplData { impl_def_id, .. }) => {
+        Some(traits::VtableImpl(traits::VtableImplData { impl_def_id, .. })) => {
             tcx.coerce_unsized_info(impl_def_id).custom_kind.unwrap()
         }
         vtable => {
diff --git a/src/librustc_ty/instance.rs b/src/librustc_ty/instance.rs
index 484b774add462..c2b2196e74c61 100644
--- a/src/librustc_ty/instance.rs
+++ b/src/librustc_ty/instance.rs
@@ -70,7 +70,7 @@ fn resolve_associated_item<'tcx>(
     );
 
     let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_substs);
-    let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref)));
+    let vtbl = tcx.codegen_fulfill_obligation((param_env, ty::Binder::bind(trait_ref)))?;
 
     // Now that we know which impl is being used, we can dispatch to
     // the actual function:
diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs
new file mode 100644
index 0000000000000..2c5257ce063cb
--- /dev/null
+++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.rs
@@ -0,0 +1,22 @@
+trait TraitA {
+    const VALUE: usize;
+}
+
+struct A;
+impl TraitA for A {
+  const VALUE: usize = 0;
+}
+
+trait TraitB {
+    type MyA: TraitA;
+    const VALUE: usize = Self::MyA::VALUE;
+}
+
+struct B;
+impl TraitB for B { //~ ERROR not all trait items implemented, missing: `MyA`
+    type M   = A; //~ ERROR type `M` is not a member of trait `TraitB`
+}
+
+fn main() {
+    let _ = [0; B::VALUE];
+}
diff --git a/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr
new file mode 100644
index 0000000000000..8ae0f8b804c93
--- /dev/null
+++ b/src/test/ui/issues/issue-69602-type-err-during-codegen-ice.stderr
@@ -0,0 +1,19 @@
+error[E0437]: type `M` is not a member of trait `TraitB`
+  --> $DIR/issue-69602-type-err-during-codegen-ice.rs:17:5
+   |
+LL |     type M   = A;
+   |     ^^^^^^^^^^^^^ not a member of trait `TraitB`
+
+error[E0046]: not all trait items implemented, missing: `MyA`
+  --> $DIR/issue-69602-type-err-during-codegen-ice.rs:16:1
+   |
+LL |     type MyA: TraitA;
+   |     ----------------- `MyA` from trait
+...
+LL | impl TraitB for B {
+   | ^^^^^^^^^^^^^^^^^ missing `MyA` in implementation
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0046, E0437.
+For more information about an error, try `rustc --explain E0046`.

From c745b4a1841bc5bea8dd50cad85921b36ca47242 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Wed, 4 Mar 2020 13:01:19 +0100
Subject: [PATCH 04/16] Add explanation for E0380

---
 src/librustc_error_codes/error_codes/E0380.md | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/librustc_error_codes/error_codes/E0380.md b/src/librustc_error_codes/error_codes/E0380.md
index fe5de56933963..638f0c8ecc65f 100644
--- a/src/librustc_error_codes/error_codes/E0380.md
+++ b/src/librustc_error_codes/error_codes/E0380.md
@@ -1,4 +1,14 @@
-Auto traits cannot have methods or associated items.
-For more information see the [opt-in builtin traits RFC][RFC 19].
+An auto trait was declared with a method or an associated item.
+
+Erroneous code example:
+
+```compile_fail,E0380
+unsafe auto trait Trait {
+    type Output; // error!
+}
+```
+
+Auto traits cannot have methods or associated items. For more information see
+the [opt-in builtin traits RFC][RFC 19].
 
 [RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md

From 6db7e34ab526abdadbff4e85701f55ce707687b8 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Wed, 4 Mar 2020 13:12:04 +0100
Subject: [PATCH 05/16] use integer assoc consts instead of methods

---
 src/librustc/mir/interpret/allocation.rs | 14 +++++++-------
 src/librustc/mir/interpret/pointer.rs    |  4 ++--
 src/librustc_mir/interpret/intrinsics.rs |  6 +++---
 src/librustc_mir/interpret/validity.rs   |  2 +-
 4 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index d3efe62e8c153..c8d35db0adeb2 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -818,9 +818,9 @@ impl UndefMask {
             // First set all bits except the first `bita`,
             // then unset the last `64 - bitb` bits.
             let range = if bitb == 0 {
-                u64::max_value() << bita
+                u64::MAX << bita
             } else {
-                (u64::max_value() << bita) & (u64::max_value() >> (64 - bitb))
+                (u64::MAX << bita) & (u64::MAX >> (64 - bitb))
             };
             if new_state {
                 self.blocks[blocka] |= range;
@@ -832,21 +832,21 @@ impl UndefMask {
         // across block boundaries
         if new_state {
             // Set `bita..64` to `1`.
-            self.blocks[blocka] |= u64::max_value() << bita;
+            self.blocks[blocka] |= u64::MAX << bita;
             // Set `0..bitb` to `1`.
             if bitb != 0 {
-                self.blocks[blockb] |= u64::max_value() >> (64 - bitb);
+                self.blocks[blockb] |= u64::MAX >> (64 - bitb);
             }
             // Fill in all the other blocks (much faster than one bit at a time).
             for block in (blocka + 1)..blockb {
-                self.blocks[block] = u64::max_value();
+                self.blocks[block] = u64::MAX;
             }
         } else {
             // Set `bita..64` to `0`.
-            self.blocks[blocka] &= !(u64::max_value() << bita);
+            self.blocks[blocka] &= !(u64::MAX << bita);
             // Set `0..bitb` to `0`.
             if bitb != 0 {
-                self.blocks[blockb] &= !(u64::max_value() >> (64 - bitb));
+                self.blocks[blockb] &= !(u64::MAX >> (64 - bitb));
             }
             // Fill in all the other blocks (much faster than one bit at a time).
             for block in (blocka + 1)..blockb {
diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs
index a4974fb541b6b..cc3c50b7899f3 100644
--- a/src/librustc/mir/interpret/pointer.rs
+++ b/src/librustc/mir/interpret/pointer.rs
@@ -78,9 +78,9 @@ pub trait PointerArithmetic: layout::HasDataLayout {
     fn overflowing_signed_offset(&self, val: u64, i: i128) -> (u64, bool) {
         // FIXME: is it possible to over/underflow here?
         if i < 0 {
-            // Trickery to ensure that `i64::min_value()` works fine: compute `n = -i`.
+            // Trickery to ensure that `i64::MIN` works fine: compute `n = -i`.
             // This formula only works for true negative values; it overflows for zero!
-            let n = u64::max_value() - (i as u64) + 1;
+            let n = u64::MAX - (i as u64) + 1;
             let res = val.overflowing_sub(n);
             self.truncate_to_ptr(res)
         } else {
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index d63abdc356234..891afbf437f2b 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -203,7 +203,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         if is_add {
                             // max unsigned
                             Scalar::from_uint(
-                                u128::max_value() >> (128 - num_bits),
+                                u128::MAX >> (128 - num_bits),
                                 Size::from_bits(num_bits),
                             )
                         } else {
@@ -381,11 +381,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         dest: PlaceTy<'tcx, M::PointerTag>,
     ) -> InterpResult<'tcx> {
         // Performs an exact division, resulting in undefined behavior where
-        // `x % y != 0` or `y == 0` or `x == T::min_value() && y == -1`.
+        // `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`.
         // First, check x % y != 0 (or if that computation overflows).
         let (res, overflow, _ty) = self.overflowing_binary_op(BinOp::Rem, a, b)?;
         if overflow || res.assert_bits(a.layout.size) != 0 {
-            // Then, check if `b` is -1, which is the "min_value / -1" case.
+            // Then, check if `b` is -1, which is the "MIN / -1" case.
             let minus1 = Scalar::from_int(-1, dest.layout.size);
             let b_scalar = b.to_scalar().unwrap();
             if b_scalar == minus1 {
diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 731dcc6a25f14..4f99bfe8a852a 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -463,7 +463,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
         let (lo, hi) = valid_range.clone().into_inner();
         // Determine the allowed range
         // `max_hi` is as big as the size fits
-        let max_hi = u128::max_value() >> (128 - op.layout.size.bits());
+        let max_hi = u128::MAX >> (128 - op.layout.size.bits());
         assert!(hi <= max_hi);
         // We could also write `(hi + 1) % (max_hi + 1) == lo` but `max_hi + 1` overflows for `u128`
         if (lo == 0 && hi == max_hi) || (hi + 1 == lo) {

From f0c3cf2b1b7bc3f6a81f91d7552f54dab667bc26 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Wed, 4 Mar 2020 13:18:08 +0100
Subject: [PATCH 06/16] cover some more nearby cases

---
 src/librustc/dep_graph/graph.rs        | 2 +-
 src/librustc/ty/layout.rs              | 5 ++---
 src/librustc/ty/print/pretty.rs        | 2 +-
 src/librustc/ty/query/on_disk_cache.rs | 2 +-
 src/librustc/ty/util.rs                | 6 +++---
 src/librustc_mir/dataflow/mod.rs       | 1 -
 6 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
index 33902fe913a9c..d5cde7034116c 100644
--- a/src/librustc/dep_graph/graph.rs
+++ b/src/librustc/dep_graph/graph.rs
@@ -524,7 +524,7 @@ impl DepGraph {
             edge_list_indices.push((start, end));
         }
 
-        debug_assert!(edge_list_data.len() <= ::std::u32::MAX as usize);
+        debug_assert!(edge_list_data.len() <= u32::MAX as usize);
         debug_assert_eq!(edge_list_data.len(), total_edge_count);
 
         SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data }
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index f1b4b828c71fa..7a5a417919d50 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -7,7 +7,6 @@ use rustc_span::DUMMY_SP;
 
 use std::cmp;
 use std::fmt;
-use std::i128;
 use std::iter;
 use std::mem;
 use std::ops::Bound;
@@ -1001,7 +1000,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     }
                 }
 
-                let (mut min, mut max) = (i128::max_value(), i128::min_value());
+                let (mut min, mut max) = (i128::MAX, i128::MIN);
                 let discr_type = def.repr.discr_type();
                 let bits = Integer::from_attr(self, discr_type).size().bits();
                 for (i, discr) in def.discriminants(tcx) {
@@ -1021,7 +1020,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     }
                 }
                 // We might have no inhabited variants, so pretend there's at least one.
-                if (min, max) == (i128::max_value(), i128::min_value()) {
+                if (min, max) == (i128::MAX, i128::MIN) {
                     min = 0;
                     max = 0;
                 }
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index 3bf92552c8624..4829955cb70c4 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -920,7 +920,7 @@ pub trait PrettyPrinter<'tcx>:
             }
             (ConstValue::Scalar(Scalar::Raw { data, .. }), ty::Uint(ui)) => {
                 let bit_size = Integer::from_attr(&self.tcx(), UnsignedInt(*ui)).size();
-                let max = truncate(u128::max_value(), bit_size);
+                let max = truncate(u128::MAX, bit_size);
 
                 let ui_str = ui.name_str();
                 if data == max {
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 109ac97fe6265..5e36e4df698ed 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -92,7 +92,7 @@ struct AbsoluteBytePos(u32);
 
 impl AbsoluteBytePos {
     fn new(pos: usize) -> AbsoluteBytePos {
-        debug_assert!(pos <= ::std::u32::MAX as usize);
+        debug_assert!(pos <= u32::MAX as usize);
         AbsoluteBytePos(pos as u32)
     }
 
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 7b1f821877baa..62d2b4ae20397 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -50,11 +50,11 @@ fn signed_min(size: Size) -> i128 {
 }
 
 fn signed_max(size: Size) -> i128 {
-    i128::max_value() >> (128 - size.bits())
+    i128::MAX >> (128 - size.bits())
 }
 
 fn unsigned_max(size: Size) -> u128 {
-    u128::max_value() >> (128 - size.bits())
+    u128::MAX >> (128 - size.bits())
 }
 
 fn int_size_and_signed<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> (Size, bool) {
@@ -77,7 +77,7 @@ impl<'tcx> Discr<'tcx> {
             let min = signed_min(size);
             let max = signed_max(size);
             let val = sign_extend(self.val, size) as i128;
-            assert!(n < (i128::max_value() as u128));
+            assert!(n < (i128::MAX as u128));
             let n = n as i128;
             let oflo = val > max - n;
             let val = if oflo { min + (n - (max - val) - 1) } else { val + n };
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index 25463f31867df..b4e33b9502e69 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -16,7 +16,6 @@ use std::borrow::Borrow;
 use std::fmt;
 use std::io;
 use std::path::PathBuf;
-use std::usize;
 
 pub use self::at_location::{FlowAtLocation, FlowsAtLocation};
 pub(crate) use self::drop_flag_effects::*;

From 8ea676eccaa3596c56b5bf665a1adb155b634ff3 Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Mon, 2 Mar 2020 10:00:05 -0800
Subject: [PATCH 07/16] Update books

---
 src/doc/embedded-book   | 2 +-
 src/doc/nomicon         | 2 +-
 src/doc/reference       | 2 +-
 src/doc/rust-by-example | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/doc/embedded-book b/src/doc/embedded-book
index b2e1092bf67bd..b81ffb7a6f4c5 160000
--- a/src/doc/embedded-book
+++ b/src/doc/embedded-book
@@ -1 +1 @@
-Subproject commit b2e1092bf67bd4d7686c4553f186edbb7f5f92db
+Subproject commit b81ffb7a6f4c5aaed92786e770e99db116aa4ebd
diff --git a/src/doc/nomicon b/src/doc/nomicon
index 3e6e1001dc6e0..9f797e65e6bcc 160000
--- a/src/doc/nomicon
+++ b/src/doc/nomicon
@@ -1 +1 @@
-Subproject commit 3e6e1001dc6e095dbd5c88005e80969f60e384e1
+Subproject commit 9f797e65e6bcc79419975b17aff8e21c9adc039f
diff --git a/src/doc/reference b/src/doc/reference
index 64239df6d1735..559e09caa9661 160000
--- a/src/doc/reference
+++ b/src/doc/reference
@@ -1 +1 @@
-Subproject commit 64239df6d173562b9deb4f012e4c3e6e960c4754
+Subproject commit 559e09caa9661043744cf7af7bd88432d966f743
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
index 32facd5522ddb..db57f899ea2a5 160000
--- a/src/doc/rust-by-example
+++ b/src/doc/rust-by-example
@@ -1 +1 @@
-Subproject commit 32facd5522ddbbf37baf01e4e4b6562bc55c071a
+Subproject commit db57f899ea2a56a544c8d280cbf033438666273d

From 0e1cd5935faf9240850c07afb2b7fd8d582c5e25 Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Wed, 4 Mar 2020 08:23:12 -0800
Subject: [PATCH 08/16] Toolstate: remove redundant beta-week check.

---
 src/bootstrap/toolstate.rs | 39 +++++++++-----------------------------
 1 file changed, 9 insertions(+), 30 deletions(-)

diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs
index 7cffc47293070..7b41ba371a83a 100644
--- a/src/bootstrap/toolstate.rs
+++ b/src/bootstrap/toolstate.rs
@@ -215,6 +215,9 @@ impl Step for ToolStateCheck {
                             tool, old_state, state
                         );
                     } else {
+                        // This warning only appears in the logs, which most
+                        // people won't read. It's mostly here for testing and
+                        // debugging.
                         eprintln!(
                             "warning: Tool `{}` is not test-pass (is `{}`), \
                             this should be fixed before beta is branched.",
@@ -222,6 +225,8 @@ impl Step for ToolStateCheck {
                         );
                     }
                 }
+                // publish_toolstate.py will be responsible for creating
+                // comments/issues warning people if there is a regression.
             }
         }
 
@@ -230,7 +235,7 @@ impl Step for ToolStateCheck {
         }
 
         if builder.config.channel == "nightly" && env::var_os("TOOLSTATE_PUBLISH").is_some() {
-            commit_toolstate_change(&toolstates, in_beta_week);
+            commit_toolstate_change(&toolstates);
         }
     }
 
@@ -373,14 +378,12 @@ fn read_old_toolstate() -> Vec<RepoState> {
 ///
 ///       * See <https://help.github.com/articles/about-commit-email-addresses/>
 ///           if a private email by GitHub is wanted.
-fn commit_toolstate_change(current_toolstate: &ToolstateData, in_beta_week: bool) {
-    let old_toolstate = read_old_toolstate();
-
+fn commit_toolstate_change(current_toolstate: &ToolstateData) {
     let message = format!("({} CI update)", OS.expect("linux/windows only"));
     let mut success = false;
     for _ in 1..=5 {
         // Update the toolstate results (the new commit-to-toolstate mapping) in the toolstate repo.
-        change_toolstate(&current_toolstate, &old_toolstate, in_beta_week);
+        change_toolstate(&current_toolstate);
 
         // `git commit` failing means nothing to commit.
         let status = t!(Command::new("git")
@@ -429,31 +432,7 @@ fn commit_toolstate_change(current_toolstate: &ToolstateData, in_beta_week: bool
     }
 }
 
-fn change_toolstate(
-    current_toolstate: &ToolstateData,
-    old_toolstate: &[RepoState],
-    in_beta_week: bool,
-) {
-    let mut regressed = false;
-    for repo_state in old_toolstate {
-        let tool = &repo_state.tool;
-        let state = repo_state.state();
-        let new_state = current_toolstate[tool.as_str()];
-
-        if new_state != state {
-            eprintln!("The state of `{}` has changed from `{}` to `{}`", tool, state, new_state);
-            if new_state < state {
-                if !NIGHTLY_TOOLS.iter().any(|(name, _path)| name == tool) {
-                    regressed = true;
-                }
-            }
-        }
-    }
-
-    if regressed && in_beta_week {
-        std::process::exit(1);
-    }
-
+fn change_toolstate(current_toolstate: &ToolstateData) {
     let commit = t!(std::process::Command::new("git").arg("rev-parse").arg("HEAD").output());
     let commit = t!(String::from_utf8(commit.stdout));
 

From a6d8c9c5ebea585304df74bdf56cff186ad8ef1a Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Wed, 4 Mar 2020 10:17:15 +0100
Subject: [PATCH 09/16] more toolstate comments

---
 src/bootstrap/toolstate.rs     | 8 +++++---
 src/ci/publish_toolstate.sh    | 4 +++-
 src/tools/publish_toolstate.py | 9 ++++-----
 3 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs
index 7b41ba371a83a..c8d8a29ac4e16 100644
--- a/src/bootstrap/toolstate.rs
+++ b/src/bootstrap/toolstate.rs
@@ -330,11 +330,11 @@ fn prepare_toolstate_config(token: &str) {
             Err(_) => false,
         };
         if !success {
-            panic!("git config key={} value={} successful (status: {:?})", key, value, status);
+            panic!("git config key={} value={} failed (status: {:?})", key, value, status);
         }
     }
 
-    // If changing anything here, then please check that src/ci/publish_toolstate.sh is up to date
+    // If changing anything here, then please check that `src/ci/publish_toolstate.sh` is up to date
     // as well.
     git_config("user.email", "7378925+rust-toolstate-update@users.noreply.github.com");
     git_config("user.name", "Rust Toolstate Update");
@@ -382,7 +382,9 @@ fn commit_toolstate_change(current_toolstate: &ToolstateData) {
     let message = format!("({} CI update)", OS.expect("linux/windows only"));
     let mut success = false;
     for _ in 1..=5 {
-        // Update the toolstate results (the new commit-to-toolstate mapping) in the toolstate repo.
+        // Upload the test results (the new commit-to-toolstate mapping) to the toolstate repo.
+        // This does *not* change the "current toolstate"; that only happens post-landing
+        // via `src/ci/docker/publish_toolstate.sh`.
         change_toolstate(&current_toolstate);
 
         // `git commit` failing means nothing to commit.
diff --git a/src/ci/publish_toolstate.sh b/src/ci/publish_toolstate.sh
index 7c43d034d8b7f..691df04e754a6 100755
--- a/src/ci/publish_toolstate.sh
+++ b/src/ci/publish_toolstate.sh
@@ -23,7 +23,9 @@ GIT_COMMIT_MSG="$(git log --format=%s -n1 HEAD)"
 cd rust-toolstate
 FAILURE=1
 for RETRY_COUNT in 1 2 3 4 5; do
-    #  The purpose is to publish the new "current" toolstate in the toolstate repo.
+    # The purpose of this is to publish the new "current" toolstate in the toolstate repo.
+    # This happens post-landing, on master.
+    # (Publishing the per-commit test results happens pre-landing in src/bootstrap/toolstate.rs).
     "$(ciCheckoutPath)/src/tools/publish_toolstate.py" "$GIT_COMMIT" \
         "$GIT_COMMIT_MSG" \
         "$MESSAGE_FILE" \
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 5fbb986286ade..b389cd0373cc4 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -1,11 +1,10 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
-# This script publishes the new "current" toolstate in the toolstate repo (not to be
-# confused with publishing the test results, which happens in
-# `src/ci/docker/x86_64-gnu-tools/checktools.sh`).
-# It is set as callback for `src/ci/docker/x86_64-gnu-tools/repo.sh` by the CI scripts
-# when a new commit lands on `master` (i.e., after it passed all checks on `auto`).
+# This script computes the new "current" toolstate for the toolstate repo (not to be
+# confused with publishing the test results, which happens in `src/bootstrap/toolstate.rs`).
+# It gets called from `src/ci/publish_toolstate.sh` when a new commit lands on `master`
+# (i.e., after it passed all checks on `auto`).
 
 from __future__ import print_function
 

From a41f1f128ee9fbe595a588b9b91d545a895f5c39 Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Wed, 4 Mar 2020 09:49:55 -0800
Subject: [PATCH 10/16] Further clarifications and comments on toolstate
 operation.

---
 src/bootstrap/toolstate.rs | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs
index c8d8a29ac4e16..f0e0f92af55fc 100644
--- a/src/bootstrap/toolstate.rs
+++ b/src/bootstrap/toolstate.rs
@@ -225,8 +225,11 @@ impl Step for ToolStateCheck {
                         );
                     }
                 }
-                // publish_toolstate.py will be responsible for creating
-                // comments/issues warning people if there is a regression.
+                // `publish_toolstate.py` is responsible for updating
+                // `latest.json` and creating comments/issues warning people
+                // if there is a regression. That all happens in a separate CI
+                // job on the master branch once the PR has passed all tests
+                // on the `auto` branch.
             }
         }
 
@@ -385,7 +388,7 @@ fn commit_toolstate_change(current_toolstate: &ToolstateData) {
         // Upload the test results (the new commit-to-toolstate mapping) to the toolstate repo.
         // This does *not* change the "current toolstate"; that only happens post-landing
         // via `src/ci/docker/publish_toolstate.sh`.
-        change_toolstate(&current_toolstate);
+        publish_test_results(&current_toolstate);
 
         // `git commit` failing means nothing to commit.
         let status = t!(Command::new("git")
@@ -434,7 +437,12 @@ fn commit_toolstate_change(current_toolstate: &ToolstateData) {
     }
 }
 
-fn change_toolstate(current_toolstate: &ToolstateData) {
+/// Updates the "history" files with the latest results.
+///
+/// These results will later be promoted to `latest.json` by the
+/// `publish_toolstate.py` script if the PR passes all tests and is merged to
+/// master.
+fn publish_test_results(current_toolstate: &ToolstateData) {
     let commit = t!(std::process::Command::new("git").arg("rev-parse").arg("HEAD").output());
     let commit = t!(String::from_utf8(commit.stdout));
 

From 729d49d7f2a19ffcac8897e6b9e1898fdc0ad0a0 Mon Sep 17 00:00:00 2001
From: Penelope Phippen <penelopedotzone@gmail.com>
Date: Wed, 4 Mar 2020 14:18:31 -0500
Subject: [PATCH 11/16] Update macros.rs: fix documentation typo.

---
 src/libstd/macros.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 9e1ac8754d9b0..7fd7de56f4615 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -185,7 +185,7 @@ macro_rules! eprintln {
 /// builds or when debugging in release mode is significantly faster.
 ///
 /// Note that the macro is intended as a debugging tool and therefore you
-/// should avoid having uses of it in version control for longer periods.
+/// should avoid having uses of it in version control for long periods.
 /// Use cases involving debug output that should be added to version control
 /// are better served by macros such as [`debug!`] from the [`log`] crate.
 ///

From 07168f9cdcaae65550ea04395bef1258e8bbe9c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= <matthias.krueger@famsik.de>
Date: Wed, 4 Mar 2020 13:36:49 +0100
Subject: [PATCH 12/16] Don't use .ok() before unwrapping via .expect() on a
 Result.

The Result can be expect-unwrapped directly. (clippy::ok_expect)
---
 src/librustc_codegen_llvm/context.rs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index 46f461b98c8de..3466363ac7972 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -174,7 +174,6 @@ pub unsafe fn create_module(
 
         let llvm_data_layout = llvm::LLVMGetDataLayout(llmod);
         let llvm_data_layout = str::from_utf8(CStr::from_ptr(llvm_data_layout).to_bytes())
-            .ok()
             .expect("got a non-UTF8 data-layout from LLVM");
 
         // Unfortunately LLVM target specs change over time, and right now we

From 569676b9b05cd150da3dadcd886cbbf5b40c4fce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= <matthias.krueger@famsik.de>
Date: Wed, 4 Mar 2020 15:13:19 +0100
Subject: [PATCH 13/16] Use .map() to modify data inside Options instead of
 using .and_then(|x| Some(y)) (clippy::option_and_then_some)

---
 src/librustc/traits/structural_impls.rs   |  6 ++---
 src/librustc_parse/parser/attr.rs         |  2 +-
 src/librustc_typeck/check/method/probe.rs | 27 ++++++++++-------------
 src/librustdoc/clean/utils.rs             |  4 +---
 4 files changed, 17 insertions(+), 22 deletions(-)

diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index f9c8b01571e04..63d7124ee91f9 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -415,9 +415,9 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
             super::ReferenceOutlivesReferent(ty) => {
                 tcx.lift(&ty).map(super::ReferenceOutlivesReferent)
             }
-            super::ObjectTypeBound(ty, r) => tcx
-                .lift(&ty)
-                .and_then(|ty| tcx.lift(&r).and_then(|r| Some(super::ObjectTypeBound(ty, r)))),
+            super::ObjectTypeBound(ty, r) => {
+                tcx.lift(&ty).and_then(|ty| tcx.lift(&r).map(|r| super::ObjectTypeBound(ty, r)))
+            }
             super::ObjectCastObligation(ty) => tcx.lift(&ty).map(super::ObjectCastObligation),
             super::Coercion { source, target } => {
                 Some(super::Coercion { source: tcx.lift(&source)?, target: tcx.lift(&target)? })
diff --git a/src/librustc_parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs
index c5f8b2dd862a5..2dccb04f6cce1 100644
--- a/src/librustc_parse/parser/attr.rs
+++ b/src/librustc_parse/parser/attr.rs
@@ -37,7 +37,7 @@ impl<'a> Parser<'a> {
                     let inner_parse_policy = InnerAttributeParsePolicy::NotPermitted {
                         reason: inner_error_reason,
                         saw_doc_comment: just_parsed_doc_comment,
-                        prev_attr_sp: attrs.last().and_then(|a| Some(a.span)),
+                        prev_attr_sp: attrs.last().map(|a| a.span),
                     };
                     let attr = self.parse_attribute_with_inner_parse_policy(inner_parse_policy)?;
                     attrs.push(attr);
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index a52cabd889477..58354c891a2b3 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -1551,21 +1551,18 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
 
             let method_names = pcx.candidate_method_names();
             pcx.allow_similar_names = false;
-            let applicable_close_candidates: Vec<ty::AssocItem> =
-                method_names
-                    .iter()
-                    .filter_map(|&method_name| {
-                        pcx.reset();
-                        pcx.method_name = Some(method_name);
-                        pcx.assemble_inherent_candidates();
-                        pcx.assemble_extension_candidates_for_traits_in_scope(hir::DUMMY_HIR_ID)
-                            .map_or(None, |_| {
-                                pcx.pick_core()
-                                    .and_then(|pick| pick.ok())
-                                    .and_then(|pick| Some(pick.item))
-                            })
-                    })
-                    .collect();
+            let applicable_close_candidates: Vec<ty::AssocItem> = method_names
+                .iter()
+                .filter_map(|&method_name| {
+                    pcx.reset();
+                    pcx.method_name = Some(method_name);
+                    pcx.assemble_inherent_candidates();
+                    pcx.assemble_extension_candidates_for_traits_in_scope(hir::DUMMY_HIR_ID)
+                        .map_or(None, |_| {
+                            pcx.pick_core().and_then(|pick| pick.ok()).map(|pick| pick.item)
+                        })
+                })
+                .collect();
 
             if applicable_close_candidates.is_empty() {
                 Ok(None)
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 99e3d731d0d6f..21e3d24cc968b 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -121,9 +121,7 @@ pub fn external_generic_args(
     let args: Vec<_> = substs
         .iter()
         .filter_map(|kind| match kind.unpack() {
-            GenericArgKind::Lifetime(lt) => {
-                lt.clean(cx).and_then(|lt| Some(GenericArg::Lifetime(lt)))
-            }
+            GenericArgKind::Lifetime(lt) => lt.clean(cx).map(|lt| GenericArg::Lifetime(lt)),
             GenericArgKind::Type(_) if skip_self => {
                 skip_self = false;
                 None

From 38f5db72681289f6ebbcb3c89081f021aa6fdc63 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= <matthias.krueger@famsik.de>
Date: Wed, 4 Mar 2020 15:16:27 +0100
Subject: [PATCH 14/16] Use .as_deref() instead of .as_ref().map(Deref::deref)
 (clippy::option_as_ref_deref)

---
 src/librustdoc/html/markdown.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index ed007fe383c1d..788cc9866155c 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -296,7 +296,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
                         ""
                     }
                 )),
-                playground_button.as_ref().map(String::as_str),
+                playground_button.as_deref(),
                 Some((s1.as_str(), s2)),
             ));
             Some(Event::Html(s.into()))
@@ -315,7 +315,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
                         ""
                     }
                 )),
-                playground_button.as_ref().map(String::as_str),
+                playground_button.as_deref(),
                 None,
             ));
             Some(Event::Html(s.into()))

From d8d2004c6ffb8b66eac90e75aa23012130adf9f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= <matthias.krueger@famsik.de>
Date: Wed, 4 Mar 2020 15:53:14 +0100
Subject: [PATCH 15/16] Don't use "if let" bindings to only check a value and
 not actually bind anything.

For example:  `if let Some(_) = foo() {}`	can be reduced to	`if foo().is_some() {}`   (clippy::redundant_pattern_matching)
---
 src/librustc_codegen_llvm/back/write.rs                | 2 +-
 src/librustc_codegen_ssa/back/write.rs                 | 2 +-
 src/librustc_errors/lib.rs                             | 2 +-
 src/librustc_interface/util.rs                         | 2 +-
 src/librustc_lint/context.rs                           | 2 +-
 src/librustc_mir/borrow_check/type_check/mod.rs        | 2 +-
 src/librustc_mir/borrow_check/type_check/relate_tys.rs | 2 +-
 src/librustc_mir/interpret/memory.rs                   | 2 +-
 src/librustc_passes/entry.rs                           | 2 +-
 9 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index a215ef81bc9eb..0c243128104e7 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -725,7 +725,7 @@ pub(crate) unsafe fn codegen(
                         Err(_) => return 0,
                     };
 
-                    if let Err(_) = write!(cursor, "{:#}", demangled) {
+                    if write!(cursor, "{:#}", demangled).is_err() {
                         // Possible only if provided buffer is not big enough
                         return 0;
                     }
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index 76728e9840616..b313bf57d4a9a 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -1257,7 +1257,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
                 if main_thread_worker_state == MainThreadWorkerState::Idle {
                     if !queue_full_enough(work_items.len(), running, max_workers) {
                         // The queue is not full enough, codegen more items:
-                        if let Err(_) = codegen_worker_send.send(Message::CodegenItem) {
+                        if codegen_worker_send.send(Message::CodegenItem).is_err() {
                             panic!("Could not send Message::CodegenItem to main thread")
                         }
                         main_thread_worker_state = MainThreadWorkerState::Codegenning;
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 5b00087de6fb7..f0e388a597b40 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -163,7 +163,7 @@ impl CodeSuggestion {
                         None => buf.push_str(&line[lo..]),
                     }
                 }
-                if let None = hi_opt {
+                if hi_opt.is_none() {
                     buf.push('\n');
                 }
             }
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index 10a8c0a63f188..7866ddbd4ccd8 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -426,7 +426,7 @@ pub(crate) fn check_attr_crate_type(attrs: &[ast::Attribute], lint_buffer: &mut
     for a in attrs.iter() {
         if a.check_name(sym::crate_type) {
             if let Some(n) = a.value_str() {
-                if let Some(_) = categorize_crate_type(n) {
+                if categorize_crate_type(n).is_some() {
                     return;
                 }
 
diff --git a/src/librustc_lint/context.rs b/src/librustc_lint/context.rs
index 29a6b8c693ff3..a6e8a0ab9301c 100644
--- a/src/librustc_lint/context.rs
+++ b/src/librustc_lint/context.rs
@@ -335,7 +335,7 @@ impl LintStore {
             lint_name.to_string()
         };
         // If the lint was scoped with `tool::` check if the tool lint exists
-        if let Some(_) = tool_name {
+        if tool_name.is_some() {
             match self.by_name.get(&complete_name) {
                 None => match self.lint_groups.get(&*complete_name) {
                     None => return CheckLintNameResult::Tool(Err((None, String::new()))),
diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs
index f4e1bce462f55..652de6c7b6fdf 100644
--- a/src/librustc_mir/borrow_check/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/type_check/mod.rs
@@ -1905,7 +1905,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             // expressions evaluate through `as_temp` or `into` a return
             // slot or local, so to find all unsized rvalues it is enough
             // to check all temps, return slots and locals.
-            if let None = self.reported_errors.replace((ty, span)) {
+            if self.reported_errors.replace((ty, span)).is_none() {
                 let mut diag = struct_span_err!(
                     self.tcx().sess,
                     span,
diff --git a/src/librustc_mir/borrow_check/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/type_check/relate_tys.rs
index 31507a184d8f9..b0f048ff1a6fd 100644
--- a/src/librustc_mir/borrow_check/type_check/relate_tys.rs
+++ b/src/librustc_mir/borrow_check/type_check/relate_tys.rs
@@ -64,7 +64,7 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> {
     }
 
     fn next_existential_region_var(&mut self, from_forall: bool) -> ty::Region<'tcx> {
-        if let Some(_) = &mut self.borrowck_context {
+        if self.borrowck_context.is_some() {
             let origin = NLLRegionVariableOrigin::Existential { from_forall };
             self.infcx.next_nll_region_var(origin)
         } else {
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 6517ae5d0f30f..3c4a1857f9690 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -565,7 +565,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
 
         // # Function pointers
         // (both global from `alloc_map` and local from `extra_fn_ptr_map`)
-        if let Some(_) = self.get_fn_alloc(id) {
+        if self.get_fn_alloc(id).is_some() {
             return if let AllocCheck::Dereferenceable = liveness {
                 // The caller requested no function pointers.
                 throw_unsup!(DerefFunctionPointer)
diff --git a/src/librustc_passes/entry.rs b/src/librustc_passes/entry.rs
index f2239ad16eeb3..86596e205562e 100644
--- a/src/librustc_passes/entry.rs
+++ b/src/librustc_passes/entry.rs
@@ -196,7 +196,7 @@ fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) {
     // The file may be empty, which leads to the diagnostic machinery not emitting this
     // note. This is a relatively simple way to detect that case and emit a span-less
     // note instead.
-    if let Ok(_) = tcx.sess.source_map().lookup_line(sp.lo()) {
+    if tcx.sess.source_map().lookup_line(sp.lo()).is_ok() {
         err.set_span(sp);
         err.span_label(sp, &note);
     } else {

From 80ed505c41319f2fbbc7e97189e62b38c47b5a70 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= <matthias.krueger@famsik.de>
Date: Wed, 4 Mar 2020 20:47:05 +0100
Subject: [PATCH 16/16] Use single-char patter on {ends,starts}_with and remove
 clone on copy type.

These were introduced since I last fixed most of these occurences. (clippy::clone_on_copy, clippy::single_char_pattern)
---
 src/librustc_errors/registry.rs          | 2 +-
 src/librustc_resolve/late/diagnostics.rs | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/librustc_errors/registry.rs b/src/librustc_errors/registry.rs
index c92a9d04775d1..32700c6500bc8 100644
--- a/src/librustc_errors/registry.rs
+++ b/src/librustc_errors/registry.rs
@@ -27,6 +27,6 @@ impl Registry {
         if !self.long_descriptions.contains_key(code) {
             return Err(InvalidErrorCode);
         }
-        Ok(self.long_descriptions.get(code).unwrap().clone())
+        Ok(*self.long_descriptions.get(code).unwrap())
     }
 }
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index 817a276ff3e73..fd62c80293425 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -1086,7 +1086,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
                     for param in params {
                         if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(param.span)
                         {
-                            if snippet.starts_with("&") && !snippet.starts_with("&'") {
+                            if snippet.starts_with('&') && !snippet.starts_with("&'") {
                                 introduce_suggestion
                                     .push((param.span, format!("&'a {}", &snippet[1..])));
                             } else if snippet.starts_with("&'_ ") {
@@ -1118,7 +1118,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
                 (1, Some(name), Some("'_")) => {
                     suggest_existing(err, name.to_string());
                 }
-                (1, Some(name), Some(snippet)) if !snippet.ends_with(">") => {
+                (1, Some(name), Some(snippet)) if !snippet.ends_with('>') => {
                     suggest_existing(err, format!("{}<{}>", snippet, name));
                 }
                 (0, _, Some("&")) => {
@@ -1127,7 +1127,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
                 (0, _, Some("'_")) => {
                     suggest_new(err, "'a");
                 }
-                (0, _, Some(snippet)) if !snippet.ends_with(">") => {
+                (0, _, Some(snippet)) if !snippet.ends_with('>') => {
                     suggest_new(err, &format!("{}<'a>", snippet));
                 }
                 _ => {