about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-12-17 03:07:09 +0000
committerbors <bors@rust-lang.org>2020-12-17 03:07:09 +0000
commit9b84d36a0b9ea3bf305f36f08d50aa42c26f96c2 (patch)
tree4f575236b223ed95924eba195fe6f6f6536630b1
parenta6491be5be9344a325b7e49b0114f3cf67ef199e (diff)
parente2582e4b778e542836232f70c9bb5dfe77a3f186 (diff)
downloadrust-9b84d36a0b9ea3bf305f36f08d50aa42c26f96c2.tar.gz
rust-9b84d36a0b9ea3bf305f36f08d50aa42c26f96c2.zip
Auto merge of #80105 - JohnTitor:rollup-8c030u5, r=JohnTitor
Rollup of 11 pull requests

Successful merges:

 - #79051 (Implement if-let match guards)
 - #79877 (Allow `since="TBD"` for rustc_deprecated)
 - #79882 (Fix issue #78496)
 - #80026 (expand-yaml-anchors: Make the output directory separator-insensitive)
 - #80039 (Remove unused `TyEncoder::tcx` required method)
 - #80069 (Test that `core::assert!` is valid)
 - #80072 (Fixed conflict with drop elaboration and coverage)
 - #80073 (Add support for target aliases)
 - #80082 (Revert #78790 - rust-src vendoring)
 - #80097 (Add `popcount` and `popcnt` as doc aliases for `count_ones` methods.)
 - #80103 (Remove docs for non-existent parameters in `rustc_expand`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs15
-rw-r--r--compiler/rustc_expand/src/mbe/macro_parser.rs5
-rw-r--r--compiler/rustc_hir/src/hir.rs5
-rw-r--r--compiler/rustc_hir/src/intravisit.rs4
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs9
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs4
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs75
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs1
-rw-r--r--compiler/rustc_middle/src/ty/query/on_disk_cache.rs3
-rw-r--r--compiler/rustc_mir/src/transform/coverage/mod.rs4
-rw-r--r--compiler/rustc_mir/src/transform/early_otherwise_branch.rs27
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs54
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs8
-rw-r--r--compiler/rustc_mir_build/src/thir/mod.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs31
-rw-r--r--compiler/rustc_passes/src/check_const.rs2
-rw-r--r--compiler/rustc_passes/src/liveness.rs14
-rw-r--r--compiler/rustc_passes/src/stability.rs44
-rw-r--r--compiler/rustc_session/src/config.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs18
-rw-r--r--compiler/rustc_typeck/src/check/_match.rs32
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior.rs4
-rw-r--r--library/core/src/num/int_macros.rs2
-rw-r--r--library/core/src/num/uint_macros.rs2
-rw-r--r--library/core/src/num/wrapping.rs2
-rw-r--r--src/bootstrap/dist.rs26
-rw-r--r--src/bootstrap/lib.rs21
-rw-r--r--src/librustdoc/html/render/mod.rs6
-rw-r--r--src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot2
-rw-r--r--src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot2
-rw-r--r--src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff2
-rw-r--r--src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff8
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json20
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json20
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json20
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt8
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt10
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt8
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt16
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt16
-rw-r--r--src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt16
-rw-r--r--src/test/rustdoc/rustc_deprecated-future.rs12
-rw-r--r--src/test/ui/deprecation/rustc_deprecation-in-future.rs9
-rw-r--r--src/test/ui/deprecation/rustc_deprecation-in-future.stderr16
-rw-r--r--src/test/ui/generator/yielding-in-match-guards.rs11
-rw-r--r--src/test/ui/mir/issue-78496.rs16
-rw-r--r--src/test/ui/no-std-macros.rs13
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/bindings.rs10
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/bindings.stderr15
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/feature-gate.rs1
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr79
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/run-pass.rs34
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/typeck.rs16
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/typeck.stderr21
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/warns.rs22
-rw-r--r--src/test/ui/rfc-2294-if-let-guard/warns.stderr26
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-sanity.rs6
-rw-r--r--src/test/ui/stability-attribute/stability-attribute-sanity.stderr12
-rw-r--r--src/tools/clippy/clippy_lints/src/shadow.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/hir_utils.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/inspector.rs5
-rw-r--r--src/tools/expand-yaml-anchors/src/main.rs3
64 files changed, 633 insertions, 285 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 6ad6e664316..9b1642df114 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -505,14 +505,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
     }
 
     fn lower_arm(&mut self, arm: &Arm) -> hir::Arm<'hir> {
+        let pat = self.lower_pat(&arm.pat);
+        let guard = arm.guard.as_ref().map(|cond| {
+            if let ExprKind::Let(ref pat, ref scrutinee) = cond.kind {
+                hir::Guard::IfLet(self.lower_pat(pat), self.lower_expr(scrutinee))
+            } else {
+                hir::Guard::If(self.lower_expr(cond))
+            }
+        });
         hir::Arm {
             hir_id: self.next_id(),
             attrs: self.lower_attrs(&arm.attrs),
-            pat: self.lower_pat(&arm.pat),
-            guard: match arm.guard {
-                Some(ref x) => Some(hir::Guard::If(self.lower_expr(x))),
-                _ => None,
-            },
+            pat,
+            guard,
             body: self.lower_expr(&arm.body),
             span: arm.span,
         }
diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index 92a8f231126..c37f9125675 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -1,4 +1,4 @@
-//! This is an NFA-based parser, which calls out to the main rust parser for named non-terminals
+//! This is an NFA-based parser, which calls out to the main Rust parser for named non-terminals
 //! (which it commits to fully when it hits one in a grammar). There's a set of current NFA threads
 //! and a set of next ones. Instead of NTs, we have a special case for Kleene star. The big-O, in
 //! pathological cases, is worse than traditional use of NFA or Earley parsing, but it's an easier
@@ -422,7 +422,6 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool {
 ///
 /// # Parameters
 ///
-/// - `sess`: the parsing session into which errors are emitted.
 /// - `cur_items`: the set of current items to be processed. This should be empty by the end of a
 ///   successful execution of this function.
 /// - `next_items`: the set of newly generated items. These are used to replenish `cur_items` in
@@ -430,8 +429,6 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool {
 /// - `eof_items`: the set of items that would be valid if this was the EOF.
 /// - `bb_items`: the set of items that are waiting for the black-box parser.
 /// - `token`: the current token of the parser.
-/// - `span`: the `Span` in the source code corresponding to the token trees we are trying to match
-///   against the matcher positions in `cur_items`.
 ///
 /// # Returns
 ///
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 280e863d474..2abebbd0303 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1160,6 +1160,7 @@ pub struct Arm<'hir> {
 #[derive(Debug, HashStable_Generic)]
 pub enum Guard<'hir> {
     If(&'hir Expr<'hir>),
+    IfLet(&'hir Pat<'hir>, &'hir Expr<'hir>),
 }
 
 #[derive(Debug, HashStable_Generic)]
@@ -1721,6 +1722,8 @@ pub enum MatchSource {
     IfDesugar { contains_else_clause: bool },
     /// An `if let _ = _ { .. }` (optionally with `else { .. }`).
     IfLetDesugar { contains_else_clause: bool },
+    /// An `if let _ = _ => { .. }` match guard.
+    IfLetGuardDesugar,
     /// A `while _ { .. }` (which was desugared to a `loop { match _ { .. } }`).
     WhileDesugar,
     /// A `while let _ = _ { .. }` (which was desugared to a
@@ -1739,7 +1742,7 @@ impl MatchSource {
         use MatchSource::*;
         match self {
             Normal => "match",
-            IfDesugar { .. } | IfLetDesugar { .. } => "if",
+            IfDesugar { .. } | IfLetDesugar { .. } | IfLetGuardDesugar => "if",
             WhileDesugar | WhileLetDesugar => "while",
             ForLoopDesugar => "for",
             TryDesugar => "?",
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 3c330c5d6c5..03c8b173885 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -1228,6 +1228,10 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) {
     if let Some(ref g) = arm.guard {
         match g {
             Guard::If(ref e) => visitor.visit_expr(e),
+            Guard::IfLet(ref pat, ref e) => {
+                visitor.visit_pat(pat);
+                visitor.visit_expr(e);
+            }
         }
     }
     visitor.visit_expr(&arm.body);
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 597c55b4bd7..0b5eb1d8266 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -2002,6 +2002,15 @@ impl<'a> State<'a> {
                     self.print_expr(&e);
                     self.s.space();
                 }
+                hir::Guard::IfLet(pat, e) => {
+                    self.word_nbsp("if");
+                    self.word_nbsp("let");
+                    self.print_pat(&pat);
+                    self.s.space();
+                    self.word_space("=");
+                    self.print_expr(&e);
+                    self.s.space();
+                }
             }
         }
         self.word_space("=>");
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 7b67d15f64a..4dfe3e84877 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -319,10 +319,6 @@ impl<'a, 'tcx> TyEncoder<'tcx> for EncodeContext<'a, 'tcx> {
         self.opaque.position()
     }
 
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-
     fn type_shorthands(&mut self) -> &mut FxHashMap<Ty<'tcx>, usize> {
         &mut self.type_shorthands
     }
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 47c140e0b18..4f08057a7e3 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -132,37 +132,37 @@ pub fn report_unstable(
 /// Checks whether an item marked with `deprecated(since="X")` is currently
 /// deprecated (i.e., whether X is not greater than the current rustc version).
 pub fn deprecation_in_effect(is_since_rustc_version: bool, since: Option<&str>) -> bool {
-    let since = if let Some(since) = since {
-        if is_since_rustc_version {
-            since
-        } else {
-            // We assume that the deprecation is in effect if it's not a
-            // rustc version.
-            return true;
-        }
-    } else {
-        // If since attribute is not set, then we're definitely in effect.
-        return true;
-    };
     fn parse_version(ver: &str) -> Vec<u32> {
         // We ignore non-integer components of the version (e.g., "nightly").
         ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect()
     }
 
-    if let Some(rustc) = option_env!("CFG_RELEASE") {
-        let since: Vec<u32> = parse_version(&since);
-        let rustc: Vec<u32> = parse_version(rustc);
-        // We simply treat invalid `since` attributes as relating to a previous
-        // Rust version, thus always displaying the warning.
-        if since.len() != 3 {
-            return true;
-        }
-        since <= rustc
-    } else {
-        // By default, a deprecation warning applies to
-        // the current version of the compiler.
-        true
+    if !is_since_rustc_version {
+        // The `since` field doesn't have semantic purpose in the stable `deprecated`
+        // attribute, only in `rustc_deprecated`.
+        return true;
     }
+
+    if let Some(since) = since {
+        if since == "TBD" {
+            return false;
+        }
+
+        if let Some(rustc) = option_env!("CFG_RELEASE") {
+            let since: Vec<u32> = parse_version(&since);
+            let rustc: Vec<u32> = parse_version(rustc);
+            // We simply treat invalid `since` attributes as relating to a previous
+            // Rust version, thus always displaying the warning.
+            if since.len() != 3 {
+                return true;
+            }
+            return since <= rustc;
+        }
+    };
+
+    // Assume deprecation is in effect if "since" field is missing
+    // or if we can't determine the current Rust version.
+    true
 }
 
 pub fn deprecation_suggestion(
@@ -182,19 +182,24 @@ pub fn deprecation_suggestion(
 }
 
 pub fn deprecation_message(depr: &Deprecation, kind: &str, path: &str) -> (String, &'static Lint) {
-    let (message, lint) = if deprecation_in_effect(
-        depr.is_since_rustc_version,
-        depr.since.map(Symbol::as_str).as_deref(),
-    ) {
+    let since = depr.since.map(Symbol::as_str);
+    let (message, lint) = if deprecation_in_effect(depr.is_since_rustc_version, since.as_deref()) {
         (format!("use of deprecated {} `{}`", kind, path), DEPRECATED)
     } else {
         (
-            format!(
-                "use of {} `{}` that will be deprecated in future version {}",
-                kind,
-                path,
-                depr.since.unwrap()
-            ),
+            if since.as_deref() == Some("TBD") {
+                format!(
+                    "use of {} `{}` that will be deprecated in a future Rust version",
+                    kind, path
+                )
+            } else {
+                format!(
+                    "use of {} `{}` that will be deprecated in future version {}",
+                    kind,
+                    path,
+                    since.unwrap()
+                )
+            },
             DEPRECATED_IN_FUTURE,
         )
     };
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index b2fc3710cd6..1983af17dd0 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -69,7 +69,6 @@ impl OpaqueEncoder for rustc_serialize::opaque::Encoder {
 pub trait TyEncoder<'tcx>: Encoder {
     const CLEAR_CROSS_CRATE: bool;
 
-    fn tcx(&self) -> TyCtxt<'tcx>;
     fn position(&self) -> usize;
     fn type_shorthands(&mut self) -> &mut FxHashMap<Ty<'tcx>, usize>;
     fn predicate_shorthands(&mut self) -> &mut FxHashMap<ty::Predicate<'tcx>, usize>;
diff --git a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
index 3eed94b1ffb..e006dfeb663 100644
--- a/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/ty/query/on_disk_cache.rs
@@ -1044,9 +1044,6 @@ where
 {
     const CLEAR_CROSS_CRATE: bool = false;
 
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
     fn position(&self) -> usize {
         self.encoder.encoder_position()
     }
diff --git a/compiler/rustc_mir/src/transform/coverage/mod.rs b/compiler/rustc_mir/src/transform/coverage/mod.rs
index 53f7c28ee35..4590d37c182 100644
--- a/compiler/rustc_mir/src/transform/coverage/mod.rs
+++ b/compiler/rustc_mir/src/transform/coverage/mod.rs
@@ -310,7 +310,7 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
             inject_statement(
                 self.mir_body,
                 counter_kind,
-                self.bcb_last_bb(bcb),
+                self.bcb_leader_bb(bcb),
                 Some(make_code_region(file_name, &self.source_file, span, body_span)),
             );
         }
@@ -470,7 +470,7 @@ fn inject_statement(
             code_region: some_code_region,
         }),
     };
-    data.statements.push(statement);
+    data.statements.insert(0, statement);
 }
 
 // Non-code expressions are injected into the coverage map, without generating executable code.
diff --git a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs
index 6fbcc140978..b16a99d7f0d 100644
--- a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs
+++ b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs
@@ -284,6 +284,33 @@ impl<'a, 'tcx> Helper<'a, 'tcx> {
                 return None;
             }
 
+            // when the second place is a projection of the first one, it's not safe to calculate their discriminant values sequentially.
+            // for example, this should not be optimized:
+            //
+            // ```rust
+            // enum E<'a> { Empty, Some(&'a E<'a>), }
+            // let Some(Some(_)) = e;
+            // ```
+            //
+            // ```mir
+            // bb0: {
+            //   _2 = discriminant(*_1)
+            //   switchInt(_2) -> [...]
+            // }
+            // bb1: {
+            //   _3 = discriminant(*(((*_1) as Some).0: &E))
+            //   switchInt(_3) -> [...]
+            // }
+            // ```
+            let discr_place = discr_info.place_of_adt_discr_read;
+            let this_discr_place = this_bb_discr_info.place_of_adt_discr_read;
+            if discr_place.local == this_discr_place.local
+                && this_discr_place.projection.starts_with(discr_place.projection)
+            {
+                trace!("NO: one target is the projection of another");
+                return None;
+            }
+
             // if we reach this point, the optimization applies, and we should be able to optimize this case
             // store the info that is needed to apply the optimization
 
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 6d166bf37f9..2e108d48093 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -228,6 +228,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         guard: Option<&Guard<'tcx>>,
         fake_borrow_temps: &Vec<(Place<'tcx>, Local)>,
         scrutinee_span: Span,
+        arm_span: Option<Span>,
         arm_scope: Option<region::Scope>,
     ) -> BasicBlock {
         if candidate.subcandidates.is_empty() {
@@ -239,6 +240,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 guard,
                 fake_borrow_temps,
                 scrutinee_span,
+                arm_span,
                 true,
             )
         } else {
@@ -274,6 +276,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         guard,
                         &fake_borrow_temps,
                         scrutinee_span,
+                        arm_span,
                         schedule_drops,
                     );
                     if arm_scope.is_none() {
@@ -436,6 +439,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             &fake_borrow_temps,
             irrefutable_pat.span,
             None,
+            None,
         )
         .unit()
     }
@@ -817,11 +821,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// For an example of a case where we set `otherwise_block`, even for an
     /// exhaustive match consider:
     ///
+    /// ```rust
     /// match x {
     ///     (true, true) => (),
     ///     (_, false) => (),
     ///     (false, true) => (),
     /// }
+    /// ```
     ///
     /// For this match, we check if `x.0` matches `true` (for the first
     /// arm). If that's false, we check `x.1`. If it's `true` we check if
@@ -935,11 +941,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Link up matched candidates. For example, if we have something like
     /// this:
     ///
+    /// ```rust
     /// ...
     /// Some(x) if cond => ...
     /// Some(x) => ...
     /// Some(x) if cond => ...
     /// ...
+    /// ```
     ///
     /// We generate real edges from:
     /// * `start_block` to the `prebinding_block` of the first pattern,
@@ -1517,7 +1525,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Initializes each of the bindings from the candidate by
     /// moving/copying/ref'ing the source as appropriate. Tests the guard, if
     /// any, and then branches to the arm. Returns the block for the case where
-    /// the guard fails.
+    /// the guard succeeds.
     ///
     /// Note: we do not check earlier that if there is a guard,
     /// there cannot be move bindings. We avoid a use-after-move by only
@@ -1529,6 +1537,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         guard: Option<&Guard<'tcx>>,
         fake_borrows: &Vec<(Place<'tcx>, Local)>,
         scrutinee_span: Span,
+        arm_span: Option<Span>,
         schedule_drops: bool,
     ) -> BasicBlock {
         debug!("bind_and_guard_matched_candidate(candidate={:?})", candidate);
@@ -1659,15 +1668,42 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 self.cfg.push_assign(block, scrutinee_source_info, Place::from(temp), borrow);
             }
 
-            // the block to branch to if the guard fails; if there is no
-            // guard, this block is simply unreachable
-            let guard = match guard {
-                Guard::If(e) => self.hir.mirror(e.clone()),
+            let (guard_span, (post_guard_block, otherwise_post_guard_block)) = match guard {
+                Guard::If(e) => {
+                    let e = self.hir.mirror(e.clone());
+                    let source_info = self.source_info(e.span);
+                    (e.span, self.test_bool(block, e, source_info))
+                },
+                Guard::IfLet(pat, scrutinee) => {
+                    let scrutinee_span = scrutinee.span();
+                    let scrutinee_place = unpack!(block = self.lower_scrutinee(block, scrutinee.clone(), scrutinee_span));
+                    let mut guard_candidate = Candidate::new(scrutinee_place, &pat, false);
+                    let wildcard = Pat::wildcard_from_ty(pat.ty);
+                    let mut otherwise_candidate = Candidate::new(scrutinee_place, &wildcard, false);
+                    let fake_borrow_temps =
+                        self.lower_match_tree(block, pat.span, false, &mut [&mut guard_candidate, &mut otherwise_candidate]);
+                    self.declare_bindings(
+                        None,
+                        pat.span.to(arm_span.unwrap()),
+                        pat,
+                        ArmHasGuard(false),
+                        Some((Some(&scrutinee_place), scrutinee.span())),
+                    );
+                    let post_guard_block = self.bind_pattern(
+                        self.source_info(pat.span),
+                        guard_candidate,
+                        None,
+                        &fake_borrow_temps,
+                        scrutinee.span(),
+                        None,
+                        None,
+                    );
+                    let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap();
+                    (scrutinee_span, (post_guard_block, otherwise_post_guard_block))
+                }
             };
-            let source_info = self.source_info(guard.span);
-            let guard_end = self.source_info(tcx.sess.source_map().end_point(guard.span));
-            let (post_guard_block, otherwise_post_guard_block) =
-                self.test_bool(block, guard, source_info);
+            let source_info = self.source_info(guard_span);
+            let guard_end = self.source_info(tcx.sess.source_map().end_point(guard_span));
             let guard_frame = self.guard_context.pop().unwrap();
             debug!("Exiting guard building context with locals: {:?}", guard_frame);
 
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index 0edd44d4bf1..62d2212d109 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -1197,6 +1197,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         arm.guard.as_ref(),
                         &fake_borrow_temps,
                         scrutinee_span,
+                        Some(arm.span),
                         Some(arm.scope),
                     );
 
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index fbdadc67b43..417f9bded09 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -776,10 +776,10 @@ impl ToBorrowKind for hir::Mutability {
 fn convert_arm<'tcx>(cx: &mut Cx<'_, 'tcx>, arm: &'tcx hir::Arm<'tcx>) -> Arm<'tcx> {
     Arm {
         pattern: cx.pattern_from_hir(&arm.pat),
-        guard: match arm.guard {
-            Some(hir::Guard::If(ref e)) => Some(Guard::If(e.to_ref())),
-            _ => None,
-        },
+        guard: arm.guard.as_ref().map(|g| match g {
+            hir::Guard::If(ref e) => Guard::If(e.to_ref()),
+            hir::Guard::IfLet(ref pat, ref e) => Guard::IfLet(cx.pattern_from_hir(pat), e.to_ref()),
+        }),
         body: arm.body.to_ref(),
         lint_level: LintLevel::Explicit(arm.hir_id),
         scope: region::Scope { id: arm.hir_id.local_id, data: region::ScopeData::Node },
diff --git a/compiler/rustc_mir_build/src/thir/mod.rs b/compiler/rustc_mir_build/src/thir/mod.rs
index 1a901746d50..ace9cad4d29 100644
--- a/compiler/rustc_mir_build/src/thir/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/mod.rs
@@ -344,6 +344,7 @@ crate struct Arm<'tcx> {
 #[derive(Clone, Debug)]
 crate enum Guard<'tcx> {
     If(ExprRef<'tcx>),
+    IfLet(Pat<'tcx>, ExprRef<'tcx>),
 }
 
 #[derive(Copy, Clone, Debug)]
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index 97edbd83b89..29b7e176b0e 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -164,10 +164,20 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
         for arm in arms {
             // Check the arm for some things unrelated to exhaustiveness.
             self.check_patterns(&arm.pat);
+            if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard {
+                self.check_patterns(pat);
+            }
         }
 
         let mut cx = self.new_cx(scrut.hir_id);
 
+        for arm in arms {
+            if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard {
+                let tpat = self.lower_pattern(&mut cx, pat, &mut false).0;
+                check_if_let_guard(&mut cx, &tpat, pat.hir_id);
+            }
+        }
+
         let mut have_errors = false;
 
         let arms: Vec<_> = arms
@@ -360,12 +370,28 @@ fn irrefutable_let_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, source: hir::
         let msg = match source {
             hir::MatchSource::IfLetDesugar { .. } => "irrefutable if-let pattern",
             hir::MatchSource::WhileLetDesugar => "irrefutable while-let pattern",
+            hir::MatchSource::IfLetGuardDesugar => "irrefutable if-let guard",
             _ => bug!(),
         };
         lint.build(msg).emit()
     });
 }
 
+fn check_if_let_guard<'p, 'tcx>(
+    cx: &mut MatchCheckCtxt<'p, 'tcx>,
+    pat: &'p super::Pat<'tcx>,
+    pat_id: HirId,
+) {
+    let arms = [MatchArm { pat, hir_id: pat_id, has_guard: false }];
+    let report = compute_match_usefulness(&cx, &arms, pat_id, pat.ty);
+    report_arm_reachability(&cx, &report, hir::MatchSource::IfLetGuardDesugar);
+
+    if report.non_exhaustiveness_witnesses.is_empty() {
+        // The match is exhaustive, i.e. the if let pattern is irrefutable.
+        irrefutable_let_pattern(cx.tcx, pat.span, pat_id, hir::MatchSource::IfLetGuardDesugar)
+    }
+}
+
 /// Report unreachable arms, if any.
 fn report_arm_reachability<'p, 'tcx>(
     cx: &MatchCheckCtxt<'p, 'tcx>,
@@ -390,6 +416,11 @@ fn report_arm_reachability<'p, 'tcx>(
                         }
                     }
 
+                    hir::MatchSource::IfLetGuardDesugar => {
+                        assert_eq!(arm_index, 0);
+                        unreachable_pattern(cx.tcx, arm.pat.span, arm.hir_id, None);
+                    }
+
                     hir::MatchSource::ForLoopDesugar | hir::MatchSource::Normal => {
                         unreachable_pattern(cx.tcx, arm.pat.span, arm.hir_id, catchall);
                     }
diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs
index e37c6418eb8..2d6bbff460d 100644
--- a/compiler/rustc_passes/src/check_const.rs
+++ b/compiler/rustc_passes/src/check_const.rs
@@ -45,6 +45,8 @@ impl NonConstExpr {
                 return None;
             }
 
+            Self::Match(IfLetGuardDesugar) => bug!("if-let guard outside a `match` expression"),
+
             // All other expressions are allowed.
             Self::Loop(Loop | While | WhileLet)
             | Self::Match(
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index a161ad16b8c..86ce35c6d99 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -360,6 +360,9 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
 
     fn visit_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) {
         self.add_from_pat(&arm.pat);
+        if let Some(hir::Guard::IfLet(ref pat, _)) = arm.guard {
+            self.add_from_pat(pat);
+        }
         intravisit::walk_arm(self, arm);
     }
 
@@ -866,10 +869,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                 for arm in arms {
                     let body_succ = self.propagate_through_expr(&arm.body, succ);
 
-                    let guard_succ = self.propagate_through_opt_expr(
-                        arm.guard.as_ref().map(|hir::Guard::If(e)| *e),
-                        body_succ,
-                    );
+                    let guard_succ = arm.guard.as_ref().map_or(body_succ, |g| match g {
+                        hir::Guard::If(e) => self.propagate_through_expr(e, body_succ),
+                        hir::Guard::IfLet(pat, e) => {
+                            let let_bind = self.define_bindings_in_pat(pat, body_succ);
+                            self.propagate_through_expr(e, let_bind)
+                        }
+                    });
                     let arm_succ = self.define_bindings_in_pat(&arm.pat, guard_succ);
                     self.merge_from_succ(ln, arm_succ);
                 }
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index f6bbbd80bf1..3c2462aab26 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -182,28 +182,32 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
                 for (dep_v, stab_v) in
                     dep_since.as_str().split('.').zip(stab_since.as_str().split('.'))
                 {
-                    if let (Ok(dep_v), Ok(stab_v)) = (dep_v.parse::<u64>(), stab_v.parse()) {
-                        match dep_v.cmp(&stab_v) {
-                            Ordering::Less => {
-                                self.tcx.sess.span_err(
-                                    item_sp,
-                                    "An API can't be stabilized \
-                                                                 after it is deprecated",
-                                );
+                    match stab_v.parse::<u64>() {
+                        Err(_) => {
+                            self.tcx.sess.span_err(item_sp, "Invalid stability version found");
+                            break;
+                        }
+                        Ok(stab_vp) => match dep_v.parse::<u64>() {
+                            Ok(dep_vp) => match dep_vp.cmp(&stab_vp) {
+                                Ordering::Less => {
+                                    self.tcx.sess.span_err(
+                                        item_sp,
+                                        "An API can't be stabilized after it is deprecated",
+                                    );
+                                    break;
+                                }
+                                Ordering::Equal => continue,
+                                Ordering::Greater => break,
+                            },
+                            Err(_) => {
+                                if dep_v != "TBD" {
+                                    self.tcx
+                                        .sess
+                                        .span_err(item_sp, "Invalid deprecation version found");
+                                }
                                 break;
                             }
-                            Ordering::Equal => continue,
-                            Ordering::Greater => break,
-                        }
-                    } else {
-                        // Act like it isn't less because the question is now nonsensical,
-                        // and this makes us not do anything else interesting.
-                        self.tcx.sess.span_err(
-                            item_sp,
-                            "Invalid stability or deprecation \
-                                                         version found",
-                        );
-                        break;
+                        },
                     }
                 }
             }
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index c20b11656b2..c9ddcbdb5f5 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -1491,7 +1491,7 @@ fn parse_target_triple(matches: &getopts::Matches, error_format: ErrorOutputType
                 early_error(error_format, &format!("target file {:?} does not exist", path))
             })
         }
-        Some(target) => TargetTriple::TargetTriple(target),
+        Some(target) => TargetTriple::from_alias(target),
         _ => TargetTriple::from_triple(host_triple()),
     }
 }
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 8d749493d0a..8d72df6850f 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1800,6 +1800,24 @@ impl TargetTriple {
         Ok(TargetTriple::TargetPath(canonicalized_path))
     }
 
+    /// Creates a target triple from its alias
+    pub fn from_alias(triple: String) -> Self {
+        macro_rules! target_aliases {
+            ( $(($alias:literal, $target:literal ),)+ ) => {
+                match triple.as_str() {
+                    $( $alias => TargetTriple::from_triple($target), )+
+                    _ => TargetTriple::TargetTriple(triple),
+                }
+            }
+        }
+
+        target_aliases! {
+            // `x86_64-pc-solaris` is an alias for `x86_64_sun_solaris` for backwards compatibility reasons.
+            // (See <https://github.com/rust-lang/rust/issues/40531>.)
+            ("x86_64-pc-solaris", "x86_64-sun-solaris"),
+        }
+    }
+
     /// Returns a string triple for this target.
     ///
     /// If this target is a path, the file name (without extension) is returned.
diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs
index 3a5eeb5381b..3106f19cf86 100644
--- a/compiler/rustc_typeck/src/check/_match.rs
+++ b/compiler/rustc_typeck/src/check/_match.rs
@@ -43,7 +43,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // FIXME(60707): Consider removing hack with principled solution.
             self.check_expr_has_type_or_error(scrut, self.tcx.types.bool, |_| {})
         } else {
-            self.demand_scrutinee_type(arms, scrut)
+            self.demand_scrutinee_type(scrut, arms_contain_ref_bindings(arms), arms.is_empty())
         };
 
         // If there are no arms, that is a diverging match; a special case.
@@ -98,7 +98,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.diverges.set(Diverges::Maybe);
                 match g {
                     hir::Guard::If(e) => {
-                        self.check_expr_has_type_or_error(e, tcx.types.bool, |_| {})
+                        self.check_expr_has_type_or_error(e, tcx.types.bool, |_| {});
+                    }
+                    hir::Guard::IfLet(pat, e) => {
+                        let scrutinee_ty = self.demand_scrutinee_type(
+                            e,
+                            pat.contains_explicit_ref_binding(),
+                            false,
+                        );
+                        self.check_pat_top(&pat, scrutinee_ty, None, true);
                     }
                 };
             }
@@ -450,8 +458,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn demand_scrutinee_type(
         &self,
-        arms: &'tcx [hir::Arm<'tcx>],
         scrut: &'tcx hir::Expr<'tcx>,
+        contains_ref_bindings: Option<hir::Mutability>,
+        no_arms: bool,
     ) -> Ty<'tcx> {
         // Not entirely obvious: if matches may create ref bindings, we want to
         // use the *precise* type of the scrutinee, *not* some supertype, as
@@ -505,17 +514,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // (once introduced) is populated by the time we get here.
         //
         // See #44848.
-        let contains_ref_bindings = arms
-            .iter()
-            .filter_map(|a| a.pat.contains_explicit_ref_binding())
-            .max_by_key(|m| match *m {
-                hir::Mutability::Mut => 1,
-                hir::Mutability::Not => 0,
-            });
-
         if let Some(m) = contains_ref_bindings {
             self.check_expr_with_needs(scrut, Needs::maybe_mut_place(m))
-        } else if arms.is_empty() {
+        } else if no_arms {
             self.check_expr(scrut)
         } else {
             // ...but otherwise we want to use any supertype of the
@@ -546,3 +547,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 }
+
+fn arms_contain_ref_bindings(arms: &'tcx [hir::Arm<'tcx>]) -> Option<hir::Mutability> {
+    arms.iter().filter_map(|a| a.pat.contains_explicit_ref_binding()).max_by_key(|m| match *m {
+        hir::Mutability::Mut => 1,
+        hir::Mutability::Not => 0,
+    })
+}
diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs
index 602b79802b3..5bc40d617d0 100644
--- a/compiler/rustc_typeck/src/check/generator_interior.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior.rs
@@ -246,6 +246,10 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
                 Guard::If(ref e) => {
                     self.visit_expr(e);
                 }
+                Guard::IfLet(ref pat, ref e) => {
+                    self.visit_pat(pat);
+                    self.visit_expr(e);
+                }
             }
 
             let mut scope_var_ids =
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 4fa48427ec6..2cde5d9995b 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -92,6 +92,8 @@ $EndFeature, "
 "),
             #[stable(feature = "rust1", since = "1.0.0")]
             #[rustc_const_stable(feature = "const_int_methods", since = "1.32.0")]
+            #[doc(alias = "popcount")]
+            #[doc(alias = "popcnt")]
             #[inline]
             pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
         }
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 390c1b7e9e8..ae8fc18a838 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -90,6 +90,8 @@ assert_eq!(n.count_ones(), 3);", $EndFeature, "
 ```"),
             #[stable(feature = "rust1", since = "1.0.0")]
             #[rustc_const_stable(feature = "const_math", since = "1.32.0")]
+            #[doc(alias = "popcount")]
+            #[doc(alias = "popcnt")]
             #[inline]
             pub const fn count_ones(self) -> u32 {
                 intrinsics::ctpop(self as $ActualT) as u32
diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs
index 5324dfdeddd..77c9a93008c 100644
--- a/library/core/src/num/wrapping.rs
+++ b/library/core/src/num/wrapping.rs
@@ -453,6 +453,8 @@ let n = Wrapping(0b01001100", stringify!($t), ");
 assert_eq!(n.count_ones(), 3);
 ```"),
                 #[inline]
+                #[doc(alias = "popcount")]
+                #[doc(alias = "popcnt")]
                 #[unstable(feature = "wrapping_int_impl", issue = "32463")]
                 pub const fn count_ones(self) -> u32 {
                     self.0.count_ones()
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index b1bb97cf83b..8ccb9dbdf01 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -1043,30 +1043,6 @@ impl Step for Src {
             builder.copy(&builder.src.join(file), &dst_src.join(file));
         }
 
-        // libtest includes std and everything else, so vendoring it
-        // creates exactly what's needed for `cargo -Zbuild-std` or any
-        // other analysis of the stdlib's source. Cargo also needs help
-        // finding the lock, so we copy it to libtest temporarily.
-        //
-        // Note that this requires std to only have one version of each
-        // crate. e.g. two versions of getopts won't be patchable.
-        let dst_libtest = dst_src.join("library/test");
-        let dst_vendor = dst_src.join("vendor");
-        let root_lock = dst_src.join("Cargo.lock");
-        let temp_lock = dst_libtest.join("Cargo.lock");
-
-        // `cargo vendor` will delete everything from the lockfile that
-        // isn't used by libtest, so we need to not use any links!
-        builder.really_copy(&root_lock, &temp_lock);
-
-        let mut cmd = Command::new(&builder.initial_cargo);
-        cmd.arg("vendor").arg(dst_vendor).current_dir(&dst_libtest);
-        builder.info("Dist src");
-        let _time = timeit(builder);
-        builder.run(&mut cmd);
-
-        builder.remove(&temp_lock);
-
         // Create source tarball in rust-installer format
         let mut cmd = rust_installer(builder);
         cmd.arg("generate")
@@ -1083,6 +1059,8 @@ impl Step for Src {
             .arg("--component-name=rust-src")
             .arg("--legacy-manifest-dirs=rustlib,cargo");
 
+        builder.info("Dist src");
+        let _time = timeit(builder);
         builder.run(&mut cmd);
 
         builder.remove_dir(&image);
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 06ccd72186d..ece9bdc7a64 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -1182,27 +1182,6 @@ impl Build {
         paths
     }
 
-    /// Copies a file from `src` to `dst` and doesn't use links, so
-    /// that the copy can be modified without affecting the original.
-    pub fn really_copy(&self, src: &Path, dst: &Path) {
-        if self.config.dry_run {
-            return;
-        }
-        self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst));
-        if src == dst {
-            return;
-        }
-        let _ = fs::remove_file(&dst);
-        let metadata = t!(src.symlink_metadata());
-        if let Err(e) = fs::copy(src, dst) {
-            panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e)
-        }
-        t!(fs::set_permissions(dst, metadata.permissions()));
-        let atime = FileTime::from_last_access_time(&metadata);
-        let mtime = FileTime::from_last_modification_time(&metadata);
-        t!(filetime::set_file_times(dst, atime, mtime));
-    }
-
     /// Copies a file from `src` to `dst`
     pub fn copy(&self, src: &Path, dst: &Path) {
         if self.config.dry_run {
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 88c5e94c276..00294878fe5 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2279,7 +2279,11 @@ fn short_item_info(item: &clean::Item, cx: &Context, parent: Option<&clean::Item
         let mut message = if let Some(since) = since {
             let since = &since.as_str();
             if !stability::deprecation_in_effect(is_since_rustc_version, Some(since)) {
-                format!("Deprecating in {}", Escape(since))
+                if *since == "TBD" {
+                    format!("Deprecating in a future Rust version")
+                } else {
+                    format!("Deprecating in {}", Escape(since))
+                }
             } else {
                 format!("Deprecated since {}", Escape(since))
             }
diff --git a/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot
index 124f2d8b97a..c00eae96e08 100644
--- a/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot
+++ b/src/test/mir-opt/coverage_graphviz.bar.InstrumentCoverage.0.dot
@@ -2,5 +2,5 @@ digraph Cov_0_4 {
     graph [fontname="Courier, monospace"];
     node [fontname="Courier, monospace"];
     edge [fontname="Courier, monospace"];
-    bcb0__Cov_0_4 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 18:1-20:2<br/>    19:5-19:9: @0[0]: _0 = const true<br/>    20:2-20:2: @0.Return: return</td></tr><tr><td align="left" balign="left">bb0: Return</td></tr></table>>];
+    bcb0__Cov_0_4 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 18:1-20:2<br/>    19:5-19:9: @0[0]: Coverage::Counter(1) for $DIR/coverage_graphviz.rs:18:1 - 20:2<br/>    20:2-20:2: @0.Return: return</td></tr><tr><td align="left" balign="left">bb0: Return</td></tr></table>>];
 }
diff --git a/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot
index d88193da4fb..5b6d73a7dee 100644
--- a/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot
+++ b/src/test/mir-opt/coverage_graphviz.main.InstrumentCoverage.0.dot
@@ -2,7 +2,7 @@ digraph Cov_0_3 {
     graph [fontname="Courier, monospace"];
     node [fontname="Courier, monospace"];
     edge [fontname="Courier, monospace"];
-    bcb2__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb2</td></tr><tr><td align="left" balign="left">Expression(bcb0 - bcb1) at 13:10-13:10<br/>    13:10-13:10: @4[0]: _1 = const ()</td></tr><tr><td align="left" balign="left">bb4: Goto</td></tr></table>>];
+    bcb2__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb2</td></tr><tr><td align="left" balign="left">Expression(bcb0 - bcb1) at 13:10-13:10<br/>    13:10-13:10: @4[0]: Coverage::Expression(4294967295) = 1 - 2 for $DIR/coverage_graphviz.rs:13:10 - 13:11</td></tr><tr><td align="left" balign="left">bb4: Goto</td></tr></table>>];
     bcb1__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb1</td></tr><tr><td align="left" balign="left">Counter(bcb1) at 12:13-12:18<br/>    12:13-12:18: @5[0]: _0 = const ()<br/>Expression(bcb1 + 0) at 15:2-15:2<br/>    15:2-15:2: @5.Return: return</td></tr><tr><td align="left" balign="left">bb3: FalseEdge</td></tr><tr><td align="left" balign="left">bb5: Return</td></tr></table>>];
     bcb0__Cov_0_3 [shape="none", label=<<table border="0" cellborder="1" cellspacing="0"><tr><td bgcolor="gray" align="center" colspan="1">bcb0</td></tr><tr><td align="left" balign="left"></td></tr><tr><td align="left" balign="left">Counter(bcb0) at 9:1-11:17<br/>    11:12-11:17: @1.Call: _2 = bar() -&gt; [return: bb2, unwind: bb6]<br/>    11:12-11:17: @2[0]: FakeRead(ForMatchedPlace, _2)</td></tr><tr><td align="left" balign="left">bb0: FalseUnwind<br/>bb1: Call</td></tr><tr><td align="left" balign="left">bb2: SwitchInt</td></tr></table>>];
     bcb2__Cov_0_3 -> bcb0__Cov_0_3 [label=<>];
diff --git a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
index 112a6983092..fef696df770 100644
--- a/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
+++ b/src/test/mir-opt/instrument_coverage.bar.InstrumentCoverage.diff
@@ -5,8 +5,8 @@
       let mut _0: bool;                    // return place in scope 0 at /the/src/instrument_coverage.rs:19:13: 19:17
   
       bb0: {
-          _0 = const true;                 // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9
 +         Coverage::Counter(1) for /the/src/instrument_coverage.rs:19:1 - 21:2; // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2
+          _0 = const true;                 // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9
           return;                          // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2
       }
   }
diff --git a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
index 83dee7efa6d..9bd8c9cf613 100644
--- a/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
+++ b/src/test/mir-opt/instrument_coverage.main.InstrumentCoverage.diff
@@ -8,6 +8,7 @@
       let mut _3: !;                       // in scope 0 at /the/src/instrument_coverage.rs:12:18: 14:10
   
       bb0: {
++         Coverage::Counter(1) for /the/src/instrument_coverage.rs:10:1 - 12:17; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
           falseUnwind -> [real: bb1, cleanup: bb6]; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
       }
   
@@ -21,26 +22,25 @@
   
       bb2: {
           FakeRead(ForMatchedPlace, _2);   // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17
-+         Coverage::Counter(1) for /the/src/instrument_coverage.rs:10:1 - 12:17; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
           switchInt(_2) -> [false: bb4, otherwise: bb3]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
       }
   
       bb3: {
++         Coverage::Expression(4294967294) = 2 + 0 for /the/src/instrument_coverage.rs:16:1 - 16:2; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
++         Coverage::Counter(2) for /the/src/instrument_coverage.rs:13:13 - 13:18; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
           falseEdge -> [real: bb5, imaginary: bb4]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
       }
   
       bb4: {
++         Coverage::Expression(4294967295) = 1 - 2 for /the/src/instrument_coverage.rs:14:10 - 14:11; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
           _1 = const ();                   // scope 0 at /the/src/instrument_coverage.rs:14:10: 14:10
           StorageDead(_2);                 // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6
-+         Coverage::Expression(4294967295) = 1 - 2 for /the/src/instrument_coverage.rs:14:10 - 14:11; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
           goto -> bb0;                     // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
       }
   
       bb5: {
           _0 = const ();                   // scope 0 at /the/src/instrument_coverage.rs:13:13: 13:18
           StorageDead(_2);                 // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6
-+         Coverage::Counter(2) for /the/src/instrument_coverage.rs:13:13 - 13:18; // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2
-+         Coverage::Expression(4294967294) = 2 + 0 for /the/src/instrument_coverage.rs:16:1 - 16:2; // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2
           return;                          // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2
       }
   
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json
index 024b5f11179..bb857ba3f3b 100644
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.assert.json
@@ -17,14 +17,14 @@
             },
             "lines": {
               "count": 15,
-              "covered": 12,
-              "percent": 80
+              "covered": 13,
+              "percent": 86.66666666666667
             },
             "regions": {
               "count": 14,
-              "covered": 12,
-              "notcovered": 2,
-              "percent": 85.71428571428571
+              "covered": 13,
+              "notcovered": 1,
+              "percent": 92.85714285714286
             }
           }
         }
@@ -42,14 +42,14 @@
         },
         "lines": {
           "count": 15,
-          "covered": 12,
-          "percent": 80
+          "covered": 13,
+          "percent": 86.66666666666667
         },
         "regions": {
           "count": 14,
-          "covered": 12,
-          "notcovered": 2,
-          "percent": 85.71428571428571
+          "covered": 13,
+          "notcovered": 1,
+          "percent": 92.85714285714286
         }
       }
     }
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json
index 030d7b033f0..128f5888ed1 100644
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.overflow.json
@@ -17,14 +17,14 @@
             },
             "lines": {
               "count": 23,
-              "covered": 19,
-              "percent": 82.6086956521739
+              "covered": 21,
+              "percent": 91.30434782608695
             },
             "regions": {
               "count": 13,
-              "covered": 11,
-              "notcovered": 2,
-              "percent": 84.61538461538461
+              "covered": 12,
+              "notcovered": 1,
+              "percent": 92.3076923076923
             }
           }
         }
@@ -42,14 +42,14 @@
         },
         "lines": {
           "count": 23,
-          "covered": 19,
-          "percent": 82.6086956521739
+          "covered": 21,
+          "percent": 91.30434782608695
         },
         "regions": {
           "count": 13,
-          "covered": 11,
-          "notcovered": 2,
-          "percent": 84.61538461538461
+          "covered": 12,
+          "notcovered": 1,
+          "percent": 92.3076923076923
         }
       }
     }
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json
index b1d44fdfeac..9c08dfd41a1 100644
--- a/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_export_coverage.panic_unwind.json
@@ -17,14 +17,14 @@
             },
             "lines": {
               "count": 19,
-              "covered": 16,
-              "percent": 84.21052631578947
+              "covered": 17,
+              "percent": 89.47368421052632
             },
             "regions": {
               "count": 13,
-              "covered": 11,
-              "notcovered": 2,
-              "percent": 84.61538461538461
+              "covered": 12,
+              "notcovered": 1,
+              "percent": 92.3076923076923
             }
           }
         }
@@ -42,14 +42,14 @@
         },
         "lines": {
           "count": 19,
-          "covered": 16,
-          "percent": 84.21052631578947
+          "covered": 17,
+          "percent": 89.47368421052632
         },
         "regions": {
           "count": 13,
-          "covered": 11,
-          "notcovered": 2,
-          "percent": 84.61538461538461
+          "covered": 12,
+          "notcovered": 1,
+          "percent": 92.3076923076923
         }
       }
     }
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt
index 355b53f7f3b..405688806ea 100644
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.assert.txt
@@ -9,13 +9,13 @@
     8|       |
     9|      1|fn main() -> Result<(),u8> {
    10|      1|    let mut countdown = 10;
-   11|     10|    while countdown > 0 {
-   12|     10|        if countdown == 1 {
-   13|      0|            might_fail_assert(3);
+   11|     11|    while countdown > 0 {
+   12|     11|        if countdown == 1 {
+   13|      1|            might_fail_assert(3);
    14|     10|        } else if countdown < 5 {
    15|      3|            might_fail_assert(2);
    16|      6|        }
-   17|      9|        countdown -= 1;
+   17|     10|        countdown -= 1;
    18|       |    }
    19|      0|    Ok(())
    20|      0|}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt
index 4dccb3413ea..25e822bffd1 100644
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.overflow.txt
@@ -14,15 +14,15 @@
    14|       |
    15|      1|fn main() -> Result<(),u8> {
    16|      1|    let mut countdown = 10;
-   17|     10|    while countdown > 0 {
-   18|     10|        if countdown == 1 {
-   19|      0|            let result = might_overflow(10);
-   20|      0|            println!("Result: {}", result);
+   17|     11|    while countdown > 0 {
+   18|     11|        if countdown == 1 {
+   19|      1|            let result = might_overflow(10);
+   20|      1|            println!("Result: {}", result);
    21|     10|        } else if countdown < 5 {
    22|      3|            let result = might_overflow(1);
    23|      3|            println!("Result: {}", result);
    24|      6|        }
-   25|      9|        countdown -= 1;
+   25|     10|        countdown -= 1;
    26|       |    }
    27|      0|    Ok(())
    28|      0|}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt
index 9ae78fee4b5..c77ee5ddc20 100644
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.panic_unwind.txt
@@ -12,13 +12,13 @@
    12|       |
    13|      1|fn main() -> Result<(), u8> {
    14|      1|    let mut countdown = 10;
-   15|     10|    while countdown > 0 {
-   16|     10|        if countdown == 1 {
-   17|      0|            might_panic(true);
+   15|     11|    while countdown > 0 {
+   16|     11|        if countdown == 1 {
+   17|      1|            might_panic(true);
    18|     10|        } else if countdown < 5 {
    19|      3|            might_panic(false);
    20|      6|        }
-   21|      9|        countdown -= 1;
+   21|     10|        countdown -= 1;
    22|       |    }
    23|      0|    Ok(())
    24|      0|}
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt
index 916ebbbcc29..0866a9a59a1 100644
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.assert.txt
@@ -20,13 +20,13 @@ Combined regions:
   6:37 -> 6:61 (count=1)
   7:1 -> 7:2 (count=3)
   9:1 -> 10:27 (count=1)
-  11:11 -> 11:24 (count=10)
-  12:12 -> 12:26 (count=10)
-  12:27 -> 14:10 (count=0)
+  11:11 -> 11:24 (count=11)
+  12:12 -> 12:26 (count=11)
+  12:27 -> 14:10 (count=1)
   14:19 -> 14:32 (count=10)
   14:33 -> 16:10 (count=3)
   16:10 -> 16:11 (count=6)
-  17:9 -> 17:23 (count=9)
+  17:9 -> 17:23 (count=10)
   19:5 -> 20:2 (count=0)
 Segment at 4:1 (count = 4), RegionEntry
 Segment at 4:41 (count = 0), Skipped
@@ -40,18 +40,18 @@ Segment at 7:1 (count = 3), RegionEntry
 Segment at 7:2 (count = 0), Skipped
 Segment at 9:1 (count = 1), RegionEntry
 Segment at 10:27 (count = 0), Skipped
-Segment at 11:11 (count = 10), RegionEntry
+Segment at 11:11 (count = 11), RegionEntry
 Segment at 11:24 (count = 0), Skipped
-Segment at 12:12 (count = 10), RegionEntry
+Segment at 12:12 (count = 11), RegionEntry
 Segment at 12:26 (count = 0), Skipped
-Segment at 12:27 (count = 0), RegionEntry
+Segment at 12:27 (count = 1), RegionEntry
 Segment at 14:10 (count = 0), Skipped
 Segment at 14:19 (count = 10), RegionEntry
 Segment at 14:32 (count = 0), Skipped
 Segment at 14:33 (count = 3), RegionEntry
 Segment at 16:10 (count = 6), RegionEntry
 Segment at 16:11 (count = 0), Skipped
-Segment at 17:9 (count = 9), RegionEntry
+Segment at 17:9 (count = 10), RegionEntry
 Segment at 17:23 (count = 0), Skipped
 Segment at 19:5 (count = 0), RegionEntry
 Segment at 20:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt
index fbc3adbfb6d..380bb7cf170 100644
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.overflow.txt
@@ -18,13 +18,13 @@ Combined regions:
   7:6 -> 7:7 (count=3)
   8:9 -> 13:2 (count=4)
   15:1 -> 16:27 (count=1)
-  17:11 -> 17:24 (count=10)
-  18:12 -> 18:26 (count=10)
-  18:27 -> 21:10 (count=0)
+  17:11 -> 17:24 (count=11)
+  18:12 -> 18:26 (count=11)
+  18:27 -> 21:10 (count=1)
   21:19 -> 21:32 (count=10)
   21:33 -> 24:10 (count=3)
   24:10 -> 24:11 (count=6)
-  25:9 -> 25:23 (count=9)
+  25:9 -> 25:23 (count=10)
   27:5 -> 28:2 (count=0)
 Segment at 4:1 (count = 4), RegionEntry
 Segment at 5:18 (count = 0), Skipped
@@ -35,18 +35,18 @@ Segment at 8:9 (count = 4), RegionEntry
 Segment at 13:2 (count = 0), Skipped
 Segment at 15:1 (count = 1), RegionEntry
 Segment at 16:27 (count = 0), Skipped
-Segment at 17:11 (count = 10), RegionEntry
+Segment at 17:11 (count = 11), RegionEntry
 Segment at 17:24 (count = 0), Skipped
-Segment at 18:12 (count = 10), RegionEntry
+Segment at 18:12 (count = 11), RegionEntry
 Segment at 18:26 (count = 0), Skipped
-Segment at 18:27 (count = 0), RegionEntry
+Segment at 18:27 (count = 1), RegionEntry
 Segment at 21:10 (count = 0), Skipped
 Segment at 21:19 (count = 10), RegionEntry
 Segment at 21:32 (count = 0), Skipped
 Segment at 21:33 (count = 3), RegionEntry
 Segment at 24:10 (count = 6), RegionEntry
 Segment at 24:11 (count = 0), Skipped
-Segment at 25:9 (count = 9), RegionEntry
+Segment at 25:9 (count = 10), RegionEntry
 Segment at 25:23 (count = 0), Skipped
 Segment at 27:5 (count = 0), RegionEntry
 Segment at 28:2 (count = 0), Skipped
diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt
index ad87f03026d..b3f61ad325d 100644
--- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt
+++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage_counters.panic_unwind.txt
@@ -18,13 +18,13 @@ Combined regions:
   6:9 -> 7:26 (count=1)
   8:12 -> 11:2 (count=3)
   13:1 -> 14:27 (count=1)
-  15:11 -> 15:24 (count=10)
-  16:12 -> 16:26 (count=10)
-  16:27 -> 18:10 (count=0)
+  15:11 -> 15:24 (count=11)
+  16:12 -> 16:26 (count=11)
+  16:27 -> 18:10 (count=1)
   18:19 -> 18:32 (count=10)
   18:33 -> 20:10 (count=3)
   20:10 -> 20:11 (count=6)
-  21:9 -> 21:23 (count=9)
+  21:9 -> 21:23 (count=10)
   23:5 -> 24:2 (count=0)
 Segment at 4:1 (count = 4), RegionEntry
 Segment at 4:36 (count = 0), Skipped
@@ -36,18 +36,18 @@ Segment at 8:12 (count = 3), RegionEntry
 Segment at 11:2 (count = 0), Skipped
 Segment at 13:1 (count = 1), RegionEntry
 Segment at 14:27 (count = 0), Skipped
-Segment at 15:11 (count = 10), RegionEntry
+Segment at 15:11 (count = 11), RegionEntry
 Segment at 15:24 (count = 0), Skipped
-Segment at 16:12 (count = 10), RegionEntry
+Segment at 16:12 (count = 11), RegionEntry
 Segment at 16:26 (count = 0), Skipped
-Segment at 16:27 (count = 0), RegionEntry
+Segment at 16:27 (count = 1), RegionEntry
 Segment at 18:10 (count = 0), Skipped
 Segment at 18:19 (count = 10), RegionEntry
 Segment at 18:32 (count = 0), Skipped
 Segment at 18:33 (count = 3), RegionEntry
 Segment at 20:10 (count = 6), RegionEntry
 Segment at 20:11 (count = 0), Skipped
-Segment at 21:9 (count = 9), RegionEntry
+Segment at 21:9 (count = 10), RegionEntry
 Segment at 21:23 (count = 0), Skipped
 Segment at 23:5 (count = 0), RegionEntry
 Segment at 24:2 (count = 0), Skipped
diff --git a/src/test/rustdoc/rustc_deprecated-future.rs b/src/test/rustdoc/rustc_deprecated-future.rs
index 3133775706b..95a767a8329 100644
--- a/src/test/rustdoc/rustc_deprecated-future.rs
+++ b/src/test/rustdoc/rustc_deprecated-future.rs
@@ -4,8 +4,16 @@
 
 // @has rustc_deprecated_future/index.html '//*[@class="stab deprecated"]' \
 //      'Deprecation planned'
-// @has rustc_deprecated_future/struct.S.html '//*[@class="stab deprecated"]' \
+// @has rustc_deprecated_future/struct.S1.html '//*[@class="stab deprecated"]' \
 //      'Deprecating in 99.99.99: effectively never'
 #[rustc_deprecated(since = "99.99.99", reason = "effectively never")]
 #[stable(feature = "rustc_deprecated-future-test", since = "1.0.0")]
-pub struct S;
+pub struct S1;
+
+// @has rustc_deprecated_future/index.html '//*[@class="stab deprecated"]' \
+//      'Deprecation planned'
+// @has rustc_deprecated_future/struct.S2.html '//*[@class="stab deprecated"]' \
+//      'Deprecating in a future Rust version: literally never'
+#[rustc_deprecated(since = "TBD", reason = "literally never")]
+#[stable(feature = "rustc_deprecated-future-test", since = "1.0.0")]
+pub struct S2;
diff --git a/src/test/ui/deprecation/rustc_deprecation-in-future.rs b/src/test/ui/deprecation/rustc_deprecation-in-future.rs
index 6a619bcc49c..11f7960b757 100644
--- a/src/test/ui/deprecation/rustc_deprecation-in-future.rs
+++ b/src/test/ui/deprecation/rustc_deprecation-in-future.rs
@@ -8,8 +8,13 @@
 
 #[rustc_deprecated(since = "99.99.99", reason = "effectively never")]
 #[stable(feature = "rustc_deprecation-in-future-test", since = "1.0.0")]
-pub struct S;
+pub struct S1;
+
+#[rustc_deprecated(since = "TBD", reason = "literally never")]
+#[stable(feature = "rustc_deprecation-in-future-test", since = "1.0.0")]
+pub struct S2;
 
 fn main() {
-    let _ = S; //~ ERROR use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never
+    let _ = S1; //~ ERROR use of unit struct `S1` that will be deprecated in future version 99.99.99: effectively never
+    let _ = S2; //~ ERROR use of unit struct `S2` that will be deprecated in a future Rust version: literally never
 }
diff --git a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr
index e4f50d10dad..b5a7dd3c28d 100644
--- a/src/test/ui/deprecation/rustc_deprecation-in-future.stderr
+++ b/src/test/ui/deprecation/rustc_deprecation-in-future.stderr
@@ -1,8 +1,8 @@
-error: use of unit struct `S` that will be deprecated in future version 99.99.99: effectively never
-  --> $DIR/rustc_deprecation-in-future.rs:14:13
+error: use of unit struct `S1` that will be deprecated in future version 99.99.99: effectively never
+  --> $DIR/rustc_deprecation-in-future.rs:18:13
    |
-LL |     let _ = S;
-   |             ^
+LL |     let _ = S1;
+   |             ^^
    |
 note: the lint level is defined here
   --> $DIR/rustc_deprecation-in-future.rs:3:9
@@ -10,5 +10,11 @@ note: the lint level is defined here
 LL | #![deny(deprecated_in_future)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: use of unit struct `S2` that will be deprecated in a future Rust version: literally never
+  --> $DIR/rustc_deprecation-in-future.rs:19:13
+   |
+LL |     let _ = S2;
+   |             ^^
+
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/generator/yielding-in-match-guards.rs b/src/test/ui/generator/yielding-in-match-guards.rs
index c76726414df..5c10a7c7811 100644
--- a/src/test/ui/generator/yielding-in-match-guards.rs
+++ b/src/test/ui/generator/yielding-in-match-guards.rs
@@ -10,6 +10,9 @@
 // Thus, `&'_ u8` should be included in type signature
 // of the underlying generator.
 
+#![feature(if_let_guard)]
+#![allow(incomplete_features)]
+
 async fn f() -> u8 { 1 }
 async fn foo() -> [bool; 10] { [false; 10] }
 
@@ -36,8 +39,16 @@ async fn i(x: u8) {
     }
 }
 
+async fn j(x: u8) {
+    match x {
+        y if let (1, 42) = (f().await, y) => (),
+        _ => (),
+    }
+}
+
 fn main() {
     let _ = g(10);
     let _ = h(9);
     let _ = i(8);
+    let _ = j(7);
 }
diff --git a/src/test/ui/mir/issue-78496.rs b/src/test/ui/mir/issue-78496.rs
new file mode 100644
index 00000000000..1b0687cfac3
--- /dev/null
+++ b/src/test/ui/mir/issue-78496.rs
@@ -0,0 +1,16 @@
+// run-pass
+// compile-flags: -Z mir-opt-level=2 -C opt-level=0
+
+// example from #78496
+pub enum E<'a> {
+    Empty,
+    Some(&'a E<'a>),
+}
+
+fn f(e: &E) -> u32 {
+   if let E::Some(E::Some(_)) = e { 1 } else { 2 }
+}
+
+fn main() {
+   assert_eq!(f(&E::Empty), 2);
+}
diff --git a/src/test/ui/no-std-macros.rs b/src/test/ui/no-std-macros.rs
new file mode 100644
index 00000000000..ada643c7ac0
--- /dev/null
+++ b/src/test/ui/no-std-macros.rs
@@ -0,0 +1,13 @@
+// compile-flags: --crate-type=lib
+// check-pass
+// issue #55482
+#![no_std]
+
+macro_rules! foo {
+    ($e:expr) => {
+        $crate::core::assert!($e);
+        $crate::core::assert_eq!($e, true);
+    };
+}
+
+pub fn foo() { foo!(true); }
diff --git a/src/test/ui/rfc-2294-if-let-guard/bindings.rs b/src/test/ui/rfc-2294-if-let-guard/bindings.rs
new file mode 100644
index 00000000000..4e2d70e3290
--- /dev/null
+++ b/src/test/ui/rfc-2294-if-let-guard/bindings.rs
@@ -0,0 +1,10 @@
+#![feature(if_let_guard)]
+#![allow(incomplete_features)]
+
+fn main() {
+    match Some(None) {
+        Some(x) if let Some(y) = x => (x, y),
+        _ => y, //~ ERROR cannot find value `y`
+    }
+    y //~ ERROR cannot find value `y`
+}
diff --git a/src/test/ui/rfc-2294-if-let-guard/bindings.stderr b/src/test/ui/rfc-2294-if-let-guard/bindings.stderr
new file mode 100644
index 00000000000..9c5d92a33ad
--- /dev/null
+++ b/src/test/ui/rfc-2294-if-let-guard/bindings.stderr
@@ -0,0 +1,15 @@
+error[E0425]: cannot find value `y` in this scope
+  --> $DIR/bindings.rs:7:14
+   |
+LL |         _ => y,
+   |              ^ not found in this scope
+
+error[E0425]: cannot find value `y` in this scope
+  --> $DIR/bindings.rs:9:5
+   |
+LL |     y
+   |     ^ not found in this scope
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
index c0a9bbc36b2..311d1afcfc0 100644
--- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
+++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs
@@ -6,7 +6,6 @@ fn _if_let_guard() {
     match () {
         () if let 0 = 1 => {}
         //~^ ERROR `if let` guard is not implemented
-        //~| ERROR `let` expressions are not supported here
 
         () if (let 0 = 1) => {}
         //~^ ERROR `let` expressions in this position are experimental
diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
index 5c7f8190dd6..1670078e0d3 100644
--- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
+++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr
@@ -1,5 +1,5 @@
 error: no rules expected the token `let`
-  --> $DIR/feature-gate.rs:81:15
+  --> $DIR/feature-gate.rs:80:15
    |
 LL |     macro_rules! use_expr {
    |     --------------------- when calling this macro
@@ -17,7 +17,7 @@ LL |         () if let 0 = 1 => {}
    = help: add `#![feature(if_let_guard)]` to the crate attributes to enable
 
 error[E0658]: `if let` guard is not implemented
-  --> $DIR/feature-gate.rs:77:12
+  --> $DIR/feature-gate.rs:76:12
    |
 LL |         () if let 0 = 1 => {}
    |            ^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL |         () if let 0 = 1 => {}
    = help: add `#![feature(if_let_guard)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:11:16
+  --> $DIR/feature-gate.rs:10:16
    |
 LL |         () if (let 0 = 1) => {}
    |                ^^^^^^^^^
@@ -35,7 +35,7 @@ LL |         () if (let 0 = 1) => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:15:18
+  --> $DIR/feature-gate.rs:14:18
    |
 LL |         () if (((let 0 = 1))) => {}
    |                  ^^^^^^^^^
@@ -44,7 +44,7 @@ LL |         () if (((let 0 = 1))) => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:19:23
+  --> $DIR/feature-gate.rs:18:23
    |
 LL |         () if true && let 0 = 1 => {}
    |                       ^^^^^^^^^
@@ -53,7 +53,7 @@ LL |         () if true && let 0 = 1 => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:23:15
+  --> $DIR/feature-gate.rs:22:15
    |
 LL |         () if let 0 = 1 && true => {}
    |               ^^^^^^^^^
@@ -62,7 +62,7 @@ LL |         () if let 0 = 1 && true => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:27:16
+  --> $DIR/feature-gate.rs:26:16
    |
 LL |         () if (let 0 = 1) && true => {}
    |                ^^^^^^^^^
@@ -71,7 +71,7 @@ LL |         () if (let 0 = 1) && true => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:31:24
+  --> $DIR/feature-gate.rs:30:24
    |
 LL |         () if true && (let 0 = 1) => {}
    |                        ^^^^^^^^^
@@ -80,7 +80,7 @@ LL |         () if true && (let 0 = 1) => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:35:16
+  --> $DIR/feature-gate.rs:34:16
    |
 LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    |                ^^^^^^^^^
@@ -89,7 +89,7 @@ LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:35:31
+  --> $DIR/feature-gate.rs:34:31
    |
 LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    |                               ^^^^^^^^^
@@ -98,7 +98,7 @@ LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:41:15
+  --> $DIR/feature-gate.rs:40:15
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |               ^^^^^^^^^
@@ -107,7 +107,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:41:28
+  --> $DIR/feature-gate.rs:40:28
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                            ^^^^^^^^^
@@ -116,7 +116,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:41:42
+  --> $DIR/feature-gate.rs:40:42
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                          ^^^^^^^^^
@@ -125,7 +125,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:41:55
+  --> $DIR/feature-gate.rs:40:55
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                                       ^^^^^^^^^
@@ -134,7 +134,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:41:68
+  --> $DIR/feature-gate.rs:40:68
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                                                    ^^^^^^^^^
@@ -143,7 +143,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:53:15
+  --> $DIR/feature-gate.rs:52:15
    |
 LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -152,7 +152,7 @@ LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:69:16
+  --> $DIR/feature-gate.rs:68:16
    |
 LL |     use_expr!((let 0 = 1 && 0 == 0));
    |                ^^^^^^^^^
@@ -161,7 +161,7 @@ LL |     use_expr!((let 0 = 1 && 0 == 0));
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error[E0658]: `let` expressions in this position are experimental
-  --> $DIR/feature-gate.rs:72:16
+  --> $DIR/feature-gate.rs:71:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^^^^^^^
@@ -170,16 +170,7 @@ LL |     use_expr!((let 0 = 1));
    = help: add `#![feature(let_chains)]` to the crate attributes to enable
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:7:15
-   |
-LL |         () if let 0 = 1 => {}
-   |               ^^^^^^^^^
-   |
-   = note: only supported directly in conditions of `if`- and `while`-expressions
-   = note: as well as when nested within `&&` and parenthesis in those conditions
-
-error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:11:16
+  --> $DIR/feature-gate.rs:10:16
    |
 LL |         () if (let 0 = 1) => {}
    |                ^^^^^^^^^
@@ -188,7 +179,7 @@ LL |         () if (let 0 = 1) => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:15:18
+  --> $DIR/feature-gate.rs:14:18
    |
 LL |         () if (((let 0 = 1))) => {}
    |                  ^^^^^^^^^
@@ -197,7 +188,7 @@ LL |         () if (((let 0 = 1))) => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:19:23
+  --> $DIR/feature-gate.rs:18:23
    |
 LL |         () if true && let 0 = 1 => {}
    |                       ^^^^^^^^^
@@ -206,7 +197,7 @@ LL |         () if true && let 0 = 1 => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:23:15
+  --> $DIR/feature-gate.rs:22:15
    |
 LL |         () if let 0 = 1 && true => {}
    |               ^^^^^^^^^
@@ -215,7 +206,7 @@ LL |         () if let 0 = 1 && true => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:27:16
+  --> $DIR/feature-gate.rs:26:16
    |
 LL |         () if (let 0 = 1) && true => {}
    |                ^^^^^^^^^
@@ -224,7 +215,7 @@ LL |         () if (let 0 = 1) && true => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:31:24
+  --> $DIR/feature-gate.rs:30:24
    |
 LL |         () if true && (let 0 = 1) => {}
    |                        ^^^^^^^^^
@@ -233,7 +224,7 @@ LL |         () if true && (let 0 = 1) => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:35:16
+  --> $DIR/feature-gate.rs:34:16
    |
 LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    |                ^^^^^^^^^
@@ -242,7 +233,7 @@ LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:35:31
+  --> $DIR/feature-gate.rs:34:31
    |
 LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    |                               ^^^^^^^^^
@@ -251,7 +242,7 @@ LL |         () if (let 0 = 1) && (let 0 = 1) => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:41:15
+  --> $DIR/feature-gate.rs:40:15
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |               ^^^^^^^^^
@@ -260,7 +251,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:41:28
+  --> $DIR/feature-gate.rs:40:28
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                            ^^^^^^^^^
@@ -269,7 +260,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:41:42
+  --> $DIR/feature-gate.rs:40:42
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                          ^^^^^^^^^
@@ -278,7 +269,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:41:55
+  --> $DIR/feature-gate.rs:40:55
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                                       ^^^^^^^^^
@@ -287,7 +278,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:41:68
+  --> $DIR/feature-gate.rs:40:68
    |
 LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 = 5) => {}
    |                                                                    ^^^^^^^^^
@@ -296,7 +287,7 @@ LL |         () if let 0 = 1 && let 1 = 2 && (let 2 = 3 && let 3 = 4 && let 4 =
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:53:15
+  --> $DIR/feature-gate.rs:52:15
    |
 LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -305,7 +296,7 @@ LL |         () if let Range { start: _, end: _ } = (true..true) && false => {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:69:16
+  --> $DIR/feature-gate.rs:68:16
    |
 LL |     use_expr!((let 0 = 1 && 0 == 0));
    |                ^^^^^^^^^
@@ -314,7 +305,7 @@ LL |     use_expr!((let 0 = 1 && 0 == 0));
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/feature-gate.rs:72:16
+  --> $DIR/feature-gate.rs:71:16
    |
 LL |     use_expr!((let 0 = 1));
    |                ^^^^^^^^^
@@ -322,6 +313,6 @@ LL |     use_expr!((let 0 = 1));
    = note: only supported directly in conditions of `if`- and `while`-expressions
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
-error: aborting due to 36 previous errors
+error: aborting due to 35 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2294-if-let-guard/run-pass.rs b/src/test/ui/rfc-2294-if-let-guard/run-pass.rs
new file mode 100644
index 00000000000..a3663003790
--- /dev/null
+++ b/src/test/ui/rfc-2294-if-let-guard/run-pass.rs
@@ -0,0 +1,34 @@
+// run-pass
+
+#![feature(if_let_guard)]
+#![allow(incomplete_features)]
+
+enum Foo {
+    Bar,
+    Baz,
+    Qux(u8),
+}
+
+fn bar(x: bool) -> Foo {
+    if x { Foo::Baz } else { Foo::Bar }
+}
+
+fn baz(x: u8) -> Foo {
+    if x % 2 == 0 { Foo::Bar } else { Foo::Baz }
+}
+
+fn qux(x: u8) -> Foo {
+    Foo::Qux(x.rotate_left(1))
+}
+
+fn main() {
+    match Some((true, 3)) {
+        Some((x, _)) if let Foo::Bar = bar(x) => panic!(),
+        Some((_, x)) if let Foo::Baz = baz(x) => {},
+        _ => panic!(),
+    }
+    match Some(42) {
+        Some(x) if let Foo::Qux(y) = qux(x) => assert_eq!(y, 84),
+        _ => panic!(),
+    }
+}
diff --git a/src/test/ui/rfc-2294-if-let-guard/typeck.rs b/src/test/ui/rfc-2294-if-let-guard/typeck.rs
new file mode 100644
index 00000000000..a4fc7f8cf2b
--- /dev/null
+++ b/src/test/ui/rfc-2294-if-let-guard/typeck.rs
@@ -0,0 +1,16 @@
+#![feature(if_let_guard)]
+#![allow(incomplete_features)]
+
+fn ok() -> Result<Option<bool>, ()> {
+    Ok(Some(true))
+}
+
+fn main() {
+    match ok() {
+        Ok(x) if let Err(_) = x => {},
+        //~^ ERROR mismatched types
+        Ok(x) if let 0 = x => {},
+        //~^ ERROR mismatched types
+        _ => {}
+    }
+}
diff --git a/src/test/ui/rfc-2294-if-let-guard/typeck.stderr b/src/test/ui/rfc-2294-if-let-guard/typeck.stderr
new file mode 100644
index 00000000000..7ce93fe7348
--- /dev/null
+++ b/src/test/ui/rfc-2294-if-let-guard/typeck.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+  --> $DIR/typeck.rs:10:22
+   |
+LL |         Ok(x) if let Err(_) = x => {},
+   |                      ^^^^^^ expected enum `Option`, found enum `std::result::Result`
+   |
+   = note: expected enum `Option<bool>`
+              found enum `std::result::Result<_, _>`
+
+error[E0308]: mismatched types
+  --> $DIR/typeck.rs:12:22
+   |
+LL |         Ok(x) if let 0 = x => {},
+   |                      ^ expected enum `Option`, found integer
+   |
+   = note: expected enum `Option<bool>`
+              found type `{integer}`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/rfc-2294-if-let-guard/warns.rs b/src/test/ui/rfc-2294-if-let-guard/warns.rs
new file mode 100644
index 00000000000..9691a12f45b
--- /dev/null
+++ b/src/test/ui/rfc-2294-if-let-guard/warns.rs
@@ -0,0 +1,22 @@
+#![feature(if_let_guard)]
+#![allow(incomplete_features)]
+
+#[deny(irrefutable_let_patterns)]
+fn irrefutable_let_guard() {
+    match Some(()) {
+        Some(x) if let () = x => {}
+        //~^ ERROR irrefutable if-let guard
+        _ => {}
+    }
+}
+
+#[deny(unreachable_patterns)]
+fn unreachable_pattern() {
+    match Some(()) {
+        x if let None | None = x => {}
+        //~^ ERROR unreachable pattern
+        _ => {}
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2294-if-let-guard/warns.stderr b/src/test/ui/rfc-2294-if-let-guard/warns.stderr
new file mode 100644
index 00000000000..45720f9fbc5
--- /dev/null
+++ b/src/test/ui/rfc-2294-if-let-guard/warns.stderr
@@ -0,0 +1,26 @@
+error: irrefutable if-let guard
+  --> $DIR/warns.rs:7:24
+   |
+LL |         Some(x) if let () = x => {}
+   |                        ^^
+   |
+note: the lint level is defined here
+  --> $DIR/warns.rs:4:8
+   |
+LL | #[deny(irrefutable_let_patterns)]
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: unreachable pattern
+  --> $DIR/warns.rs:16:25
+   |
+LL |         x if let None | None = x => {}
+   |                         ^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/warns.rs:13:8
+   |
+LL | #[deny(unreachable_patterns)]
+   |        ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity.rs b/src/test/ui/stability-attribute/stability-attribute-sanity.rs
index abd603b356e..0c40f8ae1c6 100644
--- a/src/test/ui/stability-attribute/stability-attribute-sanity.rs
+++ b/src/test/ui/stability-attribute/stability-attribute-sanity.rs
@@ -63,7 +63,11 @@ fn multiple3() { }
 #[rustc_const_unstable(feature = "c", issue = "none")]
 #[rustc_const_unstable(feature = "d", issue = "none")] //~ ERROR multiple stability levels
 pub const fn multiple4() { }
-//~^ ERROR Invalid stability or deprecation version found
+//~^ ERROR Invalid stability version found
+
+#[stable(feature = "a", since = "1.0.0")]
+#[rustc_deprecated(since = "invalid", reason = "text")]
+fn invalid_deprecation_version() {} //~ ERROR Invalid deprecation version found
 
 #[rustc_deprecated(since = "a", reason = "text")]
 fn deprecated_without_unstable_or_stable() { }
diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
index 97089f7df52..ee9a93359f0 100644
--- a/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
+++ b/src/test/ui/stability-attribute/stability-attribute-sanity.stderr
@@ -96,19 +96,25 @@ error[E0544]: multiple stability levels
 LL | #[rustc_const_unstable(feature = "d", issue = "none")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: Invalid stability or deprecation version found
+error: Invalid stability version found
   --> $DIR/stability-attribute-sanity.rs:65:1
    |
 LL | pub const fn multiple4() { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error: Invalid deprecation version found
+  --> $DIR/stability-attribute-sanity.rs:70:1
+   |
+LL | fn invalid_deprecation_version() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error[E0549]: rustc_deprecated attribute must be paired with either stable or unstable attribute
-  --> $DIR/stability-attribute-sanity.rs:68:1
+  --> $DIR/stability-attribute-sanity.rs:72:1
    |
 LL | #[rustc_deprecated(since = "a", reason = "text")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 18 previous errors
+error: aborting due to 19 previous errors
 
 Some errors have detailed explanations: E0539, E0541, E0546, E0550.
 For more information about an error, try `rustc --explain E0539`.
diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs
index 225fe58906f..f8396592678 100644
--- a/src/tools/clippy/clippy_lints/src/shadow.rs
+++ b/src/tools/clippy/clippy_lints/src/shadow.rs
@@ -342,6 +342,10 @@ fn check_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, bindings: &mut
                 if let Some(ref guard) = arm.guard {
                     match guard {
                         Guard::If(if_expr) => check_expr(cx, if_expr, bindings),
+                        Guard::IfLet(guard_pat, guard_expr) => {
+                            check_pat(cx, guard_pat, Some(*guard_expr), guard_pat.span, bindings);
+                            check_expr(cx, guard_expr, bindings);
+                        },
                     }
                 }
                 check_expr(cx, &arm.body, bindings);
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index 7250de3a41c..4249dbb4e65 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -372,6 +372,18 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
                                 self.current = if_expr_pat;
                                 self.visit_expr(if_expr);
                             },
+                            hir::Guard::IfLet(ref if_let_pat, ref if_let_expr) => {
+                                let if_let_pat_pat = self.next("pat");
+                                let if_let_expr_pat = self.next("expr");
+                                println!(
+                                    "    if let Guard::IfLet(ref {}, ref {}) = {};",
+                                    if_let_pat_pat, if_let_expr_pat, guard_pat
+                                );
+                                self.current = if_let_expr_pat;
+                                self.visit_expr(if_let_expr);
+                                self.current = if_let_pat_pat;
+                                self.visit_pat(if_let_pat);
+                            },
                         }
                     }
                     self.current = format!("{}[{}].pat", arms_pat, i);
@@ -730,6 +742,7 @@ fn desugaring_name(des: hir::MatchSource) -> String {
             "MatchSource::IfLetDesugar {{ contains_else_clause: {} }}",
             contains_else_clause
         ),
+        hir::MatchSource::IfLetGuardDesugar => "MatchSource::IfLetGuardDesugar".to_string(),
         hir::MatchSource::IfDesugar { contains_else_clause } => format!(
             "MatchSource::IfDesugar {{ contains_else_clause: {} }}",
             contains_else_clause
diff --git a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs
index d942d4e12b1..a8fbb2ffaf0 100644
--- a/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/hir_utils.rs
@@ -169,6 +169,8 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> {
     fn eq_guard(&mut self, left: &Guard<'_>, right: &Guard<'_>) -> bool {
         match (left, right) {
             (Guard::If(l), Guard::If(r)) => self.eq_expr(l, r),
+            (Guard::IfLet(lp, le), Guard::IfLet(rp, re)) => self.eq_pat(lp, rp) && self.eq_expr(le, re),
+            _ => false,
         }
     }
 
@@ -669,7 +671,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
 
     pub fn hash_guard(&mut self, g: &Guard<'_>) {
         match g {
-            Guard::If(ref expr) => {
+            Guard::If(ref expr) | Guard::IfLet(_, ref expr) => {
                 self.hash_expr(expr);
             },
         }
diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs
index 323d8745538..5d946e4bd49 100644
--- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs
@@ -560,5 +560,10 @@ fn print_guard(cx: &LateContext<'_>, guard: &hir::Guard<'_>, indent: usize) {
             println!("{}If", ind);
             print_expr(cx, expr, indent + 1);
         },
+        hir::Guard::IfLet(pat, expr) => {
+            println!("{}IfLet", ind);
+            print_pat(cx, pat, indent + 1);
+            print_expr(cx, expr, indent + 1);
+        },
     }
 }
diff --git a/src/tools/expand-yaml-anchors/src/main.rs b/src/tools/expand-yaml-anchors/src/main.rs
index f7ff64036a1..f8cf18a9309 100644
--- a/src/tools/expand-yaml-anchors/src/main.rs
+++ b/src/tools/expand-yaml-anchors/src/main.rs
@@ -87,7 +87,8 @@ impl App {
         let content = std::fs::read_to_string(source)
             .with_context(|| format!("failed to read {}", self.path(source)))?;
 
-        let mut buf = HEADER_MESSAGE.replace("{source}", &self.path(source).to_string());
+        let mut buf =
+            HEADER_MESSAGE.replace("{source}", &self.path(source).to_string().replace("\\", "/"));
 
         let documents = YamlLoader::load_from_str(&content)
             .with_context(|| format!("failed to parse {}", self.path(source)))?;